diff --git a/.eslintignore b/.eslintignore index ca7069f011..1c82b7c66a 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,7 +3,7 @@ /tests/integration/cli/ !/tests/format/**/jsfmt.spec.js !/**/.eslintrc.js -/test*.js +/test*.* /scripts/release/node_modules /coverage/ /dist/ diff --git a/.eslintrc.yml b/.eslintrc.yml index ad15b2cb42..1e6f74f65c 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -6,9 +6,10 @@ extends: - eslint:recommended - prettier plugins: + - prettier-internal-rules - import + - regexp - unicorn - - prettier-internal-rules settings: import/internal-regex: ^linguist-languages/ rules: @@ -69,12 +70,23 @@ rules: - error - never - exceptRange: true + regexp/match-any: + - error + - allows: + - dotAll + regexp/no-useless-flag: error unicorn/better-regex: error unicorn/explicit-length-check: error unicorn/new-for-builtins: error unicorn/no-array-for-each: error unicorn/no-array-push-push: error unicorn/no-useless-undefined: error + unicorn/prefer-array-flat: + - error + - functions: + - flat + - flatten + unicorn/prefer-array-flat-map: error unicorn/prefer-includes: error unicorn/prefer-number-properties: error unicorn/prefer-optional-catch-binding: error @@ -90,6 +102,9 @@ overrides: - "**/*.mjs" parserOptions: sourceType: module + rules: + unicorn/prefer-module: error + unicorn/prefer-node-protocol: error - files: - "tests/format/**/jsfmt.spec.js" - "tests/config/**/*.js" @@ -106,6 +121,8 @@ overrides: - tests/**/*.js rules: strict: off + unicorn/prefer-array-flat: off + unicorn/prefer-array-flat-map: off globals: run_spec: false - files: diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 25f95d5641..3587d6e2fd 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -5,6 +5,8 @@ # See https://git-scm.com/docs/git-blame#Documentation/git-blame.txt---ignore-revs-fileltfilegt # Prettier bump after release +# 2.3.0 +3d8dc612b54cef741a1c31da1011a2d48748a1dd # 2.2.1 80961835a68e3de1b14819a7b77583a54d2b63d7 # 2.2.0 diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index d7a05e9c63..0000000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,2 +0,0 @@ -tidelift: npm/prettier -open_collective: prettier diff --git a/.github/ISSUE_TEMPLATE/formatting.md b/.github/ISSUE_TEMPLATE/formatting.md deleted file mode 100644 index 202dc039e1..0000000000 --- a/.github/ISSUE_TEMPLATE/formatting.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -name: ✨ Formatting -about: Issues for ugly or incorrect code ---- - - - -**Prettier 2.3.0** -[Playground link](https://prettier.io/playground/#.....) - -```sh -# Options (if any): ---single-quote -``` - -**Input:** - -```jsx -// code snippet -``` - -**Output:** - -```jsx -// code snippet -``` - -**Expected behavior:** diff --git a/.github/ISSUE_TEMPLATE/integration.md b/.github/ISSUE_TEMPLATE/integration.md deleted file mode 100644 index 8e62f1ba8a..0000000000 --- a/.github/ISSUE_TEMPLATE/integration.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -name: ⚙ Integration -about: Issues for API, CLI, etc. ---- - - - -**Environments:** - -- Prettier Version: 2.3.0 -- Running Prettier via: -- Runtime: -- Operating System: -- Prettier plugins (if any): - -**Steps to reproduce:** - - - -**Expected behavior:** - -**Actual behavior:** diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 9cac6f57f9..0000000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,17 +0,0 @@ -## Description - - - -## Checklist - - - - -- [ ] I’ve added tests to confirm my change works. -- [ ] (If changing the API or CLI) I’ve documented the changes I’ve made (in the `docs/` directory). -- [ ] (If the change is user-facing) I’ve added my changes to `changelog_unreleased/*/XXXX.md` file following `changelog_unreleased/TEMPLATE.md`. -- [ ] I’ve read the [contributing guidelines](https://github.com/prettier/prettier/blob/main/CONTRIBUTING.md). - - - -**✨[Try the playground for this PR](https://prettier.io/playground-redirect)✨** diff --git a/.github/SECURITY.md b/.github/SECURITY.md index 863fe0f9d7..8ddc81ed37 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -1,5 +1,9 @@ -# Security Policy +# prettierx security -## Reporting a Vulnerability +- +- https://www.linkedin.com/in/chrisbrody/ -To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. + diff --git a/.github/no-response.yml b/.github/no-response.yml deleted file mode 100644 index c608694645..0000000000 --- a/.github/no-response.yml +++ /dev/null @@ -1,10 +0,0 @@ -# Configuration for probot-no-response - https://github.com/probot/no-response - -daysUntilClose: 14 -responseRequiredLabel: "status:awaiting response" -closeComment: > - This issue has been automatically closed because there has been no response - to our request for more information from the original author. With only the - information that is currently in the issue, we don't have enough information - to take action. Please reach out if you have or find the answers we need so - that we can investigate further. diff --git a/.github/workflows/dev-package-test.yml b/.github/workflows/dev-package-test.yml index a4d69270ce..27b3ae34e3 100644 --- a/.github/workflows/dev-package-test.yml +++ b/.github/workflows/dev-package-test.yml @@ -18,7 +18,7 @@ jobs: - "ubuntu-latest" node: # Run tests on minimal version we support - - "10" + - "12" NPM_CLIENT: - "yarn" - "npm" diff --git a/.github/workflows/dev-test.yml b/.github/workflows/dev-test.yml index f75dfbaac3..f526dcaed4 100644 --- a/.github/workflows/dev-test.yml +++ b/.github/workflows/dev-test.yml @@ -1,10 +1,15 @@ name: Dev on: + # [prettierx ...] push: branches: - main - - patch-release + # - master + # - patch-release + - dev + - dev-* + - prettierx-* pull_request: jobs: @@ -21,23 +26,19 @@ jobs: - "16" - "14" - "12" - - "10" include: # only enable coverage on the fastest job - os: "ubuntu-latest" node: "16" - ENABLE_CODE_COVERAGE: true + # [prettierx] code coverage not enabled: + # ENABLE_CODE_COVERAGE: true FULL_TEST: true CHECK_TEST_PARSERS: true exclude: - os: "macos-latest" node: "14" - - os: "macos-latest" - node: "12" - os: "windows-latest" node: "14" - - os: "windows-latest" - node: "12" env: ENABLE_CODE_COVERAGE: ${{ matrix.ENABLE_CODE_COVERAGE }} FULL_TEST: ${{ matrix.FULL_TEST }} @@ -67,6 +68,7 @@ jobs: if: matrix.os != 'macos-latest' run: yarn test --maxWorkers=2 + # [prettierx] code coverage not enabled (see above) - name: Upload Coverage uses: codecov/codecov-action@v1.5.0 if: matrix.ENABLE_CODE_COVERAGE @@ -79,6 +81,7 @@ jobs: env: PRETTIER_FALLBACK_RESOLVE: true + # [prettierx] code coverage not enabled (see above) - name: Upload Coverage (PRETTIER_FALLBACK_RESOLVE) uses: codecov/codecov-action@v1.5.0 if: matrix.ENABLE_CODE_COVERAGE diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 683907a697..c848f248aa 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,10 +1,16 @@ name: Lint on: + # [prettierx ...] push: branches: - main - - patch-release + # [prettierx ...] + # - master + # - patch-release + - dev + - dev-* + - prettierx-* pull_request: jobs: diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml deleted file mode 100644 index 6f8df0eff0..0000000000 --- a/.github/workflows/lock.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: "Lock" - -on: - schedule: - - cron: "0 0 * * *" - -jobs: - lock: - runs-on: ubuntu-latest - steps: - - uses: dessant/lock-threads@v2 - with: - # https://github.com/dessant/lock-threads - github-token: ${{ github.token }} - issue-lock-inactive-days: "90" - issue-exclude-created-before: "" - issue-exclude-labels: "keep-unlocked, status:awaiting response" - issue-lock-labels: "locked-due-to-inactivity" - issue-lock-comment: "" - issue-lock-reason: "resolved" diff --git a/.github/workflows/mark-issue-duplicate.yml b/.github/workflows/mark-issue-duplicate.yml deleted file mode 100644 index eacddb855f..0000000000 --- a/.github/workflows/mark-issue-duplicate.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Mark Issue Duplicate - -on: - issue_comment: - types: - - created - -jobs: - mark-duplicate: - runs-on: ubuntu-latest - if: ${{ !github.event.issue.pull_request && startsWith(github.event.comment.body, 'Duplicate of ') }} - steps: - - uses: actions-cool/issues-helper@v2.2.1 - with: - actions: "mark-duplicate" - token: ${{ secrets.GITHUB_TOKEN }} - duplicate-labels: "type:duplicate" - close-issue: true diff --git a/.github/workflows/prettierx-npm-dev-test-nodejs.yml b/.github/workflows/prettierx-npm-dev-test-nodejs.yml new file mode 100644 index 0000000000..0304c98de2 --- /dev/null +++ b/.github/workflows/prettierx-npm-dev-test-nodejs.yml @@ -0,0 +1,37 @@ +# This workflow will do a clean install of npm dependencies and +# run tests across different versions of node +# For more information see: +# https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +name: npm clean dev test + +on: + push: + branches: + - dev + - dev-* + - prettierx-* + pull_request: + +jobs: + build: + # ref: + # https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix + runs-on: ${{ matrix.os }} + + strategy: + matrix: + node-version: + - 14.x + os: [ubuntu-latest, windows-latest] + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - run: npm i + - run: npm test + env: + CI: true diff --git a/.github/workflows/prod-test.yml b/.github/workflows/prod-test.yml index bbeed2a29a..40478783cb 100644 --- a/.github/workflows/prod-test.yml +++ b/.github/workflows/prod-test.yml @@ -1,10 +1,16 @@ name: Prod on: + # [prettierx ...] push: branches: - main - - patch-release + # [prettierx ...] + # - master + # - patch-release + - dev + - dev-* + - prettierx-* pull_request: jobs: @@ -23,7 +29,7 @@ jobs: - name: Cache Build Results id: build-cache - uses: actions/cache@v2.1.5 + uses: actions/cache@v2.1.6 with: path: .cache key: v2-build-cache-${{ hashFiles('yarn.lock') }}-${{ hashFiles('scripts/build/**/*') }}-${{ github.ref }}- @@ -33,7 +39,8 @@ jobs: v2-build-cache-${{ hashFiles('yarn.lock') }}-${{ hashFiles('scripts/build/**/*') }}-refs/heads/main- - name: Build Package - run: yarn build + # [prettierx] + run: yarn build-extra-dist - name: Upload Artifact uses: actions/upload-artifact@v2 @@ -115,6 +122,10 @@ jobs: with: node-version: ${{ matrix.node }} + - name: Config `ignore-engines=true` (Node.js 10) + if: matrix.node == '10' + run: yarn config set ignore-engines true + - name: Install Dependencies run: yarn install --frozen-lockfile diff --git a/.github/workflows/support.yml b/.github/workflows/support.yml deleted file mode 100644 index 1caae50591..0000000000 --- a/.github/workflows/support.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: "Support requests" - -on: - issues: - types: [labeled, unlabeled, reopened] - -jobs: - support: - runs-on: ubuntu-latest - steps: - - uses: dessant/support-requests@v2 - with: - github-token: ${{ github.token }} - support-label: "type:question" - issue-comment: > - :wave: @{issue-author}, we use the issue tracker exclusively for development purposes. - For questions, please use [Stack Overflow](https://stackoverflow.com/questions/ask?tags=prettier). diff --git a/.prettierrc b/.prettierrc index 7c80702fa4..af25a135e4 100644 --- a/.prettierrc +++ b/.prettierrc @@ -2,6 +2,3 @@ overrides: - files: "**/*.{js,mjs}" options: parser: meriyah - - files: ".prettierrc" - options: - parser: yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index dcbb867020..d9a6d25bfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,249 @@ -# 2.3.0 +# Changelog + + + +## prettierx 0.19.0-dev + +[compare prettierx-0.18.1...dev](https://github.com/brodybits/prettierx/compare/prettierx-0.18.1...dev) + +## prettier 2.3.1 + +[diff](https://github.com/prettier/prettier/compare/2.3.0...2.3.1) + +### Preserve attributes order for element node (#10958 by @dcyriller) + + +```handlebars +{{!-- Input --}} + +{{!-- Prettier stable --}} + +{{!-- Prettier main --}} + +``` + +### Track cursor position properly when it’s at the end of the range to format (#10938 by @j-f1) + +Previously, if the cursor was at the end of the range to format, it would simply be placed back at the end of the updated range. +Now, it will be repositioned if Prettier decides to add additional code to the end of the range (such as a semicolon). + + +```jsx +// Input (<|> represents the cursor) +const someVariable = myOtherVariable<|> +// range to format: ^^^^^^^^^^^^^^^ + +// Prettier stable +const someVariable = myOtherVariable;<|> +// range to format: ^^^^^^^^^^^^^^^ + +// Prettier main +const someVariable = myOtherVariable<|>; +// range to format: ^^^^^^^^^^^^^^^ +``` + +### Break the LHS of type alias that has complex type parameters (#10901 by @sosukesusuzki) + + +```ts +// Input +type FieldLayoutWith< + T extends string, + S extends unknown = { width: string } +> = { + type: T; + code: string; + size: S; +}; + +// Prettier stable +type FieldLayoutWith = + { + type: T; + code: string; + size: S; + }; + +// Prettier main +type FieldLayoutWith< + T extends string, + S extends unknown = { width: string } +> = { + type: T; + code: string; + size: S; +}; + +``` + +### Break the LHS of assignments that has complex type parameters (#10916 by @sosukesuzuki) + + +```ts +// Input +const map: Map< + Function, + Map +> = new Map(); + +// Prettier stable +const map: Map> = + new Map(); + +// Prettier main +const map: Map< + Function, + Map +> = new Map(); + +``` + +### Fix incorrectly wrapped arrow functions with return types (#10940 by @thorn0) + + +```ts +// Input +longfunctionWithCall12("bla", foo, (thing: string): complex> => { + code(); +}); + +// Prettier stable +longfunctionWithCall12("bla", foo, (thing: string): complex< + type +> => { + code(); +}); + +// Prettier main +longfunctionWithCall12( + "bla", + foo, + (thing: string): complex> => { + code(); + } +); +``` + +### Support TypeScript 4.3 (#10945 by @sosukesuzuki) + +#### [`override` modifiers in class elements](https://devblogs.microsoft.com/typescript/announcing-typescript-4-3/#override) + +```ts +class Foo extends { + override method() {} +} +``` + +#### [static index signatures (`[key: KeyType]: ValueType`) in classes](https://devblogs.microsoft.com/typescript/announcing-typescript-4-3/#static-index-signatures) + +```ts +class Foo { + static [key: string]: Bar; +} +``` + +#### [`get` / `set` in type declarations](https://devblogs.microsoft.com/typescript/announcing-typescript-4-3/#separate-write-types) + +```ts +interface Foo { + set foo(value); + get foo(): string; +} +``` + +### Avoid breaking call expressions after assignments with complex type arguments (#10949 by @sosukesuzuki) + + +```ts +// Input +const foo = call<{ + prop1: string; + prop2: string; + prop3: string; +}>(); + +// Prettier stable +const foo = + call<{ + prop1: string; + prop2: string; + prop3: string; + }>(); + +// Prettier main +const foo = call<{ + prop1: string; + prop2: string; + prop3: string; +}>(); + +``` + +### Fix order of `override` modifiers (#10961 by @sosukesuzuki) + +```ts +// Input +class Foo extends Bar { + abstract override foo: string; +} + +// Prettier stable +class Foo extends Bar { + override abstract foo: string; +} + +// Prettier main +class Foo extends Bar { + abstract override foo: string; +} +``` + +# prettier 2.3.0 [diff](https://github.com/prettier/prettier/compare/2.2.1...2.3.0) 🔗 [Release Notes](https://prettier.io/blog/2021/05/09/2.3.0.html) -# 2.2.1 +### prettier 2.2.1 [diff](https://github.com/prettier/prettier/compare/2.2.0...2.2.1) @@ -36,13 +275,13 @@ module.exports = class A extends B { }; ``` -# 2.2.0 +### prettier 2.2.0 [diff](https://github.com/prettier/prettier/compare/2.1.2...2.2.0) 🔗 [Release Notes](https://prettier.io/blog/2020/11/20/2.2.0.html) -# 2.1.2 +### prettier 2.1.2 [diff](https://github.com/prettier/prettier/compare/2.1.1...2.1.2) @@ -164,7 +403,7 @@ styled.div` - another ``` -# 2.1.1 +### prettier 2.1.1 [diff](https://github.com/prettier/prettier/compare/2.1.0...2.1.1) @@ -254,13 +493,116 @@ type Tail = T extends [infer U, ...infer R] ? R : never; ``` -# 2.1.0 +### prettier 2.1.0 [diff](https://github.com/prettier/prettier/compare/2.0.5...2.1.0) 🔗 [Release Notes](https://prettier.io/blog/2020/08/24/2.1.0.html) -# 2.0.5 +## prettierx 0.18.1 + +[compare prettierx-0.18.0...prettierx-0.18.1](https://github.com/brodybits/prettierx/compare/prettierx-0.18.0...prettierx-0.18.1) + +- cleanup(src): add another objectCurlySpacing option comment +- Update some dependencies + - chalk -> 4.1.1 + - get-stream -> 6.0.1 + - mem -> 8.1.1 + +## prettierx 0.18.0 + +[compare prettierx-0.17.0...prettierx-0.18.0](https://github.com/brodybits/prettierx/compare/prettierx-0.17.0...prettierx-0.18.0) + +- Update some dependencies + - @babel/code-frame -> 7.12.13 + - ci-info -> 3.1.1 + - diff -> 5.0.0 + - globby -> 11.0.3 + - lodash -> 4.17.21 + - mem -> 8.1.0 + - postcss-less -> 4.0.1 + - resolve -> 1.20.0 + - semver -> 7.3.5 + - string-width -> 4.2.2 + - unified -> 9.2.1 + +## prettierx 0.17.0 + +- replace --no-align-ternary-lines with --offset-ternary-expressions (with updated formatting) +- replace --no-bracket-spacing with finer-grained options +- replace --paren-spacing with finer-grained options +- update graphql -> 15.5.0 +- update some descriptions & update some documentation + +[compare prettierx-0.16.1...prettierx-0.17.0](https://github.com/brodybits/prettierx/compare/prettierx-0.16.1...prettierx-0.17.0) + +## prettierx 0.16.1 + +- fix some descriptions +- update some documentation + +[compare prettierx-0.16.0...prettierx-0.16.1](https://github.com/brodybits/prettierx/compare/prettierx-0.16.0...prettierx-0.16.1) + +## prettierx 0.16.0 + +- add & implement --break-long-method-chains option +- Update fast-glob -> 3.2.5 in dependencies +- cleanup: remove extra parent.object conditions not needed + +[compare prettierx-0.15.0...prettierx-0.16.0](https://github.com/brodybits/prettierx/compare/prettierx-0.15.0...prettierx-0.16.0) + +## prettierx 0.15.0 + +- add --html-void-tags option +- update some dependencies + - @babel/parser -> 7.12.11 + - cjk-regex -> 2.0.1 + - globby -> 11.0.2 + - graphql -> 15.4.0 + - html-element-attributes -> 2.3.0 +- fix & update some documentation + +[compare prettierx-0.14.3...prettierx-0.15.0](https://github.com/brodybits/prettierx/compare/prettierx-0.14.3...prettierx-0.15.0) + +## prettierx 0.14.3 + +- Update some dependencies + - mem -> 6.1.1 + - n-readlines -> 1.0.1 + - resolve -> 1.19.0 + - semver -> 7.3.4 + - yaml-unist-parser -> 1.3.1 + +[compare prettierx-0.14.2...prettierx-0.14.3](https://github.com/brodybits/prettierx/compare/prettierx-0.14.2...prettierx-0.14.3) + +## prettierx 0.14.2 + +- Add tslib to avoid a peerDependencies warning +- Update some dependencies + - @babel/code-frame -> 7.12.11 + - @babel/parser -> 7.12.0 + - camelcase -> 6.2.0 + - lodash -> 4.17.20 + - unified -> 9.2.0 + +[compare prettierx-0.14.0...prettierx-0.14.2](https://github.com/brodybits/prettierx/compare/prettierx-0.14.0...prettierx-0.14.2) + +NOTE: prettierx release 0.14.1 was inadvertently skipped in package.json. + +## prettierx 0.14.0 + +- merge updates from Prettier 2.0.0 ... 2.0.5, with some workarounds +- parse TypeScript using Babel by default +- move the `flow-parser` parser to `peerDependenciesMeta`, as an optional dependency (note that Prettier and `prettierx` use Babel to parse Flow by default) +- update documentation of `--space-before-function-paren` and `--generator-star-spacing` features +- apply some updates for `--paren-spacing` feature from `wp-prettier-2.0.5` branch of the `wp-prettier` fork +- resolve a limited number of issues related to the `--paren-spacing` feature +- apply some additional source code cleanup +- update some dependencies + +[compare prettierx-0.13.1...prettierx-0.14.0](https://github.com/brodybits/prettierx/compare/prettierx-0.13.1...prettierx-0.14.0) + +### prettier 2.0.5 [diff](https://github.com/prettier/prettier/compare/2.0.4...2.0.5) @@ -301,13 +643,13 @@ This fixes issues that the users of Atom and WebStorm faced with 2.0.4. Prettier now switches to using the `resolve` module for resolving configuration files and plugins if it detects that `require.resolve` isn't Node's builtin function (doesn't support the second argument), which happens in environments like editor extensions. To force the fallback, set the `PRETTIER_FALLBACK_RESOLVE` environment variable to `true`. -# 2.0.4 +### prettier 2.0.4 [diff](https://github.com/prettier/prettier/compare/2.0.3...2.0.4) #### Revert [#7869](https://github.com/prettier/prettier/pull/7869), "[TypeScript] format TSAsExpression with same logic as BinaryExpression" ([#7958](https://github.com/prettier/prettier/pull/7958)) -# 2.0.3 +### prettier 2.0.3 [diff](https://github.com/prettier/prettier/compare/2.0.2...2.0.3) @@ -578,7 +920,7 @@ type T = { - Update `isSCSS` regex ([#7922](https://github.com/prettier/prettier/pull/7922) by [@fisker](https://github.com/fisker)) - Fix formatting of empty files ([#7921](https://github.com/prettier/prettier/pull/7921) by [@fisker](https://github.com/fisker)) -# 2.0.2 +### prettier 2.0.2 [diff](https://github.com/prettier/prettier/compare/2.0.1...2.0.2) @@ -679,19 +1021,92 @@ export type a = | (baz1 & baz2); ``` -# 2.0.1 +### prettier 2.0.1 [diff](https://github.com/prettier/prettier/compare/2.0.0...2.0.1) #### API: Fix build script to not corrupt `import-fresh` module ([#7820](https://github.com/prettier/prettier/pull/7820) by [@thorn0](https://github.com/thorn0)) -# 2.0.0 +### prettier 2.0.0 [diff](https://github.com/prettier/prettier/compare/1.19.1...2.0.0) 🔗 [Release Notes](https://prettier.io/blog/2020/03/21/2.0.0.html) -# 1.19.1 +## prettierx 0.13.1 + +- fix a spelling error in description of importFormatting opt +- Update unified -> 9.1.0 - dependency (#279) + +[compare prettierx-0.14.0...dev](https://github.com/brodybits/prettierx/compare/prettierx-0.14.0...dev) + +## prettierx 0.13.0 + +- option to import on one line in JS & TS (#265) +- update `@babel/parser` -> `7.10.5` +- update yaml dependency items (#266) + +[compare prettierx-0.12.1...prettierx-0.13.0](https://github.com/brodybits/prettierx/compare/prettierx-0.12.1...prettierx-0.13.0) + +## prettierx 0.12.1 + +- update some dependencies + - @babel/code-frame -> 7.10.4 + - @babel/parser -> 7.10.4 + - @iarna/toml -> 2.2.5 + - angular-html-parser -> 1.7.1 + - Update chalk -> 4.1.0 + - escape-string-regexp -> 4.0.0 + - graphql -> 15.3.0 + - postcss-scss -> 2.1.1 +- add yaml note to package.json + +[compare prettierx-0.12.0...prettierx-0.12.1](https://github.com/brodybits/prettierx/compare/prettierx-0.12.0...prettierx-0.12.1) + +## prettierx 0.12.0 + +- add --break-before-else option (#224) +- update some dependencies + +[compare prettierx-0.11.3...prettierx-0.12.0](https://github.com/brodybits/prettierx/compare/prettierx-0.11.3...prettierx-0.12.0) + +## prettierx 0.11.3 + +- yaml@1.8.3 explicitly in dependencies - needed for extra npm dist build test to keep working, due to an issue between @babel/parser & recent yaml@1.9.0 update +- update and fix some comments for prettierx-specific code +- remove lib entry from package files (not needed) + +[compare prettierx-0.11.2...dev](https://github.com/brodybits/prettierx/compare/prettierx-0.11.2...dev) + +## prettierx 0.11.2 + +- update parse-srcset -> 1.0.2 (npm hosted version) ref: #167 +- update jest-docblock -> 25.3.0 (PR #216) +- update some other dependencies + +[compare prettierx-0.11.1...prettierx-0.11.2](https://github.com/brodybits/prettierx/compare/prettierx-0.11.1...prettierx-0.11.2) + +## prettierx 0.11.1 + +- Update dependency minimist to v1.2.3 - SECURITY (#176) +- Update parse-srcset -> 03104fe (#170) +- other updates to dependencies +- add top-level files to package files + - CHANGELOG.md + - LICENSE + - README.md + +[compare prettierx-0.11.0...prettierx-0.11.0](https://github.com/brodybits/prettierx/compare/prettierx-0.11.0...prettierx-0.11.1) + +## prettierx 0.11.0 + +[compare prettierx-0.10.0...prettierx-0.11.0](https://github.com/brodybits/prettierx/compare/prettierx-0.10.0...prettierx-0.11.0) + +## prettierx 0.10.0 + +[compare prettierx-0.9.0...prettierx-0.10.0](https://github.com/brodybits/prettierx/compare/prettierx-0.9.0...prettierx-0.10.0) + +### prettier 1.19.1 [diff](https://github.com/prettier/prettier/compare/1.19.0...1.19.1) @@ -735,13 +1150,19 @@ export const getVehicleDescriptor = async ( > => {}; ``` -# 1.19.0 +### prettier 1.19.0 [diff](https://github.com/prettier/prettier/compare/1.18.2...1.19.0) 🔗 [Release Notes](https://prettier.io/blog/2019/11/09/1.19.0.html) -# 1.18.2 +## prettierx 0.9.0 + +- no bundled TypeScript & no prod build + +[compare prettierx-0.8.0...prettierx-0.9.0](https://github.com/brodybits/prettierx/compare/prettierx-0.8.0...prettierx-0.9.0) + +### prettier 1.18.2 [diff](https://github.com/prettier/prettier/compare/1.18.1...1.18.2) @@ -752,7 +1173,7 @@ export const getVehicleDescriptor = async ( [#6199]: https://github.com/prettier/prettier/pull/6199 [@duailibe]: https://github.com/duailibe -# 1.18.1 +### prettier 1.18.1 [diff](https://github.com/prettier/prettier/compare/1.18.0...1.18.1) @@ -796,13 +1217,21 @@ export const getVehicleDescriptor = async ( [@duailibe]: https://github.com/duailibe [@sosukesuzuki]: https://github.com/sosukesuzuki -# 1.18.0 +## prettierx 0.8.0 + +[compare prettierx-0.7.0...prettierx-0.8.0](https://github.com/brodybits/prettierx/compare/prettierx-0.7.0...prettierx-0.8.0) + +### prettier 1.18.0 [diff](https://github.com/prettier/prettier/compare/1.17.1...1.18.0) 🔗 [Release Notes](https://prettier.io/blog/2019/06/06/1.18.0.html) -# 1.17.1 +## prettierx 0.7.1 + +[compare prettierx-0.7.0...prettierx-0.7.1](https://github.com/brodybits/prettierx/compare/prettierx-0.7.0...prettierx-0.7.1) + +### prettier 1.17.1 [diff](https://github.com/prettier/prettier/compare/1.17.0...1.17.1) @@ -963,62 +1392,53 @@ export const getVehicleDescriptor = async ( [#6080]: https://github.com/prettier/prettier/pull/6080 [#6087]: https://github.com/prettier/prettier/pull/6087 -# 1.17.0 +## prettierx 0.7.0 + +[compare prettierx-0.6.0...prettierx-0.7.0](https://github.com/brodybits/prettierx/compare/prettierx-0.6.0...prettierx-0.7.0) + +- escape-string-regexp@2.0.0 & other updates in dependencies +- drop support for Node.js pre-8.0 + +### prettier 1.17.0 [diff](https://github.com/prettier/prettier/compare/1.16.2...1.17.0) 🔗 [Release Notes](https://prettier.io/blog/2019/04/12/1.17.0.html) -# 1.16.4 +## prettierx 0.6.0 -[diff](https://github.com/prettier/prettier/compare/1.16.3...1.16.4) +[compare prettierx-0.5.0...prettierx-0.6.0](https://github.com/brodybits/prettierx/compare/prettierx-0.5.0...prettierx-0.6.0) -- API: Fix `prettier.getSupportInfo()` reporting babel parser for older versions of Prettier. ([#5826] by [@azz]) +--paren-spacing option from WordPress ([brodybits/prettierx#16](https://github.com/brodybits/prettierx/pull/16)) - In version `1.16.0` of Prettier, the `babylon` parser was renamed to `babel`. Unfortunately this lead to a minor breaking change: `prettier.getSupportInfo('1.15.0')` would report that it supported `babel`, not `babylon`, which breaks text-editor integrations. This has now been fixed. +## prettierx 0.5.0 -[@azz]: https://github.com/azz -[#5826]: https://github.com/prettier/prettier/pull/5826 +[compare prettierx-0.4.1...prettierx-0.5.0](https://github.com/brodybits/prettierx/compare/prettierx-0.4.1...prettierx-0.5.0) -# 1.16.3 +**prettierx-specific updates:** -[diff](https://github.com/prettier/prettier/compare/1.16.2...1.16.3) +- Update `@typescript-eslint/typescript-estree` dependency, to version `1.4.1` (`@typescript-eslint/typescript-estree` update is needed to resolve issue with generics, as discussed in [prettier/prettier#5824](https://github.com/prettier/prettier/pull/5824)) +- explicitly comment old parsers out of `src/main/support.js` -- TypeScript: Revert "Update typescript-estree to new package name" ([#5818] by [@ikatyang]) +**updates from prettier 1.17.0-dev:** - There's an internal change introduced in Prettier 1.16.2, - which updated `typescript-estree` to its new package name, - but unfortunately it broke the output - so we reverted it as a temporary workaround for now. +- Tweak the plugin directory search ([prettier/prettier#5819](https://github.com/prettier/prettier/pull/5819)) +- Adds LWC Parser to support unquoted interop attributes ([prettier/prettier#5800](https://github.com/prettier/prettier/pull/5800)) +- feat(markdown): do not align table contents if it exceeds the print width and `--prose-wrap never` is set ([prettier/prettier#5701](https://github.com/prettier/prettier/pull/5701)) +- chore: update typescript-estree to new package name ([prettier/prettier#5799](https://github.com/prettier/prettier/pull/5799)) - - ```ts - // Input - export default { - load(k: K, t: T) { - return {k, t}; - } - } +### prettier 1.16.4 - // Output (Prettier 1.16.2) - export default { - load(k: K, t: T) { - return { k, t }; - } - }; +[diff](https://github.com/prettier/prettier/compare/1.16.3...1.16.4) - // Output (Prettier 1.16.3) - export default { - load(k: K, t: T) { - return { k, t }; - } - }; - ``` +- API: Fix `prettier.getSupportInfo()` reporting babel parser for older versions of Prettier. ([#5826] by [@azz]) -[@ikatyang]: https://github.com/ikatyang -[#5818]: https://github.com/prettier/prettier/pull/5818 + In version `1.16.0` of Prettier, the `babylon` parser was renamed to `babel`. Unfortunately this lead to a minor breaking change: `prettier.getSupportInfo('1.15.0')` would report that it supported `babel`, not `babylon`, which breaks text-editor integrations. This has now been fixed. + +[@azz]: https://github.com/azz +[#5826]: https://github.com/prettier/prettier/pull/5826 -# 1.16.2 +### prettier 1.16.2 [diff](https://github.com/prettier/prettier/compare/1.16.1...1.16.2) @@ -1072,7 +1492,23 @@ export const getVehicleDescriptor = async ( [#5797]: https://github.com/prettier/prettier/pull/5797 [#5804]: https://github.com/prettier/prettier/pull/5804 -# 1.16.1 +## prettierx 0.4.1 + +[compare prettierx-0.4.0...prettierx-0.4.1](https://github.com/brodybits/prettierx/compare/prettierx-0.4.0...prettierx-0.4.1) + +- [prettierx] fix alignTernaryLines behavior ([brodybits/prettierx-0.4.x#46](https://github.com/brodybits/prettierx-0.4.x/pull/46)) + +## prettierx 0.4.0 + +[compare prettierx-0.3.1...prettierx-0.4.0](https://github.com/brodybits/prettierx/compare/prettierx-0.3.1...prettierx-0.4.0) + +- [prettierx] --no-align-ternary-lines option ([brodybits/prettierx-0.4.x#41](https://github.com/brodybits/prettierx-0.4.x/pull/41)) + +## prettierx 0.3.1 + +[compare prettierx-0.3.0...prettierx-0.3.1](https://github.com/brodybits/prettierx/compare/prettierx-0.3.0...prettierx-0.3.1) + +### prettier 1.16.1 [diff](https://github.com/prettier/prettier/compare/1.16.0...1.16.1) @@ -1187,13 +1623,104 @@ export const getVehicleDescriptor = async ( [#5785]: https://github.com/prettier/prettier/pull/5785 [#5790]: https://github.com/prettier/prettier/pull/5790 -# 1.16.0 +### prettier 1.16.0 [diff](https://github.com/prettier/prettier/compare/1.15.3...1.16.0) 🔗 [Release Notes](https://prettier.io/blog/2019/01/20/1.16.0.html) -# 1.15.3 +## prettierx 0.3.0 + +[compare prettierx-0.2.1...prettierx-0.3.0](https://github.com/brodybits/prettierx/compare/prettierx-0.2.1...prettierx-0.3.0) + +- [prettierx] --no-indent-chains option ([brodybits/prettierx-0.4.x#5](https://github.com/brodybits/prettierx-0.4.x/pull/5)) +- [prettierx] -- align-object-properties option ([brodybits/prettierx-0.4.x#35](https://github.com/brodybits/prettierx-0.4.x/pull/35)) + +## prettierx 0.2.1 + +[compare prettierx-0.2.0...prettierx-0.2.1](https://github.com/brodybits/prettierx/compare/prettierx-0.2.0...prettierx-0.2.1) + +- chore: update typescript-estree to 18.0.0 ([prettier/prettier#5750](https://github.com/prettier/prettier/pull/5750)) +- fix: update typescript and typescript-estree to latest ([prettier/prettier#5728](https://github.com/prettier/prettier/pull/5728)) +- docs: fix Windows build (#5742) ([prettier/prettier#5743](https://github.com/prettier/prettier/pull/5743)) + +## prettierx 0.2.0 + +[compare prettierx-0.1.0...prettierx-0.2.0](https://github.com/brodybits/prettierx/compare/prettierx-0.1.0...prettierx-0.2.0) + +- fix(javascript): skip .connect() method when composing fun ([prettier/prettier#5739](https://github.com/prettier/prettier/pull/5739)) +- docs: remove redundant "./" from relative links ([prettier/prettier#5741](https://github.com/prettier/prettier/pull/5741)) +- Fix formatting of lists in SCSS property/variable values ([prettier/prettier#5710](https://github.com/prettier/prettier/pull/5710)) +- Escape spaces within file names in pre-commit hook script ([prettier/prettier#5721](https://github.com/prettier/prettier/pull/5721)) +- typescript: remove unneeded parentheses around type annotation ([prettier/prettier#5724](https://github.com/prettier/prettier/pull/5724)) +- Add solidity plugin to list of plugins ([prettier/prettier#5726](https://github.com/prettier/prettier/pull/5726)) +- chore(website): upgrade react-dom to 16.3.3 ([prettier/prettier#5720](https://github.com/prettier/prettier/pull/5720)) +- Update Webstorm integration docs ([prettier/prettier#5694](https://github.com/prettier/prettier/pull/5694)) + +## prettierx 0.1.0 + +[compare prettierx-0.0.3...prettierx-0.1.0](https://github.com/brodybits/prettierx/compare/prettierx-0.0.3...prettierx-0.1.0) + +- standard-like formatting ([brodybits/prettierx-0.4.x#32](https://github.com/brodybits/prettierx-0.4.x/pull/32)) +- Drop support for Node.js version 4 ([brodybits/prettierx-0.4.x#31](https://github.com/brodybits/prettierx-0.4.x/pull/31)) + +## prettierx 0.0.3 + +[compare prettierx-0.0.2...prettierx-0.0.3](https://github.com/brodybits/prettierx/compare/prettierx-0.0.2...prettierx-0.0.3) + +- prettierx fix space-before-function-paren - babel parser ([brodybits/prettierx-0.4.x#29](https://github.com/brodybits/prettierx-0.4.x/pull/29)) + +## prettierx 0.0.2 + +[compare prettierx-0.0.1...prettierx-0.0.2](https://github.com/brodybits/prettierx/compare/prettierx-0.0.1...prettierx-0.0.2) + +- Update copyright line ([prettier/prettier#5455](https://github.com/prettier/prettier/pull/5455)) +- fix(mdx): handle inline html correctly ([prettier/prettier#5704](https://github.com/prettier/prettier/pull/5704)) + +## prettierx 0.0.1 + +- prettierx space-before-function-paren option ([brodybits/prettierx-0.4.x#6](https://github.com/brodybits/prettierx-0.4.x/pull/6)) +- Update package.json, docs, scripts, tests, etc. for prettierx + +[compare 1ca4731...prettierx-0.0.1](https://github.com/brodybits/prettierx/compare/1ca4731...prettierx-0.0.1) + +### prettier 1ca4731 (1.16.0-dev) + +[compare prettier 1.15.3...1ca4731](https://github.com/prettier/prettier/compare/1.15.3...1ca4731) + +- docs: Happy New Year! 🎁 ([#5699](https://github.com/prettier/prettier/pull/5699)) +- fix(ng,vue): add parens to avoid unexpected `}}` in interpolations ([#5657](https://github.com/prettier/prettier/pull/5657)) +- feat: add babel-flow ([#5685](https://github.com/prettier/prettier/pull/5685)) +- fix(playground): backward compatibility for --parser babylon ([#5690](https://github.com/prettier/prettier/pull/5690)) +- fix(playground): code sample for --parser babylon +- fix(playground): backward compatibility for --parser babylon ([#5688](https://github.com/prettier/prettier/pull/5688)) +- Rename "babylon" with "babel" ([#5647](https://github.com/prettier/prettier/pull/5647)) +- Restore --check option docs ([#5674](https://github.com/prettier/prettier/pull/5674)) +- feat(website): enable docs versioning ([#5676](https://github.com/prettier/prettier/pull/5676)) +- Temporary remove --check docs until 1.16 is released to avoid confusion ([#5671](https://github.com/prettier/prettier/pull/5671)) +- fix(flow,ts): format `/* HTML */` templates ([#5658](https://github.com/prettier/prettier/pull/5658)) +- Add --check option ([#5629](https://github.com/prettier/prettier/pull/5629)) +- chore: update azure pipelines ([#5611](https://github.com/prettier/prettier/pull/5611)) +- Update string-width to support emoji natively ([#5646](https://github.com/prettier/prettier/pull/5646)) +- Fix formatting with --range-start / --range-end ([#5632](https://github.com/prettier/prettier/pull/5632)) +- fix(printer-postcss): ignore escape \ and escaped / in Less ([#5597](https://github.com/prettier/prettier/pull/5597)) +- feat(html): format script with "application/ld+json" ([#5642](https://github.com/prettier/prettier/pull/5642)) +- Add support for class private methods ([#5637](https://github.com/prettier/prettier/pull/5637)) +- fix(vue): tag names are case-sensitive ([#5606](https://github.com/prettier/prettier/pull/5606)) +- fix(javascript): correct indentation for expression in root template ([#5607](https://github.com/prettier/prettier/pull/5607)) +- Fix incorrect grammar ([#5626](https://github.com/prettier/prettier/pull/5626)) +- Remove the dynamic `require()` call in the standalone bundle ([#5612](https://github.com/prettier/prettier/pull/5612)) +- test: update snapshots +- feat(html): preserve surrounding linebreaks ([#5596](https://github.com/prettier/prettier/pull/5596)) +- Add support for the React `useEffect` hook ([#5608](https://github.com/prettier/prettier/pull/5608)) +- Don’t run tests on Node 6 ([#5613](https://github.com/prettier/prettier/pull/5613)) +- fix: get rid of CRLF ([#5494](https://github.com/prettier/prettier/pull/5494)) +- Reformat the first version info in the option docs ([#5604](https://github.com/prettier/prettier/pull/5604)) +- Update example for `*.vue` ([#5605](https://github.com/prettier/prettier/pull/5605)) +- feat: add mjml extension to html language ([#5505](https://github.com/prettier/prettier/pull/5505)) +- feat(html): smart quote for attributes ([#5590](https://github.com/prettier/prettier/pull/5590)) + +### prettier 1.15.3 [diff](https://github.com/prettier/prettier/compare/1.15.2...1.15.3) @@ -1230,7 +1757,7 @@ export const getVehicleDescriptor = async ( - CLI: report status code `0` for `--list-different` + `--write` ([#5512](https://github.com/prettier/prettier/pull/5512)) - Standalone: fix a regression for browser compatibility ([#5560](https://github.com/prettier/prettier/pull/5560)) -# 1.15.2 +### prettier 1.15.2 [diff](https://github.com/prettier/prettier/compare/1.15.1...1.15.2) @@ -1260,32 +1787,32 @@ export const getVehicleDescriptor = async ( - Markdown: identify CJK correctly ([#5402](https://github.com/prettier/prettier/pull/5402)) - MDX: treat JSX code block same as in Markdown ([#5391](https://github.com/prettier/prettier/pull/5391)) -# 1.15.1 +### prettier 1.15.1 [diff](https://github.com/prettier/prettier/compare/1.15.0...1.15.1) - Markdown: do not keep increasing backslashes for dollar sign ([#5358](https://github.com/prettier/prettier/pull/5358)) -# 1.15.0 +### prettier 1.15.0 [diff](https://github.com/prettier/prettier/compare/1.14.3...1.15.0) 🔗 [Release Notes](https://prettier.io/blog/2018/11/07/1.15.0.html) -# 1.14.3 +### prettier 1.14.3 [diff](https://github.com/prettier/prettier/compare/1.14.2...1.14.3) - Chore: add missing LICENSE ([#5114](https://github.com/prettier/prettier/pull/5114)) -# 1.14.2 +### prettier 1.14.2 [diff](https://github.com/prettier/prettier/compare/1.14.1...1.14.2) - YAML: fix the line ending issue on Windows ([#4957](https://github.com/prettier/prettier/pull/4957)) - TypeScript: better error message ([#4947](https://github.com/prettier/prettier/pull/4947)) -# 1.14.1 +### prettier 1.14.1 [diff](https://github.com/prettier/prettier/compare/1.14.0...1.14.1) @@ -1305,19 +1832,19 @@ export const getVehicleDescriptor = async ( - CLI: ignore .git, .svn and .hg directories ([#4906](https://github.com/prettier/prettier/pull/4906)) - CLI: support TOML configuration files ([#4877](https://github.com/prettier/prettier/pull/4877)) -# 1.14.0 +### prettier 1.14.0 [diff](https://github.com/prettier/prettier/compare/1.13.7...1.14.0) 🔗 [Release Notes](https://prettier.io/blog/2018/07/29/1.14.0.html) -# 1.13.7 +### prettier 1.13.7 [diff](https://github.com/prettier/prettier/compare/1.13.6...1.13.7) - Remove calls to `eval("require")` in the distributed code ([#4766](https://github.com/prettier/prettier/pull/4766)) -# 1.13.6 +### prettier 1.13.6 [diff](https://github.com/prettier/prettier/compare/1.13.5...1.13.6) @@ -1325,7 +1852,7 @@ export const getVehicleDescriptor = async ( - Preserve type parameters of import-types in TypeScript ([#4662](https://github.com/prettier/prettier/pull/4662)) - Preserve parens for type casting for sub-item ([#4648](https://github.com/prettier/prettier/pull/4648)) -# 1.13.5 +### prettier 1.13.5 [diff](https://github.com/prettier/prettier/compare/1.13.4...1.13.5) @@ -1334,38 +1861,38 @@ export const getVehicleDescriptor = async ( - Preserve decorator on TypeScript interfaces ([#4632](https://github.com/prettier/prettier/pull/4632)) - Inline \_ or \$ in the root of a method chain ([#4621](https://github.com/prettier/prettier/pull/4621)) -# 1.13.4 +### prettier 1.13.4 [diff](https://github.com/prettier/prettier/compare/1.13.3...1.13.4) - Fix a regression when printing graphql-in-js ([#4616](https://github.com/prettier/prettier/pull/4616)) -# 1.13.3 +### prettier 1.13.3 [diff](https://github.com/prettier/prettier/compare/1.13.2...1.13.3) - Fix a regression when printing `hasOwnProperty` and other functions in `Object`'s prototype ([#4603](https://github.com/prettier/prettier/pull/4603)) - Fix a regression in exit status when using `--debug-check` and `--list-different` ([#4600](https://github.com/prettier/prettier/pull/4600)) -# 1.13.2 +### prettier 1.13.2 [diff](https://github.com/prettier/prettier/compare/1.13.1...1.13.2) - Republished 1.13.1 with missing README included this time -# 1.13.1 +### prettier 1.13.1 [diff](https://github.com/prettier/prettier/compare/1.13.0...1.13.1) - Revert default parser change in API (still present in CLI) -# 1.13.0 +### prettier 1.13.0 [diff](https://github.com/prettier/prettier/compare/1.12.1...1.13.0) 🔗 [Release Notes](https://prettier.io/blog/2018/05/23/1.13.0.html) -# 1.12.1 +### prettier 1.12.1 [diff](https://github.com/prettier/prettier/compare/1.12.0...1.12.1) @@ -1373,44 +1900,44 @@ export const getVehicleDescriptor = async ( - Wrap awaits in unary expressions with parens ([#4315](https://github.com/prettier/prettier/pull/4315)) - Fix style regression on flow union types ([#4325](https://github.com/prettier/prettier/pull/4325)) -# 1.12.0 +### prettier 1.12.0 [diff](https://github.com/prettier/prettier/compare/1.11.1...1.12.0) 🔗 [Release Notes](https://prettier.io/blog/2018/04/11/1.12.0.html) -# 1.11.1 +### prettier 1.11.1 [diff](https://github.com/prettier/prettier/compare/1.11.0...1.11.1) - 1.11.0 was incorrectly shipped with the wrong version of the TypeScript parser, which broke conditional types. This release fixes it. - Fixed an issue relating to deprecated parsers ([#4072](https://github.com/prettier/prettier/pull/4072)) -# 1.11.0 +### prettier 1.11.0 [diff](https://github.com/prettier/prettier/compare/1.10.2...1.11.0) 🔗 [Release Notes](https://prettier.io/blog/2018/02/26/1.11.0.html) -# 1.10.2 +### prettier 1.10.2 [diff](https://github.com/prettier/prettier/compare/1.10.1...1.10.2) - Fixed an issue printing .vue files with self-closing tags. (#3705 by duailibe) -# 1.10.1 +### prettier 1.10.1 [diff](https://github.com/prettier/prettier/compare/1.10.0...1.10.1) - Fixed an issue where the CLI fails to resolve a file. -# 1.10.0 +### prettier 1.10.0 [diff](https://github.com/prettier/prettier/compare/1.9.2...1.10.0) 🔗 [Release Notes](https://prettier.io/blog/2018/01/10/1.10.0.html) -# 1.9.2 +### prettier 1.9.2 [diff](https://github.com/prettier/prettier/compare/1.9.1...1.9.2) @@ -1425,7 +1952,7 @@ export const getVehicleDescriptor = async ( - Fix closing parens on multi-line intersection/union type (#3436 by josephfrazier) - Don't break single argument destructuring arguments (for arrays and with simple default values) (#3443 by duailibe) -# 1.9.1 +### prettier 1.9.1 [diff](https://github.com/prettier/prettier/compare/1.9.0...1.9.1) @@ -1435,13 +1962,13 @@ export const getVehicleDescriptor = async ( - Fixed a bug when using glob `**/*` which would try to format directories (#3411 by duailibe) - Fixed a bug when `.editorconfig` had `max_line_length = "off"` (#3412 by duailibe) -# 1.9.0 +### prettier 1.9.0 [diff](https://github.com/prettier/prettier/compare/1.8.2...1.9.0) 🔗 [Release Notes](https://prettier.io/blog/2017/12/05/1.9.0.html) -# 1.8.2 +### prettier 1.8.2 [diff](https://github.com/prettier/prettier/compare/1.8.1...1.8.2) @@ -1450,7 +1977,7 @@ export const getVehicleDescriptor = async ( - TypeScript: Parenthesis around TSAsExpression inside TSAbstractClassDeclaration (#3191 by duailibe) - JSON: Print JSON top comments as leading comments of root node (#3187 by duailibe) -# 1.8.1 +### prettier 1.8.1 [diff](https://github.com/prettier/prettier/compare/1.8.0...1.8.1) @@ -1461,13 +1988,13 @@ export const getVehicleDescriptor = async ( - Markdown: Do not break on unbreakable place (#3177 by ikatyang) - Markdown: Do not break before special prefix (#3172 by ikatyang) -# 1.8.0 +### prettier 1.8.0 [diff](https://github.com/prettier/prettier/compare/1.7.4...1.8.0) 🔗 [Release Notes](https://prettier.io/blog/2017/11/07/1.8.0.html) -# 1.7.4 +### prettier 1.7.4 [diff](https://github.com/prettier/prettier/compare/1.7.3...1.7.4) @@ -1475,7 +2002,7 @@ export const getVehicleDescriptor = async ( - Update cosmiconfig to v3.1.0 (#2952 by ikatyang) - Respect --stdin-filepath, regardless of config source (#2948 by azz) -# 1.7.3 +### prettier 1.7.3 [diff](https://github.com/prettier/prettier/compare/1.7.2...1.7.3) @@ -1483,13 +2010,13 @@ export const getVehicleDescriptor = async ( - Fix: ignore and show warning for unknown option from config file (#2929 by ikatyang) - Don't use parens with optional chaining member expressions (#2921 by azz) -# 1.7.2 +### prettier 1.7.2 [diff](https://github.com/prettier/prettier/compare/1.7.1...1.7.2) - Revert "Fix line break in test declarations with a single argument function declaration" (#2912) -# 1.7.1 +### prettier 1.7.1 [diff](https://github.com/prettier/prettier/compare/1.7.0...1.7.1) @@ -1518,13 +2045,13 @@ export const getVehicleDescriptor = async ( - Fix editor styling on empty editors (#2904 by jakegavin) - Fix printing of comments between decorators and method names (#2906 by azz) -# 1.7.0 +### prettier 1.7.0 [diff](https://github.com/prettier/prettier/compare/1.6.1...1.7.0) 🔗 [Release Notes](https://prettier.io/blog/2017/09/15/1.7.0.html) -# 1.6.1 +### prettier 1.6.1 [diff](https://github.com/prettier/prettier/compare/1.6.0...1.6.1) @@ -1533,43 +2060,43 @@ export const getVehicleDescriptor = async ( - Fix union type with type params regression (#2688) - Fix flow parenthesis regression (#2687) -# 1.6.0 +### prettier 1.6.0 [diff](https://github.com/prettier/prettier/compare/1.5.3...1.6.0) 🔗 [Release Notes](https://prettier.io/blog/2017/08/29/1.6.0.html) -# 1.5.3 +### prettier 1.5.3 [diff](https://github.com/prettier/prettier/compare/1.5.2...1.5.3) - Force trailingComma option to "none" when parser is JSON (#2335) -# 1.5.2 +### prettier 1.5.2 [diff](https://github.com/prettier/prettier/compare/1.5.1...1.5.2) - Full printing support for GraphQL and various bug fixes - Fixes for range formatting for JSON and CSS (#2295, #2298) -# 1.5.1 +### prettier 1.5.1 [diff](https://github.com/prettier/prettier/compare/1.5.0...1.5.1) - Go back to babylon beta 13 (#2289) - Inline import('x') to avoid having trailing comma (#2288) -# 1.5.0 +### prettier 1.5.0 [diff](https://github.com/prettier/prettier/compare/1.4.4...1.5.0) 🔗 [Release Notes](https://prettier.io/blog/2017/06/28/1.5.0.html) -# 1.4.4 +### prettier 1.4.4 🔗 Fix postcss, I forgot to re-run the build script :( -# 1.4.3 +### prettier 1.4.3 [diff](https://github.com/prettier/prettier/compare/1.4.2...1.4.3) @@ -1582,7 +2109,7 @@ Formatting change: Lots of small fixes, mainly for TypeScript. -# 1.4.2 +### prettier 1.4.2 [diff](https://github.com/prettier/prettier/compare/1.4.1...1.4.2) @@ -1591,25 +2118,25 @@ Lots of small fixes, mainly for TypeScript. - fix(typescript): no semi after export default abstract class, fixes (#1937) - TypeScript: fix trailing comma in enum (#1938) -# 1.4.1 +### prettier 1.4.1 [diff](https://github.com/prettier/prettier/compare/1.4.0...1.4.1) - Lots of fixes for TypeScript and regressions from 1.4.0. If you are using 1.4.0, you should migrate to 1.4.1 asap ;) -# 1.4.0 +### prettier 1.4.0 [diff](https://github.com/prettier/prettier/compare/1.3.1...1.4.0) 🔗 [Release Notes](https://prettier.io/blog/2017/06/03/1.4.0.html) -# 1.3.1 +### prettier 1.3.1 [diff](https://github.com/prettier/prettier/compare/1.3.0...1.3.1) - Respect template inline-ness (#1497) -# 1.3.0 +### prettier 1.3.0 [diff](https://github.com/prettier/prettier/compare/1.2.2...1.3.0) @@ -1663,19 +2190,19 @@ Lots of small fixes, mainly for TypeScript. - Break inline object first in function arguments (#1453) (#1173) - Inline template literals as arrow body (#1485) -# 1.2.2 +### prettier 1.2.2 [diff](https://github.com/prettier/prettier/compare/1.2.1...1.2.2) - Only break for conditionals (#1350) -# 1.2.1 +### prettier 1.2.1 [diff](https://github.com/prettier/prettier/compare/1.2.0...1.2.1) - Fix duplicate comments in classes (#1349) -# 1.2.0 +### prettier 1.2.0 [diff](https://github.com/prettier/prettier/compare/1.1.0...1.2.0) @@ -1707,7 +2234,7 @@ Lots of small fixes, mainly for TypeScript. - Break if () if conditional inside breaks (#1344) - Don't inline paren at right of arguments (#1345) -# 1.1.0 +### prettier 1.1.0 [diff](https://github.com/prettier/prettier/compare/1.0.0...1.1.0) @@ -1723,17 +2250,17 @@ Lots of small fixes, mainly for TypeScript. - Fixing n.comments check in printer (#1239) - [WIP] no-semi comments (#1257) -# 1.0.1 +### prettier 1.0.1 - change semi default -# 1.0.0 +### prettier 1.0.0 [diff](https://github.com/prettier/prettier/compare/0.22.0...1.0.0) 🔗 [Release Notes](https://prettier.io/blog/2017/04/13/1.0.0.html) -# 0.22.0 +### prettier 0.22.0 [diff](https://github.com/prettier/prettier/compare/0.21.0...0.22.0) @@ -1768,7 +2295,7 @@ Lots of small fixes, mainly for TypeScript. - Inline BinaryExpressions inside JSXExpression (#965) - Only allow same-line arrow-less body for explicit nodes (#966) -# 0.21.0 +### prettier 0.21.0 [diff](https://github.com/prettier/prettier/compare/0.20.0...0.21.0) @@ -1791,7 +2318,7 @@ Lots of small fixes, mainly for TypeScript. - Do not break long it calls (#842) - Fix flow union comments (#853) -# 0.20.0 +### prettier 0.20.0 [diff](https://github.com/prettier/prettier/compare/0.19.0...0.20.0) @@ -1813,7 +2340,7 @@ Lots of small fixes, mainly for TypeScript. - Update list of related projects (#833) - Allow breaking for logical expressions in member chains (#827) -# 0.19.0 +### prettier 0.19.0 [diff](https://github.com/prettier/prettier/compare/0.18.0...0.19.0) @@ -1847,7 +2374,7 @@ Lots of small fixes, mainly for TypeScript. - [RFC] Add parenthesis around && inside of || (#780) - Fix tests on node 4 -# 0.18.0 +### prettier 0.18.0 [diff](https://github.com/prettier/prettier/compare/0.17.1...0.18.0) @@ -1866,13 +2393,13 @@ Lots of small fixes, mainly for TypeScript. - Fix trailing new lines preservation (#724) - Unified Split -# 0.17.1 +### prettier 0.17.1 [diff](https://github.com/prettier/prettier/compare/0.17.0...0.17.1) - Use `readline` api to manipulate `process.stdout` output. (#687) -# 0.17.0 +### prettier 0.17.0 [diff](https://github.com/prettier/prettier/compare/0.16.0...0.17.0) @@ -1907,7 +2434,7 @@ Lots of small fixes, mainly for TypeScript. - Fix comments in return statement argument (#657) - [RFC] Introduce prettier-ignore-next (#671) -# 0.16.0 +### prettier 0.16.0 [diff](https://github.com/prettier/prettier/compare/0.15.0...0.16.0) @@ -1932,7 +2459,7 @@ Lots of small fixes, mainly for TypeScript. - Fix single indented JSX comment (#596) - Print dangling on ast on all the paths -# 0.15.0 +### prettier 0.15.0 [diff](https://github.com/prettier/prettier/compare/0.14.1...0.15.0) @@ -1953,14 +2480,14 @@ Lots of small fixes, mainly for TypeScript. - Whitelist UnaryExpression for parentless objects (#545) - Make comments inside of MemberExpression look good (#556) -# 0.14.1 +### prettier 0.14.1 [diff](https://github.com/prettier/prettier/compare/0.14.0...0.14.1) - Fix range for object newline detection (#520) - a bugfix for "Keep expanded objects expanded" (#495) -# 0.14.0 +### prettier 0.14.0 [diff](https://github.com/prettier/prettier/compare/0.13.0...0.14.0) @@ -1973,7 +2500,7 @@ Lots of small fixes, mainly for TypeScript. - Do not always put an empty lines after directives (#505) - Print numbers in a uniform way (#498) -# 0.13.0 +### prettier 0.13.0 [diff](https://github.com/prettier/prettier/compare/0.12.0...0.13.0) @@ -1983,7 +2510,7 @@ Lots of small fixes, mainly for TypeScript. - [JSX] Handle each line of text separately (#455) - Proper support for dangling comments (#492) -# 0.12.0 +### prettier 0.12.0 [diff](https://github.com/prettier/prettier/compare/0.11.0...0.12.0) @@ -2024,7 +2551,7 @@ Lots of small fixes, mainly for TypeScript. - Mention eslint-plugin-prettier in Related Projects (#490) - Stop using conditionalGroup inside of UnionTypeAnnotation (#491) -# 0.11.0 +### prettier 0.11.0 [diff](https://github.com/prettier/prettier/compare/0.0.10...0.11.0) @@ -2075,7 +2602,7 @@ Now using minor versions instead of patch versions for the releases. - Use babel-code-frame for syntax errors (#367) - Update yarn.lock -# 0.0.10 +### prettier 0.0.10 [diff](https://github.com/prettier/prettier/compare/0.0.9...0.0.10) @@ -2101,7 +2628,7 @@ Now using minor versions instead of patch versions for the releases. - Indent while test the same way as if test (#352) - Add debugging support for doc IR (#347) -# 0.0.9 +### prettier 0.0.9 [diff](https://github.com/prettier/prettier/compare/0.0.8...0.0.9) @@ -2131,7 +2658,7 @@ Now using minor versions instead of patch versions for the releases. - [JSX] Split elements on newlines and preserve whitespace (w/@yamafaktory) (#234) - Print binary and logical expressions in a nicer format (#262) -# 0.0.8 +### prettier 0.0.8 [diff](https://github.com/prettier/prettier/compare/e447971...0192d58) @@ -2162,7 +2689,7 @@ Now using minor versions instead of patch versions for the releases. - Fix parens for functions inside TaggedTemplateExpression (#259) - Preserve the way numbers were written (#257) -# 0.0.7 +### prettier 0.0.7 [diff](https://github.com/prettier/prettier/compare/7e31610...6f5df0e) @@ -2177,7 +2704,7 @@ Now using minor versions instead of patch versions for the releases. - Fix DeclareInterface (#182) - Change test to workaround babylon bug (#184) -# 0.0.6 +### prettier 0.0.6 [diff](https://github.com/prettier/prettier/compare/faed09c...3af7da5) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cb960db33f..18a36da17b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Contributing to Prettier +# Contributing to prettierX To get up and running, install the dependencies and run the tests: @@ -11,7 +11,7 @@ yarn test The tests use [Jest snapshots](https://facebook.github.io/jest/docs/en/snapshot-testing.html). You can make changes and run `jest -u` (or `yarn test -u`) to update the snapshots. Then run `git diff` to take a look at what changed. Always update the snapshots when opening a PR. -Each test directory in `tests` has a `jsfmt.spec.js` file that controls how exactly the rest of the files in the directory are used for tests. This file must contain one or more calls to the `run_spec` global function. For example, in directories with JavaScript formatting tests, `jsfmt.spec.js` generally looks like this: +Each test directory in `tests/format` has a `jsfmt.spec.js` file that controls how exactly the rest of the files in the directory are used for tests. This file must contain one or more calls to the `run_spec` global function. For example, in directories with JavaScript formatting tests, `jsfmt.spec.js` generally looks like this: ```js run_spec(__dirname, ["babel", "flow", "typescript"]); @@ -48,18 +48,18 @@ function run_spec( Parameters: - **`fixtures`**: Must be set to `__dirname` or to an object of the shape `{ dirname: __dirname, ... }`. The object may have the `snippets` property to specify an array of extra input entries in addition to the files in the current directory. For each input entry (a file or a snippet), `run_spec` configures and runs a number of tests. The main check is that for a given input the output should match the snapshot (for snippets, the expected output can also be specified directly). [Additional checks](#deeper-testing) are controlled by options and environment variables. -- **`parsers`**: A list of parser names. The tests verify that the parsers in this list produce the same output. If the list includes `typescript`, then `babel-ts` is included implicitly. If the list includes `babel`, and the current directory is inside `tests/js`, then `espree` and `meriyah` are included implicitly. -- **`options`**: In addition to Prettier's formatting option, can contain the `errors` property to specify that it's expected that the formatting shouldn't be successful and an error should be thrown for all (`errors: true`) or some combinations of input entries and parsers. +- **`parsers`**: A list of parser names. The tests verify that the parsers in this list produce the same output. If the list includes `typescript`, then `babel-ts` is included implicitly. If the list includes `babel`, and the current directory is inside `tests/format/js`, then `espree` and `meriyah` are included implicitly. +- **`options`**: In addition to Prettier's formatting options, can contain the `errors` property to specify that it's expected that the formatting shouldn't be successful and an error should be thrown for all (`errors: true`) or some combinations of input entries and parsers. The implementation of `run_spec` can be found in [`tests/config/format-test.js`](tests/config/format-test.js). -`tests/flow-repo/` contains the Flow test suite and is not supposed to be edited by hand. To update it, clone the Flow repo next to the Prettier repo and run: `node scripts/sync-flow-tests.js ../flow/tests/`. +`tests/format/flow-repo/` contains the Flow test suite and is not supposed to be edited by hand. To update it, clone the Flow repo next to the Prettier repo and run: `node scripts/sync-flow-tests.js ../flow/tests/`. ## Debugging -To debug Prettier locally, you can either debug it in Node (recommended) or the browser. +To debug prettierX locally, you can either debug it in Node (recommended) or the browser. -- The easiest way to debug it in Node is to create a local test file with some example code you want formatted and either run it in an editor like VS Code or run it directly via `./bin/prettier.js `. +- The easiest way to debug it in Node is to create a local test file with some example code you want formatted and either run it in an editor like VS Code or run it directly via `./bin/prettierx.js `. - The easiest way to debug it in the browser is to build Prettier's website locally (see [`website/README.md`](website/README.md)). ## Other @@ -70,18 +70,18 @@ After opening a PR, describe your changes in a file in the `changelog_unreleased Take a look at [`commands.md`](commands.md) and, if you know Haskell, check out [Wadler's paper](http://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf) to understand how Prettier works. -If you want to know more about Prettier's GitHub labels, see the [Issue Labels](https://github.com/prettier/prettier/wiki/Issue-Labels) page on the Wiki. +~~If you want to know more about prettier(X)'s GitHub labels, see the [Prettier Issue Labels](https://github.com/prettier/prettier/wiki/Issue-Labels) page on the Wiki.~~ # Advanced topics ## Performance -If you're contributing a performance improvement, the following Prettier CLI options can help: +If you're contributing a performance improvement, the following prettier(X) CLI options can help: - `--debug-repeat N` uses a naïve loop to repeat the formatting `N` times and measures the average run duration. It can be useful to highlight hot functions in the profiler. The measurements are printed at the debug log level, use `--loglevel debug` to see them. - `--debug-benchmark` uses [`benchmark`](https://npm.im/benchmark) module to produce statistically significant duration measurements. The measurements are printed at the debug log level, use `--loglevel debug` to see them. -For convenience, the following commands for profiling are available via `package.json` `scripts`. +~~For convenience, the following commands for profiling are available via `package.json` `scripts`.~~ _The convenience `perf:` package scripts are [currently broken](https://github.com/brodybits/prettierx/issues/554)._ _Unfortunately, [`yarn` simply appends passed arguments to commands, cannot reference them by name](https://github.com/yarnpkg/yarn/issues/5207), so we have to use inline environment variables to pass them._ @@ -91,8 +91,8 @@ _Unfortunately, [`yarn` simply appends passed arguments to commands, cannot refe In the above commands: -- `yarn && yarn build` ensures the compiler-optimized version of Prettier is built prior to launching it. Prettier's own environment checks are defaulted to production and removed during the build. The build output is cached, so a rebuild will happen only if the source code changes. -- `NODE_ENV=production` ensures Prettier and its dependencies run in production mode. +- `yarn && yarn build-extra-dist` ensures the compiler-optimized version of prettierX is built prior to launching it; prettierX's own environment checks are defaulted to production and removed during the build. The build output is cached, so a rebuild will happen only if the source code changes. +- `NODE_ENV=production` ensures prettierX and its dependencies run in production mode. - `node --inspect-brk` pauses the script execution until Inspector is connected to the Node process. - `--loglevel debug` ensures the `--debug-repeat` or `--debug-benchmark` measurements are printed to `stderr`. - `> /dev/null` ensures the formatted output is discarded. diff --git a/LICENSE b/LICENSE index 5767e34d30..71db5d4c22 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright © James Long and contributors +Copyright © Christopher J. Brody, James Long, and other contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/README.md b/README.md index 189df95a69..57320dca76 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,102 @@ +# prettierX - a less opinionated fork of Prettier + +[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE) +[![npm](https://img.shields.io/npm/v/prettierx.svg)](https://www.npmjs.com/package/prettierx) + +An unofficial fork of the Prettier code formatter, intended to provide some additional options to help improve consistency with ["Standard JS"](https://standardjs.com/) ([`feross/standard`](https://github.com/standard/standard)) and [`Flet/semistandard`](https://github.com/Flet/semistandard). This fork is an attempt to pick up where [`arijs/prettier-miscellaneous`](https://github.com/arijs/prettier-miscellaneous) left off. + +## prettierX as a Prettier plugin + +[`prettier-plugin-x`](https://www.npmjs.com/package/prettier-plugin-x) - provides the additional formatting options in a prettier plugin + +## CLI Usage + +**Quick CLI usage:** + +```sh +prettierx +``` + +## Additional prettierX options + +- `--align-object-properties` (`alignObjectProperties: true`): Align colons in multiline object literals (not applied with any of the JSON parsers). +- `--offset-ternary-expressions` (`offsetTernaryExpressions: true`): Indent and align ternary expression branches more consistently with "Standard JS" (similar to the corresponding eslint option). +- `--space-before-function-paren` (`spaceBeforeFunctionParen: true`): Put a space before function parenthesis in all declarations (similar to the corresponding eslint option). (Default is to put a space before function parenthesis for untyped anonymous functions only.) +- `--generator-star-spacing` (`generatorStarSpacing: true`): Put spaces around the star (`*`) in generator functions (before and after - similar to the corresponding eslint option). (Default is after only.) +- `--yield-star-spacing` (`yieldStarSpacing: true`): Put spaces around the star (`*`) in `yield*` expressions (before and after - similar to the corresponding eslint option). (Default is after only.) +- `--no-indent-chains` (`indentChains: false`): Disable indents at the start of chained calls. +- `--break-before-else` (`breakBeforeElse: true`): Always add a line break before else. +- --import-formatting (importFormatting: ""): Formatting of import statements, may be `oneline` to avoid conflict with VSCode "Organize Imports" feature. +- `--html-void-tags` (`htmlVoidTags: true`): Format void HTML elements as void tags. +- `--break-long-method-chains` (`breakLongMethodChains: true`): Break method chains with more than 3 method calls, like Prettier 1.x. +- `--array-bracket-spacing` (`arrayBracketSpacing: true`): Put spaces between array brackets (similar to the corresponding eslint option). Status: experimental, with limited testing. +- `--css-paren-spacing` (`cssParenSpacing: true`): Put spaces between parens in CSS, WordPress style. Status: experimental, with limited testing. +- `--computed-property-spacing` (`computedPropertySpacing: true`): Put spaces between computed property brackets (similar to the corresponding eslint option). Status: experimental, with limited testing.", +- `--space-in-parens` (`spaceInParens: true`): Print spaces in between parens, WordPress style (similar to the corresponding eslint option). Not recommended in combination with the default `arrowParens: "always"` option. Status: experimental, with limited testing. +- `--space-unary-ops` (`spaceUnaryOps: true`): Put spaces after unary operator symbols, except in the middle of `!!` (similar to the corresponding eslint option). Status: experimental, with limited testing. +- `--template-curly-spacing` (`templateCurlySpacing: true`): Put spaces between template curly brackets (similar to the corresponding eslint option). Status: experimental, with limited testing. +- `--type-angle-bracket-spacing` (`typeAngleBracketSpacing: true`): Put spaces between type angle brackets. Status: experimental, with limited testing. +- `--type-bracket-spacing` (`typeBracketSpacing: true`): Put spaces between type brackets. Status: experimental, with limited testing. +- `--no-export-curly-spacing` (`exportCurlySpacing: false`): Put or disable spaces between export curly braces. +- `--no-import-curly-spacing` (`importCurlySpacing: false`): Put or disable spaces between import curly braces. +- `--no-object-curly-spacing` (`objectCurlySpacing: false`): Disable spaces between object curly braces (similar to the corresponding eslint option). +- `--no-graphql-curly-spacing` (`graphqlCurlySpacing: false`): Disable spaces between curly braces for GraphQL. +- `--no-yaml-bracket-spacing` (`yamlBracketSpacing: false`): Disable spaces between brackets / curly braces for YAML. +- `--no-type-curly-spacing` (`typeCurlySpacing: false`): Disable spaces between type curly braces. + +(See [`docs/options.md`](docs/options.md) for more information.) + +## "Standard JS" formatting options + +The following options should be used to _format_ the code _as consistently as possible_ with ["Standard JS"](https://standardjs.com/): + +- `--arrow-parens avoid` (`arrowParens: "avoid"`) +- `--generator-star-spacing` (`generatorStarSpacing: true`) +- `--space-before-function-paren` (`spaceBeforeFunctionParen: true`) +- `--single-quote` (`singleQuote: true`) +- `--jsx-single-quote` (`jsxSingleQuote: true`) +- `--no-semi` (`semi: false`) +- `--offset-ternary-expressions` (`offsetTernaryExpressions: true`) +- `--yield-star-spacing` (`yieldStarSpacing: true`) +- `--trailing-comma none` (`trailingComma: "none"`) + +Note that this tool does **not** follow any of the other ["Standard JS"](https://standardjs.com/) rules. It is recommended to use this tool together with eslint, in some form, to archive correct formatting according to ["Standard JS"](https://standardjs.com/). + +Any known conflicts with ["Standard JS"](https://standardjs.com/) will be tracked in [open issues with the `conflict-with-standard` tag](https://github.com/brodybits/prettierx/issues?q=is%3Aissue+label%3Aconflict-with-standard+is%3Aopen). + +## some recommended options + +- `--arrow-parens avoid` (`arrowParens: "avoid"`), especially in combination with `--space-in-parens` (`spaceInParens: true`). +- `--break-long-method-chains` (`breakLongMethodChains: true`) +- `--offset-ternary-expressions` (`offsetTernaryExpressions: true`) + +## options removed + +- `--no-align-ternary-lines` - replaced with: `--offset-ternary-expressions` +- `--paren-spacing` - replaced with finer-grained options: + - `--array-bracket-spacing` + - `--css-paren-spacing` + - `--computed-property-spacing` + - `--space-in-parens` + - `--space-unary-ops` + - `--template-curly-spacing` + - `--type-angle-bracket-spacing` + - `--type-bracket-spacing` +- `no-bracket-spacing` - replaced with finer-grained options: + - `--no-export-curly-spacing` + - `--no-import-curly-spacing` + - `--no-object-curly-spacing` + - `--no-graphql-curly-spacing` + - `--no-yaml-bracket-spacing` + - `--no-type-curly-spacing` + + + + + + ### Input @@ -82,22 +199,36 @@ foo( ); ``` + ---- +## Integration with eslint + +A couple packages by [@aMarCruz (Alberto Martínez)](https://github.com/aMarCruz): + +- [`eslint-plugin-prettierx`](https://www.npmjs.com/package/eslint-plugin-prettierx) +- [`eslint-config-standardized`](https://www.npmjs.com/package/eslint-config-standardize) + + + + --- + ## Contributing diff --git a/bin/prettier.js b/bin/prettierx.js similarity index 100% rename from bin/prettier.js rename to bin/prettierx.js diff --git a/changelog_unreleased/api/10122.md b/changelog_unreleased/api/10122.md deleted file mode 100644 index 5d228bbb60..0000000000 --- a/changelog_unreleased/api/10122.md +++ /dev/null @@ -1,34 +0,0 @@ -#### Fix `lineSuffixBoundary` IR command (#10122 by @thorn0) - -There was a bug in the implementation of the [`lineSuffixBoundary`][lsb] command that significantly limited its usefulness: the printer algorithm didn't correctly consider it a potential line break. Now that the bug has been fixed, we urge plugin authors to give this command another try and see if it can help them simplify printing of trailing comments. - -[lsb]: https://github.com/prettier/prettier/blob/main/commands.md#linesuffixboundary - - -```jsx -// Input -group([ - "let foo = [", - indent([ - softline, - [lineSuffixBoundary, "item1,"], - line, - [lineSuffixBoundary, "item2,", lineSuffix(" // comment")], - line, - [lineSuffixBoundary, "item3"], - ]), - softline, - "];", -]) - -// Prettier stable -let foo = [item1, item2, // comment - item3]; - -// Prettier main -let foo = [ - item1, - item2, // comment - item3 -]; -``` diff --git a/changelog_unreleased/api/10221.md b/changelog_unreleased/api/10221.md deleted file mode 100644 index 5e4fecb186..0000000000 --- a/changelog_unreleased/api/10221.md +++ /dev/null @@ -1,3 +0,0 @@ -#### Add `indentIfBreak` IR command (#10221 by @thorn) - -`indentIfBreak(doc, { groupId })` is an optimized version of `ifBreak(indent(doc), doc, { groupId })`. diff --git a/changelog_unreleased/api/10557.md b/changelog_unreleased/api/10557.md deleted file mode 100644 index 2716b3e9f2..0000000000 --- a/changelog_unreleased/api/10557.md +++ /dev/null @@ -1,37 +0,0 @@ -#### Simplified `print` callback (#10557 by @fisker) - -The third argument of the `print` method of plugin printers (the `print` callback) has been updated. Its first argument can be a string or an array of strings now. - -To print the current node, call `print` without arguments: - -```diff - function print(path, options, print) { - const parts = []; - path.each((childPath) => { -- parts.push(print(childPath)); -+ parts.push(print()); - }, "children"); - return parts; - } -``` - -To print a property of the current node, use `"property"` or `["property"]`: - -```diff - function print(path, options, print) { -- return path.call(print, "property"); -+ return print("property"); - } -``` - -To print a sub-property of the current node, use `["property1", "property2"]`: - -```diff - function print(path, options, print) { - // print `node.child.child` -- return path.call(print, "child", "child"); -+ return print(["child", "child"]); - } -``` - -See also an example in the [docs](https://prettier.io/docs/en/plugins.html#print). diff --git a/changelog_unreleased/api/8105.md b/changelog_unreleased/api/8105.md deleted file mode 100644 index 6cb237df7e..0000000000 --- a/changelog_unreleased/api/8105.md +++ /dev/null @@ -1,3 +0,0 @@ -#### Treat `.prettierrc` as YAML when formatting it (#8105 by @fisker) - -The `.prettierrc` file can be written in either JSON or YAML. Previously, when Prettier formatted it, the parser was inferred to be `json`, which lead to a `SyntaxError` thrown if the content was YAML. Now it’s treated as a YAML file. However, if it's JSON, it will be formatted as JSON (not as JSON-like YAML). diff --git a/changelog_unreleased/api/9733.md b/changelog_unreleased/api/9733.md deleted file mode 100644 index 4def4af71c..0000000000 --- a/changelog_unreleased/api/9733.md +++ /dev/null @@ -1,15 +0,0 @@ -#### Use arrays instead of `concat` (#9733 by @fisker, @thorn0) - -To simplify the code of AST printers, the data structure for the concatenation command has been changed from `{ type: 'concat', parts: Doc[] }` to `Doc[]`. The old format is deprecated, but for compatibility, the doc printer still supports it, and `doc.builders.concat` (as well as some other builder functions) will keep using it until the next major version of Prettier. - -If you're a plugin author, this change should only concern you if your plugin introspects or modifies composed docs. If it happens to be the case, please make your plugin compatible with future versions of Prettier by tweaking the introspecting code to support the new format. There also is an off-chance where this change can break things, namely if a plugin calls another plugin to [print an embedded language](https://prettier.io/docs/en/plugins.html#optional-embed) and then introspects the returned doc. There seems to be no reason for plugins to do that though. - -To replace `concat(…)` calls in your plugins, you can try auto-fix by this ESLint rule [`prettier-doc/no-concat`](https://github.com/fisker/eslint-plugin-prettier-doc#no-concat). - -```jsx -// Prettier stable -myDoc = group(concat(["foo", line, "bar"])); - -// Prettier main -myDoc = group(["foo", line, "bar"]); -``` diff --git a/changelog_unreleased/cli/10058.md b/changelog_unreleased/cli/10058.md deleted file mode 100644 index 05dd3b6a1d..0000000000 --- a/changelog_unreleased/cli/10058.md +++ /dev/null @@ -1,16 +0,0 @@ -#### Add CLI option to prevent errors on unmatched pattern (#10058 by @daronmcintosh) - -The Prettier CLI will no longer display an error when no files match the glob pattern passed as input. - -```sh -# Prettier stable -$ npx prettier --check "prettier/docs/*.yaml" -Checking formatting... -[error] No files matching the pattern were found: "prettier/docs/*.yaml". -All matched files use Prettier code style! - -# Prettier main -$ npx prettier --check --no-error-on-unmatched-pattern "prettier/docs/*.yaml" -Checking formatting... -All matched files use Prettier code style! -``` diff --git a/changelog_unreleased/cli/10124.md b/changelog_unreleased/cli/10124.md deleted file mode 100644 index 0c3f204e68..0000000000 --- a/changelog_unreleased/cli/10124.md +++ /dev/null @@ -1,3 +0,0 @@ -#### Add CLI flag for debugging comment attachment issues (#10124 by @thorn0) - -A new `--debug-print-comments` CLI flag and corresponding functionality for the Playground. diff --git a/changelog_unreleased/cli/10169.md b/changelog_unreleased/cli/10169.md deleted file mode 100644 index 7a0b6249a0..0000000000 --- a/changelog_unreleased/cli/10169.md +++ /dev/null @@ -1,3 +0,0 @@ -#### Round-trippable `--debug-print-doc` (#10169, #10177 by @thorn0) - -The idea is to make the output of `--debug-print-doc` closer to actual code for generating docs (Prettier's intermediate representation). Ideally, it should be possible for it to work without modification after copy-pasting into a JS file. That ideal hasn't probably been reached by this PR, but it's pretty close. This is going to make `--debug-print-doc` and the corresponding part of the Playground a bit more useful. diff --git a/changelog_unreleased/cli/10208.md b/changelog_unreleased/cli/10208.md deleted file mode 100644 index c8dac16928..0000000000 --- a/changelog_unreleased/cli/10208.md +++ /dev/null @@ -1,11 +0,0 @@ -#### Print an error message when `--find-config-path` can't find config file (#10208 by @fisker) - -```console -# Prettier stable -$ prettier --find-config-path /prettier.js -# Silently failed - -# Prettier main -$ prettier --find-config-path /prettier.js -[error] Can not find configure file for "/prettier.js" -``` diff --git a/changelog_unreleased/cli/10217.md b/changelog_unreleased/cli/10217.md deleted file mode 100644 index e260bfc722..0000000000 --- a/changelog_unreleased/cli/10217.md +++ /dev/null @@ -1,17 +0,0 @@ -#### Clear printed long filenames of formatting file (#10217 by @fisker) - - -```console -# Prettier stable -$ prettier tests/flow-repo/config_module_system_node_resolve_dirname --check -Checking formatting... -tests\flow-repo\config_module_system_node_resolve_dirname\custom_resolve_dir\tes -tests\flow-repo\config_module_system_node_resolve_dirname\custom_resolve_dir\tes -tests\flow-repo\config_module_system_node_resolve_dirname\subdir\custom_resolve_ -All matched files use Prettier code style! - -# Prettier main -$ prettier tests/flow-repo/config_module_system_node_resolve_dirname --check -Checking formatting... -All matched files use Prettier code style! -``` diff --git a/changelog_unreleased/cli/10256.md b/changelog_unreleased/cli/10256.md deleted file mode 100644 index 1ac6e1126e..0000000000 --- a/changelog_unreleased/cli/10256.md +++ /dev/null @@ -1,14 +0,0 @@ -#### Don't skip file paths containing special words like `constructor` (#10256 by @ashlkv) - -Directories whose names happened to coincide with the properties of `Object.prototype` were ignored by Prettier CLI because of a classic bug (introduced in Prettier 2.0.0) with object properties not being checked for being own. - - -```sh -# Prettier stable -$ prettier 'js/constructor/*.js' --write -[error] No matching files. Patterns: js/constructor/*.js - -# Prettier main -prettier 'js/constructor/*.js' --write -js/constructor/test.js 42ms -``` diff --git a/changelog_unreleased/css/10773.md b/changelog_unreleased/css/10773.md deleted file mode 100644 index f08ed1ed79..0000000000 --- a/changelog_unreleased/css/10773.md +++ /dev/null @@ -1,34 +0,0 @@ -#### Exclude `@keyframes` params from being parsed as a Less variable (#10773 by @tmazeika) - - -```css -/* Input */ -@keyframes :global(spin) { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} - -/* Prettier stable */ -@keyframes: global(spin){ - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -}; - -/* Prettier main */ -@keyframes :global(spin) { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} -``` diff --git a/changelog_unreleased/css/9966.md b/changelog_unreleased/css/9966.md deleted file mode 100644 index 9fc31c4ecd..0000000000 --- a/changelog_unreleased/css/9966.md +++ /dev/null @@ -1,15 +0,0 @@ -#### Fix absolute path in custom CSS `-custom-url()` calls (#9966 by @vjeux) - -The CSS parser is parsing this as `["division", "absolute/path"]` instead of a single `"/absolute/path"` token unless you are in a `url()` call. Because we put space after division, it results in an incorrect path. The fix was to avoid printing a space if a division is the first token of a call, which hopefully should be safe. - - -```css -/* Input */ --custom-url(/absolute/path) - -/* Prettier stable */ --custom-url(/ absolute/path) - -/* Prettier main */ --custom-url(/absolute/path) -``` diff --git a/changelog_unreleased/flow/10397.md b/changelog_unreleased/flow/10397.md deleted file mode 100644 index 3df2ddcc35..0000000000 --- a/changelog_unreleased/flow/10397.md +++ /dev/null @@ -1,15 +0,0 @@ -#### Support `this` type annotation in functions via `babel-flow` (#10397 by @sosukesuzuki) - -`this` type annotation is supported since [Babel 7.13](https://babeljs.io/blog/2021/02/22/7.13.0#new-flow-features-12193httpsgithubcombabelbabelpull12193-12234httpsgithubcombabelbabelpull12234). - -```js -// Input -var foo: (this: boolean) => void; - -// Prettier stable -SyntaxError: Unexpected token, expected ")" (1:15) - -// Prettier main -var foo: (this: boolean) => void; - -``` diff --git a/changelog_unreleased/flow/10505.md b/changelog_unreleased/flow/10505.md deleted file mode 100644 index 3e1bd25d6c..0000000000 --- a/changelog_unreleased/flow/10505.md +++ /dev/null @@ -1,15 +0,0 @@ -#### Fix range formatting issues (#10505 by @thorn0) - -Prettier had trouble formatting some ranges in function declarations. `SyntaxError` was thrown. Prettier main formats these cases without errors. Examples of problematic ranges are shown below: - - -```jsx -declare export function graphql> - // ^^^^^ range 1 - (query: GQLDocument, config?: Config>): - (Component: Component) => React$ComponentType<$Diff, { - data: Object|void, - // ^^^^ range 2 - mutate: Function|void - }>> -``` diff --git a/changelog_unreleased/flow/10594.md b/changelog_unreleased/flow/10594.md deleted file mode 100644 index 83620ee1f7..0000000000 --- a/changelog_unreleased/flow/10594.md +++ /dev/null @@ -1,13 +0,0 @@ -#### Support for Flow's indexed access type (#10594 by @gkz) - - -```js -// Input -const x: Obj['foo'] = 1; - -// Prettier stable -// Error: unsupported node type "IndexedAccessType" - -// Prettier main -const x: Obj["foo"] = 1; -``` diff --git a/changelog_unreleased/flow/10788.md b/changelog_unreleased/flow/10788.md deleted file mode 100644 index 8972e86ca6..0000000000 --- a/changelog_unreleased/flow/10788.md +++ /dev/null @@ -1,13 +0,0 @@ -#### Support for Flow's optional indexed access type (#10788 by @gkz) - - -```js -// Input -type T = Obj?.['foo']; - -// Prettier stable -// Error: unsupported node type "OptionalIndexedAccessType" - -// Prettier main -type T = Obj?.['foo']; -``` diff --git a/changelog_unreleased/flow/9767.md b/changelog_unreleased/flow/9767.md deleted file mode 100644 index 72dcbc0ac5..0000000000 --- a/changelog_unreleased/flow/9767.md +++ /dev/null @@ -1,15 +0,0 @@ -#### Fix missing semicolon in `declare export * from …` (#9767 by @fisker) - - - - -```jsx -// Input -declare export * from "ES6_ExportAllFrom_Source2"; - -// Prettier stable -declare export * from "ES6_ExportAllFrom_Source2" - -// Prettier main -declare export * from "ES6_ExportAllFrom_Source2"; -``` diff --git a/changelog_unreleased/graphql/10689.md b/changelog_unreleased/graphql/10689.md deleted file mode 100644 index 3e0d7f7e91..0000000000 --- a/changelog_unreleased/graphql/10689.md +++ /dev/null @@ -1,19 +0,0 @@ -#### Fix missing space after keyword in anonymous operations (#10689 by @patriscus) - - -```graphql -# Input -query ($unnamed: String) { - id -} - -# Prettier stable -query($unnamed: String) { - id -} - -# Prettier main -query ($unnamed: String) { - id -} -``` diff --git a/changelog_unreleased/handlebars/10145.md b/changelog_unreleased/handlebars/10145.md deleted file mode 100644 index 851eaaaae6..0000000000 --- a/changelog_unreleased/handlebars/10145.md +++ /dev/null @@ -1,25 +0,0 @@ -#### Fix formatting of attributes (#10145 by @thorn0) - -- fix escaping of `{{` in attributes and text -- fix the choice between `'` and `"` for attributes with interpolations -- fix the bug with `[object Object]` printed in the `class` attribute -- implement simple formatting for the `class` attribute, like Prettier formatted it in HTML before v2.3.0 - - -```hbs -{{!-- Input --}} -
-
-
- -{{!-- Prettier stable --}} -
-
-
- -{{!-- Prettier main --}} -
-
-
-``` diff --git a/changelog_unreleased/handlebars/10179.md b/changelog_unreleased/handlebars/10179.md deleted file mode 100644 index ad2fb046b4..0000000000 --- a/changelog_unreleased/handlebars/10179.md +++ /dev/null @@ -1,20 +0,0 @@ -#### Split text content on multiple lines (#10179 by @dcyriller) - - -```handlebars -{{!-- Input --}} -
- A long enough string to trigger a line break that would prevent wrapping more and more. -
- -{{!-- Prettier stable --}} -
- A long enough string to trigger a line break that would prevent wrapping more and more. -
- -{{!-- Prettier main --}} -
- A long enough string to trigger a line break that would prevent wrapping more - and more. -
-``` diff --git a/changelog_unreleased/handlebars/10290.md b/changelog_unreleased/handlebars/10290.md deleted file mode 100644 index cf7ea6442b..0000000000 --- a/changelog_unreleased/handlebars/10290.md +++ /dev/null @@ -1,23 +0,0 @@ -#### [HIGHLIGHT] Move Handlebars support out of alpha to release (#10290 by @dcyriller & @thorn0) - -This started in 2017. Handlebars support has been in Prettier for a while, but it wasn’t released officially as it wasn’t really ready. Its status went from “alpha” to “experimental” to “beta” and then, if you checked older release notes, you can see that after “beta” somehow it was “alpha” again… - -Well, anyway, it finally is happening: Prettier can now officially format HTML templates with Handlebars! 🎉 - -It uses [Glimmer], [Ember]’s Handlebars parser, so it should be compliant with the HTML spec thanks to the Ember team. - -The [`--html-whitespace-sensitivity`][hws-option] option is supported and defaults to `strict`, which means that Prettier will always respect the presence or absence of whitespace around tags and consider it unsafe to add whitespace where there were none and vice versa as this can affect how the document is rendered in the browser. The `css` value is not yet supported (treated as `strict` for now). - -The feature is called “Ember / Handlebars” and not just “Handlebars” because Glimmer doesn’t support some syntax and use cases of Handlebars. This is mostly due to the fact that [Handlebars], being a template engine (a preprocessor), doesn’t care about the underlying syntax of the content it processes whereas Glimmer parses two syntaxes – HTML and Handlebars – at the same time and combines the result into a single tree, which Prettier can print. This means Prettier won’t format Handlebars files that can’t be parsed into such a tree, either because the underlying syntax isn’t HTML or because template directives and tags overlap in a way that can’t be represented in a tree (e.g., `{{#if foo}}
{{/if}`). Even with these restrictions, the formatter still seems to be useful enough to non-Ember Handlebars users. As for the syntax unsupported by Ember, there is a good chance to see support for it in future versions of Prettier as Glimmer uses a full-fledged Handlebars parser under the hood. - -Files with the extensions `.hbs` and `.handlebars` are recognized as Handlebars by default. For other extensions, the [`--parser`](parser-option) option with the value `glimmer` has to be specified – for example, using command line or, better yet, [configuration overrides]. - -See the formatter in action on the [playground][playground-glimmer]! - -[glimmer]: https://www.npmjs.com/package/@glimmer/syntax -[ember]: https://emberjs.com -[hws-option]: https://prettier.io/docs/en/options.html#html-whitespace-sensitivity -[handlebars]: https://handlebarsjs.com/ -[parser-option]: https://prettier.io/docs/en/options.html#parser -[configuration overrides]: https://prettier.io/docs/en/configuration.html#configuration-overrides -[playground-glimmer]: https://prettier.io/playground/#N4Igxg9gdgLgprEAuEACVAeAJgSwG7qFgA2AhgM7kC8AOiAjAE4CedhqAfDVOhgBYBGDsGDoYOGMTjsAvjIwB6QVx6ZcBdCQrU6AIwhZWIFe1OERhfYbOE53Reo6YFjkABoQEAA7jo5ZKCkjIwQAO4ACkEI-iikxKGkzP4euoykYADWcDAAyl7pOFAA5shMAK5wHnAAtrpwWFj1ADKkxWWkRXAAYhCM1aQw4sXIIKRlMBDuIHww1cQA6nwScOT5YHA50RL4Eswj5Ew4YDBTheRwjDDhaUX9yABmceceAFbkAB4AQmmZ2Tmk1TgTUKcAeT0qIDe7xyhSKUgAimUIPAwcRniB8oxzowRnCcNVATiPF5GIUYPMcFgYHxkAAOAAMxJC53maS8IxJKwueFBHgAjkj4NdvDFRuQALRQOD1epTRhwAU4eXXDp3JCPNEQ87VHClRgVDzkWEIwWg9XgjwwUi6ClUmlIABMlrSOGIsIAwhACaQRisAKxTMrnAAq1piGvReAqAEkoI1YDkwKSfABBOM5GDMKSo85yIA diff --git a/changelog_unreleased/handlebars/10550.md b/changelog_unreleased/handlebars/10550.md deleted file mode 100644 index 1d334f225f..0000000000 --- a/changelog_unreleased/handlebars/10550.md +++ /dev/null @@ -1,13 +0,0 @@ -#### Preserve numeric character references (#10550 by @rwjblue and @thorn0) - - -```hbs -{{! Input }} - - -{{! Prettier stable }} - - -{{! Prettier main }} - -``` diff --git a/changelog_unreleased/handlebars/10586.md b/changelog_unreleased/handlebars/10586.md deleted file mode 100644 index 90ecd1c181..0000000000 --- a/changelog_unreleased/handlebars/10586.md +++ /dev/null @@ -1,40 +0,0 @@ -#### Do not break opening mustache and path (#10586 by @dcyriller) - - -```handlebars -{{!-- Input --}} - - - -{{!-- Prettier stable --}} - - - -{{!-- Prettier main --}} - - -``` diff --git a/changelog_unreleased/handlebars/10958.md b/changelog_unreleased/handlebars/10958.md new file mode 100644 index 0000000000..1890c5a777 --- /dev/null +++ b/changelog_unreleased/handlebars/10958.md @@ -0,0 +1,44 @@ +#### Preserve attributes order for element node (#10958 by @dcyriller) + + +```handlebars +{{!-- Input --}} + +{{!-- Prettier stable --}} + +{{!-- Prettier main --}} + +``` diff --git a/changelog_unreleased/handlebars/9082.md b/changelog_unreleased/handlebars/9082.md deleted file mode 100644 index 00adb39d9b..0000000000 --- a/changelog_unreleased/handlebars/9082.md +++ /dev/null @@ -1,19 +0,0 @@ -#### Preserve tilde comments (#9082 by @kangax, @fisker) - - -```hbs -{{!-- Input --}} -{{~! Comment }} -{{! Comment ~}} -{{~! Comment ~}} - -{{!-- Prettier stable --}} -{{! Comment }} -{{! Comment }} -{{! Comment }} - -{{!-- Prettier main --}} -{{~! Comment }} -{{! Comment ~}} -{{~! Comment ~}} -``` diff --git a/changelog_unreleased/handlebars/9885.md b/changelog_unreleased/handlebars/9885.md deleted file mode 100644 index 2fe1c4e9bc..0000000000 --- a/changelog_unreleased/handlebars/9885.md +++ /dev/null @@ -1,45 +0,0 @@ -#### Add a whitespace sensitive mode (#9885 by @dcyriller) - -```sh ---html-whitespace-sensitivity strict -``` - - -```hbs -{{!-- Input --}} -123 {{mustache}} - -123 {{mustache}} -123 {{mustache}} - - -123 {{mustache}} - - -{{!-- Prettier stable --}} - - 123 {{mustache}} - - - 123 {{mustache}} - - - 123 {{mustache}} - - - 123 {{mustache}} - - -{{!-- Prettier main --}} -123 {{mustache}} - - 123 - {{mustache}} -123 - {{mustache}} - - - 123 - {{mustache}} - -``` diff --git a/changelog_unreleased/handlebars/9978.md b/changelog_unreleased/handlebars/9978.md deleted file mode 100644 index 74b1083948..0000000000 --- a/changelog_unreleased/handlebars/9978.md +++ /dev/null @@ -1,44 +0,0 @@ -#### Print final `blockParam` on its own line (#9978 by @dcyriller) - - -```hbs -{{!-- Input --}} - -{{#block param hashKey=hashValue hashKey=hashValue hashKey=hashValue as |blockParam|}} - Hello -{{/block}} - -{{!-- Prettier stable --}} - -{{#block - param - hashKey=hashValue - hashKey=hashValue - hashKey=hashValue as |blockParam| -}} - Hello -{{/block}} - -{{!-- Prettier main --}} - -{{#block - param - hashKey=hashValue - hashKey=hashValue - hashKey=hashValue - as |blockParam| -}} - Hello -{{/block}} -``` diff --git a/changelog_unreleased/html/10906.md b/changelog_unreleased/html/10906.md new file mode 100644 index 0000000000..54d664af9c --- /dev/null +++ b/changelog_unreleased/html/10906.md @@ -0,0 +1,29 @@ +#### Allow `:` as class prefix delimiter (#10906 by @tkalmar) + + +```html + +
+ + +
+ + +
+``` diff --git a/changelog_unreleased/html/7865.md b/changelog_unreleased/html/7865.md deleted file mode 100644 index 9587027eb2..0000000000 --- a/changelog_unreleased/html/7865.md +++ /dev/null @@ -1,22 +0,0 @@ -#### [IMPROVEMENT] Prefix-based multiline formatting for the `class` attribute (#7865 by @thorn0) - -Formatting of HTML class names will now keep classes on one line until the line length limit is reached; at that point, consecutive classes with the same prefix will be grouped together on each line. For layout frameworks such as Bootstrap and Tailwind CSS, which add many classes to an element, this is important for readability and maintainability vs. the previous behavior (keeping all classes on one line) or e.g. putting each class on its own line. - - -```html - -
- - -
-``` diff --git a/changelog_unreleased/javascript/10085.md b/changelog_unreleased/javascript/10085.md deleted file mode 100644 index 187c15a343..0000000000 --- a/changelog_unreleased/javascript/10085.md +++ /dev/null @@ -1,19 +0,0 @@ -#### [IMPROVEMENT:2] Improve visual separation between header and body in classes with multiline headers (#10085 by @sosukesuzuki) - - -```ts -// Prettier stable -class loooooooooooooooooooong - extends looooooooooooooooooong - implements loooooooooooooooooooong { - property: string; -} - -// Prettier main -class loooooooooooooooooooong - extends looooooooooooooooooong - implements loooooooooooooooooooong -{ - property: string; -} -``` diff --git a/changelog_unreleased/javascript/10106.md b/changelog_unreleased/javascript/10106.md deleted file mode 100644 index c3510be6fd..0000000000 --- a/changelog_unreleased/javascript/10106.md +++ /dev/null @@ -1,43 +0,0 @@ -#### [IMPROVEMENT:3] Concise formatting of number-only arrays (#10106, #10160 by @thorn0) - -While in general, Prettier avoids this kind of formatting because it's not diff-friendly, in this special case we decided that the benefits outweigh the risks. - -If at least one element has a trailing single-line (`// ...`) comment on the same line, the concise formatting isn't applied. On the other hand, single-line comments placed on separate lines don't have such an effect and – as well as empty lines – can be used for logical grouping. - - -```jsx -// Input -const lazyCatererNumbers = [1, 2, 4, 7, 11, 16, 22, 29, 37, 46, - -// n > 10 -56, 67, 79, 92, 106, 121, 137, 154, 172, 191, 211, 232, 254, 277, 301, 326, 352, 379, 407, 436, 466, -497, 529, 562, 596, 631, 667, 704, 742, 781, -// n > 40 -821, 862, 904, 947, 991, 1036, 1082, 1129, 1177, 1226, 1276, 1327, 1379]; - -// Prettier stable -const lazyCatererNumbers = [ - 1, - 2, - 4, - 7, - 11, - 16, - 22, - 29, - 37, - // ... ✂ 46 lines ✂ ... - 1379, -]; - -// Prettier main -const lazyCatererNumbers = [ - 1, 2, 4, 7, 11, 16, 22, 29, 37, 46, - - // n > 10 - 56, 67, 79, 92, 106, 121, 137, 154, 172, 191, 211, 232, 254, 277, 301, 326, - 352, 379, 407, 436, 466, 497, 529, 562, 596, 631, 667, 704, 742, 781, - // n > 40 - 821, 862, 904, 947, 991, 1036, 1082, 1129, 1177, 1226, 1276, 1327, 1379, -]; -``` diff --git a/changelog_unreleased/javascript/10187.md b/changelog_unreleased/javascript/10187.md deleted file mode 100644 index ba043e458b..0000000000 --- a/changelog_unreleased/javascript/10187.md +++ /dev/null @@ -1,51 +0,0 @@ -#### [IMPROVEMENT:6] Consistent indentation for conditional operators (#10187, #10266 by @sosukesuzuki) - - -```ts -// Prettier stable -const dotNotationMemberExpression = (callNode.parent?.type === -AST_NODE_TYPES.ChainExpression - ? callNode.parent.parent - : callNode.parent -).TSESTree.BinaryExpression; - -const computedMemberExpression = (callNode.parent?.type === -AST_NODE_TYPES.ChainExpression - ? callNode.parent.parent - : callNode.parent)[TSESTree.BinaryExpression]; - -const callExpressionCallee = (callNode.parent?.type === - AST_NODE_TYPES.ChainExpression - ? callNode.parent.parent - : callNode.parent)(TSESTree.BinaryExpression); - -const typeScriptAsExpression = (callNode.parent?.type === -AST_NODE_TYPES.ChainExpression - ? callNode.parent.parent - : callNode.parent) as TSESTree.BinaryExpression; - -// Prettier main -const dotNotationMemberExpression = ( - callNode.parent?.type === AST_NODE_TYPES.ChainExpression - ? callNode.parent.parent - : callNode.parent -).TSESTree.BinaryExpression; - -const computedMemberExpression = ( - callNode.parent?.type === AST_NODE_TYPES.ChainExpression - ? callNode.parent.parent - : callNode.parent -)[TSESTree.BinaryExpression]; - -const callExpressionCallee = ( - callNode.parent?.type === AST_NODE_TYPES.ChainExpression - ? callNode.parent.parent - : callNode.parent -)(TSESTree.BinaryExpression); - -const typeScriptAsExpression = ( - callNode.parent?.type === AST_NODE_TYPES.ChainExpression - ? callNode.parent.parent - : callNode.parent -) as TSESTree.BinaryExpression; -``` diff --git a/changelog_unreleased/javascript/10222.md b/changelog_unreleased/javascript/10222.md deleted file mode 100644 index ba79129be1..0000000000 --- a/changelog_unreleased/javascript/10222.md +++ /dev/null @@ -1,41 +0,0 @@ -#### [HIGHLIGHT] Format assignments more consistently (#10222, #10643, #10672 by @thorn0; #10158 by @sosukesuzuki) - -Previously, Prettier had a lot of trouble with figuring out how to break lines in assignments. E.g., long right-hand sides often stayed unbroken. Not anymore. - - -```ts -// Prettier stable -aParticularlyLongAndObnoxiousNameForIllustrativePurposes = anotherVeryLongNameForIllustrativePurposes; - -aParticularlyLongAndObnoxiousNameForIllustrativePurposes = "a very long string for illustrative purposes" - .length; - -someReallyLongThingStoredInAMapWithAReallyBigName[ - pageletID -] = _someVariableThatWeAreCheckingForFalsiness - ? Date.now() - _someVariableThatWeAreCheckingForFalsiness - : 0; - -class x { - private readonly rawConfigFromFile$: BehaviorSubject = new BehaviorSubject( - notRead - ); -} - -// Prettier main -aParticularlyLongAndObnoxiousNameForIllustrativePurposes = - anotherVeryLongNameForIllustrativePurposes; - -aParticularlyLongAndObnoxiousNameForIllustrativePurposes = - "a very long string for illustrative purposes".length; - -someReallyLongThingStoredInAMapWithAReallyBigName[pageletID] = - _someVariableThatWeAreCheckingForFalsiness - ? Date.now() - _someVariableThatWeAreCheckingForFalsiness - : 0; - -class x { - private readonly rawConfigFromFile$: BehaviorSubject = - new BehaviorSubject(notRead); -} -``` diff --git a/changelog_unreleased/javascript/10238.md b/changelog_unreleased/javascript/10238.md deleted file mode 100644 index c229c97b48..0000000000 --- a/changelog_unreleased/javascript/10238.md +++ /dev/null @@ -1,15 +0,0 @@ -#### [IMPROVEMENT:1] Improve formatting for React Hooks calls (#10238 by @sosukesuzuki) - - -```js -// Prettier stable -const { firstName, lastName } = useMemo(() => parseFullName(fullName), [ - fullName, -]); - -// Prettier main -const { firstName, lastName } = useMemo( - () => parseFullName(fullName), - [fullName] -); -``` diff --git a/changelog_unreleased/javascript/10278.md b/changelog_unreleased/javascript/10278.md deleted file mode 100644 index c6e3505c6a..0000000000 --- a/changelog_unreleased/javascript/10278.md +++ /dev/null @@ -1,15 +0,0 @@ -#### Fix error thrown on expressions like `a(b => c => function (){})` (#10278 by @thorn0) - -Regression from v2.2.0. - - -```jsx -// Input -a(b => c => function (){}) - -// Prettier stable -TypeError: Cannot read property 'length' of undefined - -// Prettier main -a((b) => (c) => function () {}); -``` diff --git a/changelog_unreleased/javascript/10296.md b/changelog_unreleased/javascript/10296.md deleted file mode 100644 index d3405b77c0..0000000000 --- a/changelog_unreleased/javascript/10296.md +++ /dev/null @@ -1,25 +0,0 @@ -#### Improve formatting for inline decorators (#10296 by @fisker) - - -```jsx -// Input -class Foo { - @decorator([]) bar() {} - @decorator( - [] - ) baz() {} -} - -// Prettier stable -class Foo { - @decorator([]) bar() {} - @decorator([]) - baz() {} -} - -// Prettier main -class Foo { - @decorator([]) bar() {} - @decorator([]) baz() {} -} -``` diff --git a/changelog_unreleased/javascript/10334.md b/changelog_unreleased/javascript/10334.md deleted file mode 100644 index 8d41c6fe84..0000000000 --- a/changelog_unreleased/javascript/10334.md +++ /dev/null @@ -1,22 +0,0 @@ -#### Fix ASI protection for private fields (#10334 by @thorn0) - - -```jsx -// Input -class C { - #field = 'value'; - ["method"]() {} -} - -// Prettier stable (with --no-semi) -class C { - #field = "value" - ["method"]() {} -} - -// Prettier main (with --no-semi) -class C { - #field = "value"; - ["method"]() {} -} -``` diff --git a/changelog_unreleased/javascript/10335.md b/changelog_unreleased/javascript/10335.md deleted file mode 100644 index 0a0a09c115..0000000000 --- a/changelog_unreleased/javascript/10335.md +++ /dev/null @@ -1,21 +0,0 @@ -#### [HIGHLIGHT] Prevent wrapping object properties with short keys (#10335 by @thorn0) - -Line breaks after short property names in object literals often look unnatural. Even when such a line break yields a line length benefit of 1 or 2 characters, it rarely looks justified. Prettier main avoids line breaks after property names shorter than `tabWidth + 3` – for example, 5 characters in the default configuration, or 7 characters with `tabWidth: 4`. This heuristic may be revised in future versions. - - -```js -// Prettier stable -const importantLink = { - url: - "https://prettier.io/docs/en/rationale.html#what-prettier-is-concerned-about", - gitHubUrl: - "https://github.com/prettier/prettier/blob/main/docs/rationale.md#what-prettier-is-concerned-about", -}; - -// Prettier main -const importantLink = { - url: "https://prettier.io/docs/en/rationale.html#what-prettier-is-concerned-about", - gitHubUrl: - "https://github.com/prettier/prettier/blob/main/docs/rationale.md#what-prettier-is-concerned-about", -}; -``` diff --git a/changelog_unreleased/javascript/10342.md b/changelog_unreleased/javascript/10342.md deleted file mode 100644 index 572d656514..0000000000 --- a/changelog_unreleased/javascript/10342.md +++ /dev/null @@ -1,34 +0,0 @@ -#### [IMPROVEMENT:4] Improve formatting for nested await expressions in heads of member and call expressions (#10342 by @thorn0) - -Even though Prettier tries to be helpful here, please don't write code like this. Have mercy upon your teammates and use intermediate variables. - - -```jsx -// Input -const getAccountCount = async () => - (await - (await ( - await focusOnSection(BOOKMARKED_PROJECTS_SECTION_NAME) - ).findItem("My bookmarks")).getChildren() - ).length - -// Prettier stable -const getAccountCount = async () => - ( - await ( - await (await focusOnSection(BOOKMARKED_PROJECTS_SECTION_NAME)).findItem( - "My bookmarks" - ) - ).getChildren() - ).length; - -// Prettier main -const getAccountCount = async () => - ( - await ( - await ( - await focusOnSection(BOOKMARKED_PROJECTS_SECTION_NAME) - ).findItem("My bookmarks") - ).getChildren() - ).length; -``` diff --git a/changelog_unreleased/javascript/10417.md b/changelog_unreleased/javascript/10417.md deleted file mode 100644 index ec0625f114..0000000000 --- a/changelog_unreleased/javascript/10417.md +++ /dev/null @@ -1,17 +0,0 @@ -#### Support Module Blocks proposal (#10417 by @sosukesuzuki, @thorn0) - -Support formatting for [Module Blocks Stage 2 proposal](https://github.com/tc39/proposal-js-module-blocks). - - -```js -// Input -module { export let foo = "foo"; }; - -// Prettier stable -SyntaxError: Unexpected token, expected ";" - -// Prettier main -module { - export let foo = "foo"; -}; -``` diff --git a/changelog_unreleased/javascript/10446.md b/changelog_unreleased/javascript/10446.md deleted file mode 100644 index bbd5a88068..0000000000 --- a/changelog_unreleased/javascript/10446.md +++ /dev/null @@ -1,19 +0,0 @@ -#### Fix missing parentheses for `yield` in a pipeline (#10446 by @fisker) - - -```jsx -// Input -function* f() { - return x |> (yield #); -} - -// Prettier stable -function* f() { - return x |> yield #; -} - -// Prettier main -function* f() { - return x |> (yield #); -} -``` diff --git a/changelog_unreleased/javascript/10495.md b/changelog_unreleased/javascript/10495.md deleted file mode 100644 index 2cb8ec8282..0000000000 --- a/changelog_unreleased/javascript/10495.md +++ /dev/null @@ -1,31 +0,0 @@ -#### Make Babel’s error recovery more selective (#10495 by @fisker, #9787 by @sosukesuzuki, #10065, #10322 by @thorn0) - -Previously, because of the [error recovery](https://babeljs.io/blog/2019/11/05/7.7.0#parser-error-recovery-10363httpsgithubcombabelbabelpull10363), the Babel parser was too permissive, which lead to all kinds of AST shapes that Prettier couldn’t print. Prettier main lets Babel recover only from a few harmless types of errors – for example, multiple `const` declarations with the same name. Anything else is reported as syntax errors. - - -```js -// Input -foo("a", , "b"); - -// Prettier stable -TypeError: Cannot read property 'type' of null - -// Prettier main -[error] stdin: SyntaxError: Argument expression expected. (1:10) -[error] > 1 | foo("a", , "b"); -[error] | ^ -``` - - -```js -// Input -const \u{20} = 1 - -// Prettier stable -const = 1; - -// Prettier main -[error] stdin: SyntaxError: Invalid Unicode escape (1:7) -[error] > 1 | const \u{20} = 1 -[error] | ^ ^ -``` diff --git a/changelog_unreleased/javascript/10517.md b/changelog_unreleased/javascript/10517.md deleted file mode 100644 index abfdcf5ea8..0000000000 --- a/changelog_unreleased/javascript/10517.md +++ /dev/null @@ -1,33 +0,0 @@ -#### Avoid last-argument hugging for number-only arrays (#10517 by @thorn0) - -Another special case for number-only arrays. - - -```jsx -// Input -instantiate(game, [ - transform([-0.7, 0.5, 0]), - render_colored_diffuse(game.MaterialDiffuse, game.Meshes["monkey_flat"], [1, 1, 0.3, 1]), -]); - -// Prettier stable -instantiate(game, [ - transform([-0.7, 0.5, 0]), - render_colored_diffuse(game.MaterialDiffuse, game.Meshes["monkey_flat"], [ - 1, - 1, - 0.3, - 1, - ]), -]); - -// Prettier main -instantiate(game, [ - transform([-0.7, 0.5, 0]), - render_colored_diffuse( - game.MaterialDiffuse, - game.Meshes["monkey_flat"], - [1, 1, 0.3, 1] - ), -]); -``` diff --git a/changelog_unreleased/javascript/10528.md b/changelog_unreleased/javascript/10528.md deleted file mode 100644 index 07cbccec36..0000000000 --- a/changelog_unreleased/javascript/10528.md +++ /dev/null @@ -1,16 +0,0 @@ -#### Improve detection of AMD `define` (#10528 by @thorn0) - -Prettier special-cases AMD `define` calls to avoid unexpected line breaks in them. We now only format `define` calls if they are at the top level of a function or program and are passed arguments in the way AMD expects. - - -```jsx -// Prettier stable -const someVariable = define("some string literal", anotherVariable, yetAnotherVariable); - -// Prettier main -const someVariable = define( - "some string literal", - anotherVariable, - yetAnotherVariable -); -``` diff --git a/changelog_unreleased/javascript/10666.md b/changelog_unreleased/javascript/10666.md deleted file mode 100644 index d35e2fdf10..0000000000 --- a/changelog_unreleased/javascript/10666.md +++ /dev/null @@ -1,21 +0,0 @@ -#### Fix duplicated `prettier-ignore` comments (#10666 by @fisker) - - -```jsx -// Input -foo = a. - // prettier-ignore - b; - -// Prettier stable -foo = - // prettier-ignore - a. - // prettier-ignore - b; - -// Prettier main -foo = a. - // prettier-ignore - b; -``` diff --git a/changelog_unreleased/javascript/10693.md b/changelog_unreleased/javascript/10693.md deleted file mode 100644 index bebf23919b..0000000000 --- a/changelog_unreleased/javascript/10693.md +++ /dev/null @@ -1,20 +0,0 @@ -#### [IMPROVEMENT:5] Improve formatting for `do` expressions in function calls (#10693 by @sosukesuzuki) - -“`do` expressions” are a [stage 1 ECMAScript proposal](https://github.com/tc39/proposal-do-expressions). - - -```js -// Prettier stable -expect( - do { - var bar = "foo"; - bar; - } -).toBe("foo"); - -// Prettier main -expect(do { - var bar = "foo"; - bar; -}).toBe("foo"); -``` diff --git a/changelog_unreleased/javascript/10695.md b/changelog_unreleased/javascript/10695.md deleted file mode 100644 index 8d64d832af..0000000000 --- a/changelog_unreleased/javascript/10695.md +++ /dev/null @@ -1,40 +0,0 @@ -#### Process conditional groups in `mapDoc` (#10695 by @thorn0) - -In particular, this fixes broken substitutions in HTML-in-JS. - - -```jsx -// Input -export default function include_photoswipe( - gallery_selector = ".my-gallery" -): string { - return /* HTML */ ` - `; -} - -// Prettier stable -export default function include_photoswipe( - gallery_selector = ".my-gallery" -): string { - return /* HTML */ ` `; -} - -// Prettier main -export default function include_photoswipe( - gallery_selector = ".my-gallery" -): string { - return /* HTML */ ` `; -} -``` diff --git a/changelog_unreleased/javascript/10712.md b/changelog_unreleased/javascript/10712.md deleted file mode 100644 index ee220b2283..0000000000 --- a/changelog_unreleased/javascript/10712.md +++ /dev/null @@ -1,24 +0,0 @@ -#### Avoid arg expansion that leads to broken code (#10712 by @thorn0) - - -```jsx -// Input -glimseGlyphsHazardNoopsTieTie(({ a, b = () => { - console.log(); -}}) => averredBathersBoxroomBuggyNurl()); - -// Prettier stable -glimseGlyphsHazardNoopsTieTie(({ a, b = () => { - console.log(); - } }) => averredBathersBoxroomBuggyNurl()); - -// Prettier main -glimseGlyphsHazardNoopsTieTie( - ({ - a, - b = () => { - console.log(); - }, - }) => averredBathersBoxroomBuggyNurl() -); -``` diff --git a/changelog_unreleased/javascript/10781.md b/changelog_unreleased/javascript/10781.md deleted file mode 100644 index eec318f358..0000000000 --- a/changelog_unreleased/javascript/10781.md +++ /dev/null @@ -1,17 +0,0 @@ -#### Fix missing parentheses on `async` inside `for..of` (#10781 by @fisker) - - -```jsx -// Input -for ((async) of []); - -// Prettier stable -for (async of []); - -// Prettier stable (second format) -SyntaxError: Unexpected token, expected "=>" (1:15) -> 1 | for (async of []); - -// Prettier main -for ((async) of []); -``` diff --git a/changelog_unreleased/javascript/10813.md b/changelog_unreleased/javascript/10813.md deleted file mode 100644 index 7fd23485e2..0000000000 --- a/changelog_unreleased/javascript/10813.md +++ /dev/null @@ -1,18 +0,0 @@ -#### Support async do expressions proposal (#10813 by @sosukesuzuki) - -https://github.com/tc39/proposal-async-do-expressions - -```js -// Input -const x = async do { - await requestAPI().json(); -}; - -// Prettier stable -SyntaxError: Unexpected token, expected ";" (1:17) - -// Prettier main -const x = async do { - await requestAPI().json(); -}; -``` diff --git a/changelog_unreleased/javascript/10938.md b/changelog_unreleased/javascript/10938.md new file mode 100644 index 0000000000..bd98f47d85 --- /dev/null +++ b/changelog_unreleased/javascript/10938.md @@ -0,0 +1,19 @@ +#### Track cursor position properly when it’s at the end of the range to format (#10938 by @j-f1) + +Previously, if the cursor was at the end of the range to format, it would simply be placed back at the end of the updated range. +Now, it will be repositioned if Prettier decides to add additional code to the end of the range (such as a semicolon). + + +```jsx +// Input (<|> represents the cursor) +const someVariable = myOtherVariable<|> +// range to format: ^^^^^^^^^^^^^^^ + +// Prettier stable +const someVariable = myOtherVariable;<|> +// range to format: ^^^^^^^^^^^^^^^ + +// Prettier main +const someVariable = myOtherVariable<|>; +// range to format: ^^^^^^^^^^^^^^^ +``` diff --git a/changelog_unreleased/javascript/9672.md b/changelog_unreleased/javascript/9672.md deleted file mode 100644 index e23d509eb7..0000000000 --- a/changelog_unreleased/javascript/9672.md +++ /dev/null @@ -1,25 +0,0 @@ -#### Fix unstable multiple comments on the same line (#9672 by @fisker) - - -```js -// Input -a; -/*1*//*2*/ -/*3*/ -b; - -// Prettier stable -a; /*2*/ -/*1*/ /*3*/ -b; - -// Prettier stable (second format) -a; /*2*/ /*3*/ -/*1*/ b; - -// Prettier main -a; -/*1*/ /*2*/ -/*3*/ -b; -``` diff --git a/changelog_unreleased/javascript/9704.md b/changelog_unreleased/javascript/9704.md deleted file mode 100644 index e6963df2a1..0000000000 --- a/changelog_unreleased/javascript/9704.md +++ /dev/null @@ -1,17 +0,0 @@ -#### Don’t format nodes that end just before `rangeStart` (#9704 by @fisker) - -Previously, when [range formatting](https://prettier.io/docs/en/options.html#range) was performed, such nodes were considered part of the range, now they're excluded. This affects other languages that the range formatting feature supports, not only JavaScript. - - -```js -// Input -foo = 1.0000;bar = 1.0000;baz=1.0000; - ^^^^^^^^^^^^^ Range - -// Prettier stable -foo = 1.0; -bar = 1.0;baz=1.0000; - -// Prettier main -foo = 1.0000;bar = 1.0;baz=1.0000; -``` diff --git a/changelog_unreleased/javascript/9711.md b/changelog_unreleased/javascript/9711.md deleted file mode 100644 index bd6788a34d..0000000000 --- a/changelog_unreleased/javascript/9711.md +++ /dev/null @@ -1,18 +0,0 @@ -#### Fix comments inside JSX end tag (#9711 by @fisker) - - -```jsx -// Input -; - -// Prettier stable -; - -// Prettier main -; -``` diff --git a/changelog_unreleased/javascript/9743.md b/changelog_unreleased/javascript/9743.md deleted file mode 100644 index 00bee1081b..0000000000 --- a/changelog_unreleased/javascript/9743.md +++ /dev/null @@ -1,21 +0,0 @@ -#### Fix inconsistent language comment detection (#9743 by @fisker) - -An `/* HTML */` comment should directly precede a template literal for the latter to be recognized as HTML-in-JS. Previously, the comment was erroneously recognized is some other locations. - - -```jsx -// Input -foo /* HTML */ = `
-
`; - -// Prettier stable (--parser=babel) -foo /* HTML */ = `
`; - -// Prettier stable (--parser=meriyah) -foo /* HTML */ = `
-
`; - -// Prettier main (All JavaScript parsers) -foo /* HTML */ = `
-
`; -``` diff --git a/changelog_unreleased/javascript/9850.md b/changelog_unreleased/javascript/9850.md deleted file mode 100644 index 7a0476f1d8..0000000000 --- a/changelog_unreleased/javascript/9850.md +++ /dev/null @@ -1,31 +0,0 @@ -#### Fix extra semicolon added to ignored directives (#9850 by @fisker) - - -```js -// Input -// prettier-ignore -'use strict'; - -function foo() { -// prettier-ignore -"use strict";; -} - -// Prettier stable -// prettier-ignore -'use strict';; - -function foo() { - // prettier-ignore - "use strict";; -} - -// Prettier main -// prettier-ignore -'use strict'; - -function foo() { - // prettier-ignore - "use strict"; -} -``` diff --git a/changelog_unreleased/javascript/9866.md b/changelog_unreleased/javascript/9866.md deleted file mode 100644 index 21b837a621..0000000000 --- a/changelog_unreleased/javascript/9866.md +++ /dev/null @@ -1,29 +0,0 @@ -#### Fix unstable JSX formatting with U+3000 (#9866 by @fisker) - - -```js -// Input -

-  {this.props.data.title}  - //----- ^ U+3000 --------------- ^ U+3000 -

- -// Prettier stable -

- -  {this.props.data.title}  - //----- ^ U+3000 --------------- ^ U+3000 -

; - -// Prettier stable (second format) -

-  {this.props.data.title}  - //----- ^ U+3000 --------------- ^ U+3000 -

; - -// Prettier main -

-  {this.props.data.title}  - //----- ^ U+3000 --------------- ^ U+3000 -

; -``` diff --git a/changelog_unreleased/javascript/9992.md b/changelog_unreleased/javascript/9992.md deleted file mode 100644 index fad44c9399..0000000000 --- a/changelog_unreleased/javascript/9992.md +++ /dev/null @@ -1,19 +0,0 @@ -#### [IMPROVEMENT:0] Refine formatting of curried arrow functions (#9992, #10543 by @sosukesuzuki & @thorn0) - - -```js -// Prettier stable -const currying = (argument1) => (argument2) => (argument3) => (argument4) => ( - argument5 -) => (argument6) => foo; - -// Prettier main -const currying = - (argument1) => - (argument2) => - (argument3) => - (argument4) => - (argument5) => - (argument6) => - foo; -``` diff --git a/changelog_unreleased/json/10323.md b/changelog_unreleased/json/10323.md deleted file mode 100644 index eab0505f60..0000000000 --- a/changelog_unreleased/json/10323.md +++ /dev/null @@ -1,21 +0,0 @@ -#### Don't use smart quotes for JSON5 with `--quote-props=preserve` (#10323 by @thorn0) - -With the `quoteProps` option set to `preserve` and `singleQuotes` to `false` (default), double quotes are always used for printing strings, including situations like `"bla\"bla"`. This effectively allows using `--parser json5` for "JSON with comments and trailing commas". - - -```js -// Input -{ - "char": "\"", -} - -// Prettier stable -{ - "char": '"', -} - -// Prettier main -{ - "char": "\"", -} -``` diff --git a/changelog_unreleased/json/10346.md b/changelog_unreleased/json/10346.md deleted file mode 100644 index cfa51d4896..0000000000 --- a/changelog_unreleased/json/10346.md +++ /dev/null @@ -1,17 +0,0 @@ -#### Stricter JSON parser (#10346, #10443, #10456, #10434 by @fisker) - -Prettier internally uses a JavaScript expression parser to parse JSON. That's why the `json` and `json5` parsers used to be very forgiving and allowed all kinds of JavaScript expressions. Now they are much stricter, although some simple non-standard syntax is still allowed (e.g., [JSON6](https://github.com/d3x0r/JSON6) is supported, except for multiple minus signs: `----123`). - - -```js -// Input -[1, 2, 1 + 2] - -// Prettier stable -[1, 2, 1 + 2] - -// Prettier main -SyntaxError: BinaryExpression is not allowed in JSON. (1:8) -> 1 | [1, 2, 1 + 2] - | ^ -``` diff --git a/changelog_unreleased/json/10433.md b/changelog_unreleased/json/10433.md deleted file mode 100644 index 91a49bf267..0000000000 --- a/changelog_unreleased/json/10433.md +++ /dev/null @@ -1,17 +0,0 @@ -#### Improve error message (#10433 by @fisker) - - -```js -// Input -{key: "foo" + "bar"} - -// Prettier stable (--parser=json-stringify) -SyntaxError: BinaryExpression is not allowed in JSON. (1:7) -> 1 | {key: "foo" + "bar"} - | ^ - -// Prettier main -SyntaxError: BinaryExpression is not allowed in JSON. (1:7) -> 1 | {key: "foo" + "bar"} - | ^^^^^^^^^^^^^ -``` diff --git a/changelog_unreleased/json/10497.md b/changelog_unreleased/json/10497.md deleted file mode 100644 index 10e7b5dc7f..0000000000 --- a/changelog_unreleased/json/10497.md +++ /dev/null @@ -1,16 +0,0 @@ -#### Fix syntax error on JSON range formatting (#10497 by @fisker) - - -```js -// Input -[{ a: 1.0000}, {"b": 2.0000 }] -// ^^^^^^^^^^^ range - -// Prettier stable -SyntaxError: Unexpected token (1:4) -> 1 | "b": 2.0000 - | ^ - -// Prettier main -[{ a: 1.0000}, { "b": 2.0 }] -``` diff --git a/changelog_unreleased/markdown/9736.md b/changelog_unreleased/markdown/9736.md deleted file mode 100644 index a96744438c..0000000000 --- a/changelog_unreleased/markdown/9736.md +++ /dev/null @@ -1,26 +0,0 @@ -#### Fix extra newline at the end of JavaScript fenced code block with string literal (#9736 by @fisker) - - -````markdown - -Markdown - -```js -"· " -``` - - -Markdown - -```js -"· "; - -``` - - -Markdown - -```js -"· "; -``` -```` diff --git a/changelog_unreleased/markdown/9791.md b/changelog_unreleased/markdown/9791.md deleted file mode 100644 index b23ad3027f..0000000000 --- a/changelog_unreleased/markdown/9791.md +++ /dev/null @@ -1,44 +0,0 @@ -#### Fix empty front matter formatting (#9791 by @fisker) - - -```markdown - ---- ---- - -# Title - -a|b|c| -|:--|:-:|--:| -|d|e|f| - ---- - -text - - ---- ---- -# Title - -a|b|c| -|:--|:-:|--:| -|d|e|f| ---- - -text - - ---- ---- - -# Title - -| a | b | c | -| :-- | :-: | --: | -| d | e | f | - ---- - -text -``` diff --git a/changelog_unreleased/markdown/9878.md b/changelog_unreleased/markdown/9878.md deleted file mode 100644 index 409d2c4bbb..0000000000 --- a/changelog_unreleased/markdown/9878.md +++ /dev/null @@ -1,31 +0,0 @@ -#### Support YAML document end marker in front matter (#9878 by @michaelbeaumont) - -Add the ability to delimit the end of front matter with `...`. - - -```markdown - ---- -title: Hello -slug: home -... - -Markdown - - ---- - -title: Hello -slug: home -... - -Markdown - - ---- -title: Hello -slug: home -... - -Markdown -``` diff --git a/changelog_unreleased/scss/10005.md b/changelog_unreleased/scss/10005.md deleted file mode 100644 index 17b441df8b..0000000000 --- a/changelog_unreleased/scss/10005.md +++ /dev/null @@ -1,17 +0,0 @@ -#### Fix maps with keys that are lists or maps (#10005 by @fisker) - - -```scss -// Input -$map: ( - ('my list'): 'hello world', -); - -// Prettier stable -TypeError: Cannot read property 'length' of undefined - -// Prettier main -$map: ( - ("my list"): "hello world", -); -``` diff --git a/changelog_unreleased/scss/9710.md b/changelog_unreleased/scss/9710.md deleted file mode 100644 index a729dddf07..0000000000 --- a/changelog_unreleased/scss/9710.md +++ /dev/null @@ -1,23 +0,0 @@ -#### Fix broken comment inside parens (#9710 by @fisker) - - -```scss -// Input -.simplification { - foo: ( - calc() // not a comment anymore - ); -} - -// Prettier stable -.simplification { - foo: (calc() // not a comment anymore); -} - -// Prettier main -.simplification { - foo: ( - calc() // not a comment anymore - ); -} -``` diff --git a/changelog_unreleased/typescript/10024.md b/changelog_unreleased/typescript/10024.md deleted file mode 100644 index eca023a3ca..0000000000 --- a/changelog_unreleased/typescript/10024.md +++ /dev/null @@ -1,25 +0,0 @@ -#### Fix unnecessary line breaks in method type declaration parameters (#10024 by @sosukesuzuki, #10357 by @thorn0) - - -```js -// Input -type Foo = { - method(foo: "foo"): ` - ` -}; - -// Prettier stable -type Foo = { - method( - foo: "foo" - ): ` - `; -}; - -// Prettier main -type Foo = { - method(foo: "foo"): ` - `; -}; - -``` diff --git a/changelog_unreleased/typescript/10109.md b/changelog_unreleased/typescript/10109.md deleted file mode 100644 index e1bbb5aa5c..0000000000 --- a/changelog_unreleased/typescript/10109.md +++ /dev/null @@ -1,29 +0,0 @@ -#### Print trailing commas in type parameters (#10109 by @sosukesuzuki, #10353 by @thorn0) - -TypeScript has been supporting trailing commas in type parameters since TypeScript 2.7 released in January 2018. Prettier main prints them if the `trailingComma` option is set to `all`. Keep this option at the more conservative default value `es5` if compatibility with TypeScript 2.7 or older is needed. Note that TypeScript [still doesn't support][ts-issue-21984] trailing commas in type arguments (type parameter instantiations). - -[ts-issue-21984]: https://github.com/microsoft/TypeScript/issues/21984 - - -```ts -// Input -export class BaseSingleLevelProfileTargeting< - T extends ValidSingleLevelProfileNode, -> { - // ... -} - -// Prettier stable -export class BaseSingleLevelProfileTargeting< - T extends ValidSingleLevelProfileNode -> { - // ... -} - -// Prettier main with --trailling-comma=all -export class BaseSingleLevelProfileTargeting< - T extends ValidSingleLevelProfileNode, -> { - // ... -} -``` diff --git a/changelog_unreleased/typescript/10316.md b/changelog_unreleased/typescript/10316.md deleted file mode 100644 index 69629b7420..0000000000 --- a/changelog_unreleased/typescript/10316.md +++ /dev/null @@ -1,16 +0,0 @@ -#### Allow hugging arguments that are non-concise arrow functions with return type annotations (#10316 by @thorn0) - - -```ts -// Prettier stable -users.map( - (user: User): User => { - return user; - } -); - -// Prettier main -users.map((user: User): User => { - return user; -}) -``` diff --git a/changelog_unreleased/typescript/10337.md b/changelog_unreleased/typescript/10337.md deleted file mode 100644 index defd35cd3c..0000000000 --- a/changelog_unreleased/typescript/10337.md +++ /dev/null @@ -1,27 +0,0 @@ -#### Correct parentheses for non-null assertions (#10337 by @thorn0) - -Necessary parentheses sometimes weren't printed in expressions containing non-null assertions. This has been fixed. - - -```ts -// Input -const myFunction2 = (key: string): number => - ({ - a: 42, - b: 42, - }[key]!) - -// Prettier stable (invalid syntax) -const myFunction2 = (key: string): number => - { - a: 42, - b: 42, - }[key]!; - -// Prettier main -const myFunction2 = (key: string): number => - ({ - a: 42, - b: 42, - }[key]!); -``` diff --git a/changelog_unreleased/typescript/10341.md b/changelog_unreleased/typescript/10341.md deleted file mode 100644 index 77c838c550..0000000000 --- a/changelog_unreleased/typescript/10341.md +++ /dev/null @@ -1,22 +0,0 @@ -#### Indent type assertions in heads of member and call expressions (#10341 by @thorn0) - - -```ts -// Input -const accountCount = (findItemInSection(BOOKMARKED_PROJECTS_SECTION_NAME, - "My bookmarks") as TreeItem).getChildren().length; - -// Prettier stable -const accountCount = (findItemInSection( - BOOKMARKED_PROJECTS_SECTION_NAME, - "My bookmarks" -) as TreeItem).getChildren().length; - -// Prettier main -const accountCount = ( - findItemInSection( - BOOKMARKED_PROJECTS_SECTION_NAME, - "My bookmarks" - ) as TreeItem -).getChildren().length; -``` diff --git a/changelog_unreleased/typescript/10390.md b/changelog_unreleased/typescript/10390.md deleted file mode 100644 index 0c4671a3ed..0000000000 --- a/changelog_unreleased/typescript/10390.md +++ /dev/null @@ -1,14 +0,0 @@ -#### Support intrinsic keyword (#10390 by @sosukesuzuki) - - -```ts -// Input -type Uppercase = intrinsic; - -// Prettier stable -Error: unknown type: "TSIntrinsicKeyword" - -// Prettier main -type Uppercase = intrinsic; - -``` diff --git a/changelog_unreleased/typescript/10418.md b/changelog_unreleased/typescript/10418.md deleted file mode 100644 index b33afe6f8f..0000000000 --- a/changelog_unreleased/typescript/10418.md +++ /dev/null @@ -1,31 +0,0 @@ -#### Support TypeScript 4.2 (#10418, #10466, #10546, #10589 by @sosukesuzuki) - -##### [`abstract` Construct Signatures](https://devblogs.microsoft.com/typescript/announcing-typescript-4-2/#abstract-construct-signatures) - - -```ts -// Input -type T = abstract new () => void; - -// Prettier stable -SyntaxError: Unexpected token, expected ";" (1:19) - -// Prettier main -type T = abstract new () => void; - -``` - -##### [Type imports in import require declaration](https://github.com/microsoft/TypeScript/pull/41573) - - -```ts -// Input -import type A = require("A"); - -// Prettier stable -SyntaxError: Only ECMAScript imports may use 'import type'. - -// Prettier main -import type A = require("A"); - -``` diff --git a/changelog_unreleased/typescript/10457.md b/changelog_unreleased/typescript/10457.md deleted file mode 100644 index 8587da5a24..0000000000 --- a/changelog_unreleased/typescript/10457.md +++ /dev/null @@ -1,13 +0,0 @@ -#### Fix misplaced comments in unions and intersections (#10457 by @thorn0) - - -```ts -// Input -type Foo = "1" | "2" /* two */ | "3"; - -// Prettier stable -type Foo = "1" | "2" | /* two */ "3"; - -// Prettier main -type Foo = "1" | "2" /* two */ | "3"; -``` diff --git a/changelog_unreleased/typescript/10702.md b/changelog_unreleased/typescript/10702.md deleted file mode 100644 index 8982855f7c..0000000000 --- a/changelog_unreleased/typescript/10702.md +++ /dev/null @@ -1,13 +0,0 @@ -#### Don’t print parens around nested type assertions (#10702 by @thorn0) - - -```ts -// Input -foo as unknown as Bar - -// Prettier stable -(foo as unknown) as Bar; - -// Prettier main -foo as unknown as Bar; -``` diff --git a/changelog_unreleased/typescript/10901.md b/changelog_unreleased/typescript/10901.md new file mode 100644 index 0000000000..4ab300e845 --- /dev/null +++ b/changelog_unreleased/typescript/10901.md @@ -0,0 +1,33 @@ +#### Break the LHS of type alias that has complex type parameters (#10901 by @sosukesusuzki) + + +```ts +// Input +type FieldLayoutWith< + T extends string, + S extends unknown = { width: string } +> = { + type: T; + code: string; + size: S; +}; + +// Prettier stable +type FieldLayoutWith = + { + type: T; + code: string; + size: S; + }; + +// Prettier main +type FieldLayoutWith< + T extends string, + S extends unknown = { width: string } +> = { + type: T; + code: string; + size: S; +}; + +``` diff --git a/changelog_unreleased/typescript/10916.md b/changelog_unreleased/typescript/10916.md new file mode 100644 index 0000000000..68f41577b5 --- /dev/null +++ b/changelog_unreleased/typescript/10916.md @@ -0,0 +1,21 @@ +#### Break the LHS of assignments that has complex type parameters (#10916 by @sosukesuzuki) + + +```ts +// Input +const map: Map< + Function, + Map +> = new Map(); + +// Prettier stable +const map: Map> = + new Map(); + +// Prettier main +const map: Map< + Function, + Map +> = new Map(); + +``` diff --git a/changelog_unreleased/typescript/10940.md b/changelog_unreleased/typescript/10940.md new file mode 100644 index 0000000000..e74b638add --- /dev/null +++ b/changelog_unreleased/typescript/10940.md @@ -0,0 +1,25 @@ +#### Fix incorrectly wrapped arrow functions with return types (#10940 by @thorn0) + + +```ts +// Input +longfunctionWithCall12("bla", foo, (thing: string): complex> => { + code(); +}); + +// Prettier stable +longfunctionWithCall12("bla", foo, (thing: string): complex< + type +> => { + code(); +}); + +// Prettier main +longfunctionWithCall12( + "bla", + foo, + (thing: string): complex> => { + code(); + } +); +``` diff --git a/changelog_unreleased/typescript/10811.md b/changelog_unreleased/typescript/10945.md similarity index 59% rename from changelog_unreleased/typescript/10811.md rename to changelog_unreleased/typescript/10945.md index 5f2a6c99ef..07c4719098 100644 --- a/changelog_unreleased/typescript/10811.md +++ b/changelog_unreleased/typescript/10945.md @@ -1,6 +1,6 @@ -#### Support TypeScript 4.3 via `babel-ts` (#10811 by @sosukesuzuki) +#### Support TypeScript 4.3 (#10945 by @sosukesuzuki) -##### [`override` modifiers in class elements](https://devblogs.microsoft.com/typescript/announcing-typescript-4-3-beta/#override-and-the-noimplicitoverride-flag) +##### [`override` modifiers in class elements](https://devblogs.microsoft.com/typescript/announcing-typescript-4-3/#override) ```ts class Foo extends { @@ -8,7 +8,7 @@ class Foo extends { } ``` -##### [static index signatures (`[key: KeyType]: ValueType`) in classes](https://devblogs.microsoft.com/typescript/announcing-typescript-4-3-beta/#static-index-signatures) +##### [static index signatures (`[key: KeyType]: ValueType`) in classes](https://devblogs.microsoft.com/typescript/announcing-typescript-4-3/#static-index-signatures) ```ts class Foo { @@ -16,7 +16,7 @@ class Foo { } ``` -##### [`get` / `set` in type declarations](https://devblogs.microsoft.com/typescript/announcing-typescript-4-3-beta/#separate-write-types-on-properties) +##### [`get` / `set` in type declarations](https://devblogs.microsoft.com/typescript/announcing-typescript-4-3/#separate-write-types) ```ts interface Foo { diff --git a/changelog_unreleased/typescript/10949.md b/changelog_unreleased/typescript/10949.md new file mode 100644 index 0000000000..973b8b7eb7 --- /dev/null +++ b/changelog_unreleased/typescript/10949.md @@ -0,0 +1,27 @@ +#### Avoid breaking call expressions after assignments with complex type arguments (#10949 by @sosukesuzuki) + + +```ts +// Input +const foo = call<{ + prop1: string; + prop2: string; + prop3: string; +}>(); + +// Prettier stable +const foo = + call<{ + prop1: string; + prop2: string; + prop3: string; + }>(); + +// Prettier main +const foo = call<{ + prop1: string; + prop2: string; + prop3: string; +}>(); + +``` diff --git a/changelog_unreleased/typescript/10961.md b/changelog_unreleased/typescript/10961.md new file mode 100644 index 0000000000..5c8d87a15a --- /dev/null +++ b/changelog_unreleased/typescript/10961.md @@ -0,0 +1,18 @@ +#### Fix order of `override` modifiers (#10961 by @sosukesuzuki) + +```ts +// Input +class Foo extends Bar { + abstract override foo: string; +} + +// Prettier stable +class Foo extends Bar { + override abstract foo: string; +} + +// Prettier main +class Foo extends Bar { + abstract override foo: string; +} +``` diff --git a/changelog_unreleased/typescript/9872.md b/changelog_unreleased/typescript/9872.md deleted file mode 100644 index fd8c2911d9..0000000000 --- a/changelog_unreleased/typescript/9872.md +++ /dev/null @@ -1,19 +0,0 @@ -#### Fix missing comments in `MethodDefinition` (#9872 by @fisker) - -`typescript` parser only, `babel-ts` doesn't have this issue. - - -```typescript -// Input -class Foo { - bar() /* bat */; -} - -// Prettier stable -Error: Comment "bat" was not printed. Please report this error! - -// Prettier main -class Foo { - bar /* bat */(); -} -``` diff --git a/changelog_unreleased/yaml/10516.md b/changelog_unreleased/yaml/10516.md deleted file mode 100644 index 3094ae3e3c..0000000000 --- a/changelog_unreleased/yaml/10516.md +++ /dev/null @@ -1,24 +0,0 @@ -#### Fix SyntaxError incorrectly thrown on anchors followed by empty lines (#10516 by @eemeli & @thorn0) - -Prettier couldn't parse this valid YAML. Thanks to Eemeli Aro for fixing this bug in the underlying parser. - - -```yaml -# Input -key1: &default - - subkey1: value1 - -key2: - <<: *default - -# Prettier stable -SyntaxError: Nested mappings are not allowed in compact mappings (1:7) - -# Prettier main -key1: &default - subkey1: value1 - -key2: - <<: *default -``` diff --git a/changelog_unreleased/yaml/10874.md b/changelog_unreleased/yaml/10874.md new file mode 100644 index 0000000000..c73e119eca --- /dev/null +++ b/changelog_unreleased/yaml/10874.md @@ -0,0 +1,66 @@ +#### Don't switch to explicit mappings needlessly (#10874 by @pdavies) + +Previously, Prettier printed long YAML keys using explicit mapping syntax. The intent was to use that syntax to accommodate multiline keys, but it had the unintended effect of using it even for long keys that couldn’t be made multiline – for example, because `--prose-wrap` was set to `preserve` or the key didn’t contain whitespace. This is bad because: + +- Doing so has the effect of further increasing the line length. +- Explicit mappings are obscure and most people have never seen them. It causes confusion to introduce them needlessly. + + +```yaml +# Input +- stage: Process + jobs: + - template: Process.yml + parameters: + ${{ if in(parameters.BuildType, 'a') }}: + BuildArtifacts: + - input: Build.Release.x86 + output: Processed.Release.x86 + ${{ if in(parameters.BuildType, 'b ') }}: + BuildArtifacts: + - input: Build.Release + output: Processed.Release + +# Prettier stable +- stage: Process + jobs: + - template: Process.yml + parameters: + ${{ if in(parameters.BuildType, 'a') }}: + BuildArtifacts: + - input: Build.Release.x86 + output: Processed.Release.x86 + ? ${{ if in(parameters.BuildType, 'b ') }} + : BuildArtifacts: + - input: Build.Release + output: Processed.Release + +# Prettier main +- stage: Process + jobs: + - template: Process.yml + parameters: + ${{ if in(parameters.BuildType, 'a') }}: + BuildArtifacts: + - input: Build.Release.x86 + output: Processed.Release.x86 + ${{ if in(parameters.BuildType, 'b ') }}: + BuildArtifacts: + - input: Build.Release + output: Processed.Release + +# Prettier main (with --prose-wrap always) +- stage: Process + jobs: + - template: Process.yml + parameters: + ${{ if in(parameters.BuildType, 'a') }}: + BuildArtifacts: + - input: Build.Release.x86 + output: Processed.Release.x86 + ? ${{ if in(parameters.BuildType, 'b ') + }} + : BuildArtifacts: + - input: Build.Release + output: Processed.Release +``` diff --git a/commands.md b/commands.md index e0364a7896..b1bc31ed06 100644 --- a/commands.md +++ b/commands.md @@ -59,7 +59,7 @@ declare function conditionalGroup( ): Doc; ``` -This will try to print the first argument, if it fit use it, otherwise go to the next one and so on. +This will try to print the first alternative, if it fit use it, otherwise go to the next one and so on. The alternatives is an array of documents going from the least expanded (most flattened) representation first to the most expanded. ```js conditionalGroup([a, b, c]); @@ -292,7 +292,7 @@ declare const hardlineWithoutBreakParent: Doc; declare const literallineWithoutBreakParent: Doc; ``` -These are used very rarely, for advanced formatting tricks. Unlike their "normal" counterparts, they don't include an implicit (`breakParent`)[#breakParent]. +These are used very rarely, for advanced formatting tricks. Unlike their "normal" counterparts, they don't include an implicit [`breakParent`](#breakParent). Examples: diff --git a/cspell.json b/cspell.json index f3e0162576..bd29f7d587 100644 --- a/cspell.json +++ b/cspell.json @@ -1,6 +1,16 @@ { "version": "0.1", "words": [ + "Brody", + "Flet", + "arijs", + "brodybits", + "feross", + "memberexpr", + "oneline", + "prettierx", + "semistandard", + "typecheck", "ACMR", "Alexa", "algolia", @@ -54,6 +64,7 @@ "camelified", "chedeau", "cherow", + "Cheung", "chrzosel", "Clemmons", "cliify", @@ -69,6 +80,7 @@ "commonmark", "concating", "cond", + "corejs", "cosmiconfig", "CRLFs", "crossorigin", @@ -126,6 +138,7 @@ "Filipe", "finalizer", "Fiorini", + "Fisker", "fnames", "foldgutter", "formatprg", @@ -201,6 +214,7 @@ "keyframes", "keyof", "Khatri", + "Konstantin", "l’objectif", "lcov", "libdef", @@ -293,6 +307,14 @@ "preorder", "prettier's", "Prettier’s", + "Prettierx’s", + "PrettierX’s", + "Prettierx's", + "PrettierX's", + "prettierx’s", + "prettierX’s", + "prettierx's", + "prettierX's", "prettierformatsource", "prettiergetsupportinfo", "prettierignore", @@ -302,6 +324,7 @@ "progid", "promisify", "proto", + "Pschera", "quasis", "Raghuvir", "Rasmus", @@ -312,10 +335,10 @@ "readlines", "rebalance", "rebeccapurple", - "Redeclaration", "Rects", "recurse", "recurses", + "Redeclaration", "refmt", "regexes", "Reimplement", @@ -342,10 +365,12 @@ "Simen", "singleline", "skratchdot", + "Skyscanner", "socio", "softline", "softlines", "Sorin", + "Sosuke", "srcset", "Stachowiak", "staged's", @@ -379,7 +404,6 @@ "TSESTree", "TSESTreeOptions", "TSJS", - "tslib", "typeahead", "typecasted", "typecheck", @@ -453,4 +477,4 @@ "website/static/lib/**", "website/static/playground.js" ] -} \ No newline at end of file +} diff --git a/docs/browser.md b/docs/browser.md index f764d5f079..cb7aee8496 100644 --- a/docs/browser.md +++ b/docs/browser.md @@ -32,8 +32,8 @@ See below for examples. ### Global ```html - - + + \`; + +const nestedFun2 = /* HTML */ \`\${outerExpr(1)} + \`; + +setFoo( + html\`
one
+
two
+
three
\`, + secondArgument +); + +setFoo( + html\`
+
nested
+
+
two
+
three
\`, + secondArgument +); + +setFoo( + html\`
+
nested
+
\`, + secondArgument +); + +=====================================output===================================== +const nestedFun = /* HTML */ \`\${ outerExpr( 1 ) } + \`; + +const nestedFun2 = /* HTML */ \`\${ outerExpr( 1 ) } + \`; + +setFoo( + html\`
one
+
two
+
three
\`, + secondArgument +); + +setFoo( + html\`
+
nested
+
+
two
+
three
\`, + secondArgument +); + +setFoo( + html\`
+
nested
+
\`, + secondArgument +); + +================================================================================ +`; + +exports[`import-export.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} [espree] format 1`] = ` +"Unexpected token a (5:8) + 3 | import(\\"module.js\\").then((a) => a); + 4 | +> 5 | export a, { b } from \\"./baz\\"; + | ^ + 6 | + 7 | export default () => { }; + 8 |" +`; + +exports[`import-export.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} [meriyah] format 1`] = ` +"[5:8]: Unexpected token: 'identifier' (5:8) + 3 | import(\\"module.js\\").then((a) => a); + 4 | +> 5 | export a, { b } from \\"./baz\\"; + | ^ + 6 | + 7 | export default () => { }; + 8 |" +`; + +exports[`import-export.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "babel-ts"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true + | printWidth +=====================================input====================================== +import { fitsIn, oneLine } from '.'; + +import("module.js").then((a) => a); + +export a, { b } from "./baz"; + +export default () => { }; + +export const c = (function f() { }) + +=====================================output===================================== +import { fitsIn, oneLine } from "."; + +import( "module.js" ).then( ( a ) => a ); + +export a, { b } from "./baz"; + +export default () => {}; + +export const c = function f() {}; + +================================================================================ +`; + +exports[`jest-test-each.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "babel-ts"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true + | printWidth +=====================================input====================================== +test.each\` + a | b | expected + \${1} | \${1} | \${2} + \${1} | \${2} | \${3} + \${2} | \${1} | \${3} +\`("returns $expected when $a is added $b", ({a, b, expected}) => { + expect(a + b).toBe(expected); +}); + +=====================================output===================================== +test.each\` + a | b | expected + \${ 1 } | \${ 1 } | \${ 2 } + \${ 1 } | \${ 2 } | \${ 3 } + \${ 2 } | \${ 1 } | \${ 3 } +\`( "returns $expected when $a is added $b", ( { a, b, expected } ) => { + expect( a + b ).toBe( expected ); +} ); + +================================================================================ +`; + +exports[`loops.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "babel-ts"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true + | printWidth +=====================================input====================================== +while (someVeryLongFunc(someVeryLongArgA, someVeryLongArgB, someVeryLongArgC, someVeryLongArgD)) { } + +do { } +while (someVeryLongFunc(someVeryLongArgA, someVeryLongArgB, someVeryLongArgC, someVeryLongArgD)); + +for (let i = 0, len = arr.length; i < len; i++) { } + +(async () => { + for await (num of asyncIterable) { + console.log(num); + } + for await (const x of delegate_yield()) { + x; + } +})(); + +=====================================output===================================== +while ( + someVeryLongFunc( + someVeryLongArgA, + someVeryLongArgB, + someVeryLongArgC, + someVeryLongArgD + ) +) {} + +do {} while ( + someVeryLongFunc( + someVeryLongArgA, + someVeryLongArgB, + someVeryLongArgC, + someVeryLongArgD + ) +); + +for ( let i = 0, len = arr.length; i < len; i++ ) {} + +( async () => { + for await ( num of asyncIterable ) { + console.log( num ); + } + for await ( const x of delegate_yield() ) { + x; + } +} )(); + +================================================================================ +`; + +exports[`nullish.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "babel-ts"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true + | printWidth +=====================================input====================================== +const x = (foo, bar = foo ?? bar) => { }; + +foo ? bar ?? foo : baz; + +foo ?? (bar ?? baz); +(foo ?? bar) ?? baz; + +=====================================output===================================== +const x = ( foo, bar = foo ?? bar ) => {}; + +foo ? bar ?? foo : baz; + +foo ?? bar ?? baz; +foo ?? bar ?? baz; + +================================================================================ +`; + +exports[`objects.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} [espree] format 1`] = ` +"Unexpected token : (5:4) + 3 | a = () => ({}).x; + 4 | ({} && a, b); +> 5 | ({}:: b, 0); + | ^ + 6 | ({}:: b()\`\`[''].c++ && 0 ? 0 : 0, 0); + 7 | ({}(), 0); + 8 | ({} = 0);" +`; + +exports[`objects.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} [meriyah] format 1`] = ` +"[5:4]: Expected ')' (5:4) + 3 | a = () => ({}).x; + 4 | ({} && a, b); +> 5 | ({}:: b, 0); + | ^ + 6 | ({}:: b()\`\`[''].c++ && 0 ? 0 : 0, 0); + 7 | ({}(), 0); + 8 | ({} = 0);" +`; + +exports[`objects.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "babel-ts"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true + | printWidth +=====================================input====================================== +() => ({}\`\`); +({})\`\`; +a = () => ({}).x; +({} && a, b); +({}:: b, 0); +({}:: b()\`\`[''].c++ && 0 ? 0 : 0, 0); +({}(), 0); +({} = 0); +(({} = 0), 1); + +=====================================output===================================== +() => ( {}\`\` ); +( {}\`\` ); +a = () => ( {}.x ); +( {} && a, b ); +( {}::b, 0 ); +( {}::b()\`\`[ "" ].c++ && 0 ? 0 : 0, 0 ); +( {}(), 0 ); +( {} = 0 ); +( {} = 0 ), 1; + +================================================================================ +`; + +exports[`return.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "babel-ts"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true + | printWidth +=====================================input====================================== +function f() { + return ( + foo + // comment + .bar() + ); +} + +=====================================output===================================== +function f() { + return ( + foo + // comment + .bar() + ); +} + +================================================================================ +`; + +exports[`sequence.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "babel-ts"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true + | printWidth +=====================================input====================================== +(a = b ? c : function () { return 0; }), + (a = b ? c : function () { return 0; }), + (a = b ? c : function () { return 0; }), + (a = b ? c : function () { return 0; }), + (a = b ? c : function () { return 0; }); + +=====================================output===================================== +( a = b + ? c + : function () { + return 0; + } ), + ( a = b + ? c + : function () { + return 0; + } ), + ( a = b + ? c + : function () { + return 0; + } ), + ( a = b + ? c + : function () { + return 0; + } ), + ( a = b + ? c + : function () { + return 0; + } ); + +================================================================================ +`; + +exports[`spread.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} [espree] format 1`] = ` +"Unexpected token class (7:9) + 5 | async () => ({ ...(await foo) }); + 6 | +> 7 | declare class C { f(...r): void; } + | ^ + 8 |" +`; + +exports[`spread.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} [meriyah] format 1`] = ` +"[7:13]: Unexpected token: 'class' (7:13) + 5 | async () => ({ ...(await foo) }); + 6 | +> 7 | declare class C { f(...r): void; } + | ^ + 8 |" +`; + +exports[`spread.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "babel-ts"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true + | printWidth +=====================================input====================================== +const foo = { ...(a || b) }; +const foo2 = { ...a || b }; +const foo3 = { ...(a ? b : c) }; + +async () => ({ ...(await foo) }); + +declare class C { f(...r): void; } + +=====================================output===================================== +const foo = { ...( a || b ) }; +const foo2 = { ...( a || b ) }; +const foo3 = { ...( a ? b : c ) }; + +async () => ( { ...( await foo ) } ); + +declare class C { + f( ...r ): void; +} + +================================================================================ +`; + +exports[`switch.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "babel-ts"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true + | printWidth +=====================================input====================================== +switch (a) { + case 3: + alert("3"); + break; + case 4: + alert("4"); + break; + case 5: + alert("5"); + break; + default: + alert("default"); +} + +=====================================output===================================== +switch ( a ) { + case 3: + alert( "3" ); + break; + case 4: + alert( "4" ); + break; + case 5: + alert( "5" ); + break; + default: + alert( "default" ); +} + +================================================================================ +`; + +exports[`template-literals.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "babel-ts"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true + | printWidth +=====================================input====================================== +\`\${1 ?? 2}\`; + +\`glp-text-\${isImagePresent ? 56 : 64}@M\` + +const headerResolve = css.resolve\` +.top-bar {background:black; + margin: 0; + position: fixed; + top: 0;left:0; + width: 100%; + text-align: center ; + padding: 15px 0 0 1em; + z-index: 9999; +} + +.top-bar .logo { + height: 30px; + margin: auto; + position: absolute; + left: 0;right: 0; +} +\`; + +styled.input\` + border: 1px solid + \${(props) => (props.isError?props.theme.colors.error:props.theme.colors.borderColor)}; + :focus { + outline: \${(props) => + props.isError + ?props.theme.colors.error + :props.theme.colors.outline} + } +\`; + +const value = \` + Hello \${(props) => (props.isError?props.theme.colors.error:props.theme.colors.borderColor)}; +\`; + +return (
) + +=====================================output===================================== +\`\${ 1 ?? 2 }\`; + +\`glp-text-\${ isImagePresent ? 56 : 64 }@M\`; + +const headerResolve = css.resolve\` + .top-bar { + background: black; + margin: 0; + position: fixed; + top: 0; + left: 0; + width: 100%; + text-align: center; + padding: 15px 0 0 1em; + z-index: 9999; + } + + .top-bar .logo { + height: 30px; + margin: auto; + position: absolute; + left: 0; + right: 0; + } +\`; + +styled.input\` + border: 1px solid + \${ ( props ) => + props.isError + ? props.theme.colors.error + : props.theme.colors.borderColor }; + :focus { + outline: \${ ( props ) => + props.isError ? props.theme.colors.error : props.theme.colors.outline }; + } +\`; + +const value = \` + Hello \${ ( props ) => + props.isError ? props.theme.colors.error : props.theme.colors.borderColor }; +\`; + +return ( +
+); + +================================================================================ +`; + +exports[`ternaries.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "babel-ts"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true + | printWidth +=====================================input====================================== +a => a ? () => { a } : () => { a } + +const devOnly = (block) => (__DEV__?block:null); + +f(result => (result ? result : candidate), "foobar"); + +const obj = { + foo: "foo", + bar: "bar", + text: () => (typeof text === "function" ? text() : text), +}; + +=====================================output===================================== +( a ) => + a + ? () => { + a; + } + : () => { + a; + }; + +const devOnly = ( block ) => ( __DEV__ ? block : null ); + +f( ( result ) => ( result ? result : candidate ), "foobar" ); + +const obj = { + foo: "foo", + bar: "bar", + text: () => ( typeof text === "function" ? text() : text ), +}; + +================================================================================ +`; + +exports[`throw.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} [espree] format 1`] = ` +"Unexpected token throw (6:15) + 4 | + 5 | lint(ast, { +> 6 | with: () => throw new Error(\\"avoid using 'with' statements.\\") + | ^ + 7 | }); + 8 |" +`; + +exports[`throw.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} [meriyah] format 1`] = ` +"[6:19]: Unexpected token: 'throw' (6:19) + 4 | + 5 | lint(ast, { +> 6 | with: () => throw new Error(\\"avoid using 'with' statements.\\") + | ^ + 7 | }); + 8 |" +`; + +exports[`throw.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "babel-ts"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true + | printWidth +=====================================input====================================== +function f() { + throw (foo.bar()); +} + +lint(ast, { + with: () => throw new Error("avoid using 'with' statements.") + }); + +=====================================output===================================== +function f() { + throw foo.bar(); +} + +lint( ast, { + with: () => throw new Error( "avoid using 'with' statements." ), +} ); + +================================================================================ +`; + +exports[`try-catch.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} [espree] format 1`] = ` +"Cannot use keyword 'await' outside an async function (3:11) + 1 | try { foo() } + 2 | catch (e) { bar() } +> 3 | finally { await baz() } + | ^ + 4 |" +`; + +exports[`try-catch.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} [meriyah] format 1`] = ` +"[3:15]: 'Await' may not be used as an identifier in this context (3:15) + 1 | try { foo() } + 2 | catch (e) { bar() } +> 3 | finally { await baz() } + | ^ + 4 |" +`; + +exports[`try-catch.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "babel-ts"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true + | printWidth +=====================================input====================================== +try { foo() } +catch (e) { bar() } +finally { await baz() } + +=====================================output===================================== +try { + foo(); +} catch ( e ) { + bar(); +} finally { + await baz(); +} + +================================================================================ +`; + +exports[`with.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "babel-ts"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true + | printWidth +=====================================input====================================== +with (0) { }; + +=====================================output===================================== +with ( 0 ) { +} + +================================================================================ +`; diff --git a/tests/format/js/inner-paren-spacing/arrays.js b/tests/format/js/inner-paren-spacing/arrays.js new file mode 100644 index 0000000000..4ee01f441e --- /dev/null +++ b/tests/format/js/inner-paren-spacing/arrays.js @@ -0,0 +1,9 @@ +[[]]; +[[], []]; +[[], [], []]; +[[], [0], []]; +[[], [0], [0]]; +[[], [0, 1], [0]]; +[[], [0, 1], [0, 1]]; +[...a, ...b,]; +[...a, ...b]; diff --git a/tests/format/js/inner-paren-spacing/bind.js b/tests/format/js/inner-paren-spacing/bind.js new file mode 100644 index 0000000000..0b5092bd35 --- /dev/null +++ b/tests/format/js/inner-paren-spacing/bind.js @@ -0,0 +1,38 @@ +(a || b):: c; +a || (b:: c); +:: obj.prop; +(void 0):: func(); +(+0):: is(-0); +a:: (b.c); +a:: (b.c()); +a:: b.c(); +a:: (b.c()()); +a:: ((b.c())()); +a:: (b.c())(); +a:: (b.c().d); +a:: (c().d.e); +a:: (b()); +a:: (b:: c()); +a:: (b():: c); +a:: (b().c:: d); +a:: (b.c:: d); +a:: (b:: c.d); +a:: (b.c:: d:: e); +a:: (b:: c:: d); +a:: (b:: c:: d.e); +a:: ((b:: c:: d).e); +a:: (void 0); +a:: (b.c():: d.e); +a:: (b.c:: d.e); +a:: (b.c:: d.e):: f.g; +b.c:: d.e; +(b.c:: d).e; +(b:: c:: d).e; +new (a:: b) (); +new f(a:: b); +f[a:: b]; +f[a:: b()]; + +a => ({}:: b()``[''].c++ && 0 ? 0 : 0); +(a => b):: c; +a:: (b => c); diff --git a/tests/format/js/inner-paren-spacing/class.js b/tests/format/js/inner-paren-spacing/class.js new file mode 100644 index 0000000000..be724d249d --- /dev/null +++ b/tests/format/js/inner-paren-spacing/class.js @@ -0,0 +1,14 @@ +class c { + ["i"]() { } +} + +(class { }) + 1; +(class a { }) + 1; +(class extends b { }) + 1; +(class a extends b { }) + 1; + +class X { + async * b() { + yield* a(); + } +} diff --git a/tests/format/js/inner-paren-spacing/conditionals.js b/tests/format/js/inner-paren-spacing/conditionals.js new file mode 100644 index 0000000000..4396bc2deb --- /dev/null +++ b/tests/format/js/inner-paren-spacing/conditionals.js @@ -0,0 +1,23 @@ +if (someVeryLongFunc(someVeryLongArgA, someVeryLongArgB, someVeryLongArgC, someVeryLongArgD)) { } + +const radioSelectedAttr = + (isAnyValueSelected && + node.getAttribute(radioAttr.toLowerCase()) === radioValue) || + ((!isAnyValueSelected && values[a].default === true) || a === 0); + +function f() { + if (position) + {return { name: pair };} + return { + name: pair.slice(0, Math.max(0, position)), + value: pair.slice(Math.max(0, position + 1)) + }; +} + + +(foo || bar) || baz; +foo || (bar || baz); +foo || ((bar || baz) || qux); +foo || (bar || (baz || qux)); +foo || (bar || ((baz || qux) || xyz)); +foo || (bar || (baz || (qux || xyz))); diff --git a/tests/format/js/inner-paren-spacing/destructuring.js b/tests/format/js/inner-paren-spacing/destructuring.js new file mode 100644 index 0000000000..af3cad0f17 --- /dev/null +++ b/tests/format/js/inner-paren-spacing/destructuring.js @@ -0,0 +1,3 @@ +const [one, two = null, three = null] = arr; +a = ([s = 1,]) => 1 +const { children, ...props } = this.props diff --git a/tests/format/js/inner-paren-spacing/expressions.js b/tests/format/js/inner-paren-spacing/expressions.js new file mode 100644 index 0000000000..ffdf8e4596 --- /dev/null +++ b/tests/format/js/inner-paren-spacing/expressions.js @@ -0,0 +1,15 @@ +(this.x++).toString() + +new (r++); + +(x++)(); + +const uuid = String(this._uuidCounter++); + +!( + { a: 1, b: 2 } // foo +) + +new (factory())(factory()) + +object.foo().bar().baz(); diff --git a/tests/format/js/inner-paren-spacing/functions.js b/tests/format/js/inner-paren-spacing/functions.js new file mode 100644 index 0000000000..52fc816d3d --- /dev/null +++ b/tests/format/js/inner-paren-spacing/functions.js @@ -0,0 +1,19 @@ +function* f() { + (yield async (a) => a); +} + +async function f3() { + a = (await 1) ? 1 : 1; +} + +(function () { }).length +typeof (function () { }); +export default (function () { })(); +(function () { })()``; +(function () { })``; +new (function () { }); +(function () { }); +a = function f() { } || b; +(function () { } && a); +a + function () { }; +new function () { }; diff --git a/tests/format/js/inner-paren-spacing/html-template-literals.js b/tests/format/js/inner-paren-spacing/html-template-literals.js new file mode 100644 index 0000000000..d4a787b566 --- /dev/null +++ b/tests/format/js/inner-paren-spacing/html-template-literals.js @@ -0,0 +1,32 @@ +const nestedFun = /* HTML */ `${outerExpr(1)} + `; + +const nestedFun2 = /* HTML */ `${outerExpr(1)} + `; + +setFoo( + html`
one
+
two
+
three
`, + secondArgument +); + +setFoo( + html`
+
nested
+
+
two
+
three
`, + secondArgument +); + +setFoo( + html`
+
nested
+
`, + secondArgument +); diff --git a/tests/format/js/inner-paren-spacing/import-export.js b/tests/format/js/inner-paren-spacing/import-export.js new file mode 100644 index 0000000000..d149be0a36 --- /dev/null +++ b/tests/format/js/inner-paren-spacing/import-export.js @@ -0,0 +1,9 @@ +import { fitsIn, oneLine } from '.'; + +import("module.js").then((a) => a); + +export a, { b } from "./baz"; + +export default () => { }; + +export const c = (function f() { }) diff --git a/tests/format/js/inner-paren-spacing/jest-test-each.js b/tests/format/js/inner-paren-spacing/jest-test-each.js new file mode 100644 index 0000000000..ae98ed2096 --- /dev/null +++ b/tests/format/js/inner-paren-spacing/jest-test-each.js @@ -0,0 +1,8 @@ +test.each` + a | b | expected + ${1} | ${1} | ${2} + ${1} | ${2} | ${3} + ${2} | ${1} | ${3} +`("returns $expected when $a is added $b", ({a, b, expected}) => { + expect(a + b).toBe(expected); +}); diff --git a/tests/format/js/inner-paren-spacing/jsfmt.spec.js b/tests/format/js/inner-paren-spacing/jsfmt.spec.js new file mode 100644 index 0000000000..2b01fcb39b --- /dev/null +++ b/tests/format/js/inner-paren-spacing/jsfmt.spec.js @@ -0,0 +1,25 @@ +run_spec(__dirname, ["babel", "babel-flow", "babel-ts"], { + spaceInParens: true, + arrayBracketSpacing: true, + computedPropertySpacing: true, + spaceUnaryOps: true, + templateCurlySpacing: true, + errors: { + espree: [ + "bind.js", + "import-export.js", + "objects.js", + "spread.js", + "throw.js", + "try-catch.js", + ], + meriyah: [ + "bind.js", + "import-export.js", + "objects.js", + "spread.js", + "throw.js", + "try-catch.js", + ], + }, +}); diff --git a/tests/format/js/inner-paren-spacing/loops.js b/tests/format/js/inner-paren-spacing/loops.js new file mode 100644 index 0000000000..0ab2de0465 --- /dev/null +++ b/tests/format/js/inner-paren-spacing/loops.js @@ -0,0 +1,15 @@ +while (someVeryLongFunc(someVeryLongArgA, someVeryLongArgB, someVeryLongArgC, someVeryLongArgD)) { } + +do { } +while (someVeryLongFunc(someVeryLongArgA, someVeryLongArgB, someVeryLongArgC, someVeryLongArgD)); + +for (let i = 0, len = arr.length; i < len; i++) { } + +(async () => { + for await (num of asyncIterable) { + console.log(num); + } + for await (const x of delegate_yield()) { + x; + } +})(); diff --git a/tests/format/js/inner-paren-spacing/nullish.js b/tests/format/js/inner-paren-spacing/nullish.js new file mode 100644 index 0000000000..7c74200b62 --- /dev/null +++ b/tests/format/js/inner-paren-spacing/nullish.js @@ -0,0 +1,6 @@ +const x = (foo, bar = foo ?? bar) => { }; + +foo ? bar ?? foo : baz; + +foo ?? (bar ?? baz); +(foo ?? bar) ?? baz; diff --git a/tests/format/js/inner-paren-spacing/objects.js b/tests/format/js/inner-paren-spacing/objects.js new file mode 100644 index 0000000000..c6d3f9cb4d --- /dev/null +++ b/tests/format/js/inner-paren-spacing/objects.js @@ -0,0 +1,9 @@ +() => ({}``); +({})``; +a = () => ({}).x; +({} && a, b); +({}:: b, 0); +({}:: b()``[''].c++ && 0 ? 0 : 0, 0); +({}(), 0); +({} = 0); +(({} = 0), 1); diff --git a/tests/format/js/inner-paren-spacing/return.js b/tests/format/js/inner-paren-spacing/return.js new file mode 100644 index 0000000000..457205e616 --- /dev/null +++ b/tests/format/js/inner-paren-spacing/return.js @@ -0,0 +1,7 @@ +function f() { + return ( + foo + // comment + .bar() + ); +} diff --git a/tests/format/js/inner-paren-spacing/sequence.js b/tests/format/js/inner-paren-spacing/sequence.js new file mode 100644 index 0000000000..6b8b54dc27 --- /dev/null +++ b/tests/format/js/inner-paren-spacing/sequence.js @@ -0,0 +1,5 @@ +(a = b ? c : function () { return 0; }), + (a = b ? c : function () { return 0; }), + (a = b ? c : function () { return 0; }), + (a = b ? c : function () { return 0; }), + (a = b ? c : function () { return 0; }); diff --git a/tests/format/js/inner-paren-spacing/spread.js b/tests/format/js/inner-paren-spacing/spread.js new file mode 100644 index 0000000000..cb5cc23413 --- /dev/null +++ b/tests/format/js/inner-paren-spacing/spread.js @@ -0,0 +1,7 @@ +const foo = { ...(a || b) }; +const foo2 = { ...a || b }; +const foo3 = { ...(a ? b : c) }; + +async () => ({ ...(await foo) }); + +declare class C { f(...r): void; } diff --git a/tests/format/js/inner-paren-spacing/switch.js b/tests/format/js/inner-paren-spacing/switch.js new file mode 100644 index 0000000000..beb143202e --- /dev/null +++ b/tests/format/js/inner-paren-spacing/switch.js @@ -0,0 +1,13 @@ +switch (a) { + case 3: + alert("3"); + break; + case 4: + alert("4"); + break; + case 5: + alert("5"); + break; + default: + alert("default"); +} diff --git a/tests/format/js/inner-paren-spacing/template-literals.js b/tests/format/js/inner-paren-spacing/template-literals.js new file mode 100644 index 0000000000..f3bba34fa2 --- /dev/null +++ b/tests/format/js/inner-paren-spacing/template-literals.js @@ -0,0 +1,50 @@ +`${1 ?? 2}`; + +`glp-text-${isImagePresent ? 56 : 64}@M` + +const headerResolve = css.resolve` +.top-bar {background:black; + margin: 0; + position: fixed; + top: 0;left:0; + width: 100%; + text-align: center ; + padding: 15px 0 0 1em; + z-index: 9999; +} + +.top-bar .logo { + height: 30px; + margin: auto; + position: absolute; + left: 0;right: 0; +} +`; + +styled.input` + border: 1px solid + ${(props) => (props.isError?props.theme.colors.error:props.theme.colors.borderColor)}; + :focus { + outline: ${(props) => + props.isError + ?props.theme.colors.error + :props.theme.colors.outline} + } +`; + +const value = ` + Hello ${(props) => (props.isError?props.theme.colors.error:props.theme.colors.borderColor)}; +`; + +return (
) diff --git a/tests/format/js/inner-paren-spacing/ternaries.js b/tests/format/js/inner-paren-spacing/ternaries.js new file mode 100644 index 0000000000..33e0fdb1a2 --- /dev/null +++ b/tests/format/js/inner-paren-spacing/ternaries.js @@ -0,0 +1,11 @@ +a => a ? () => { a } : () => { a } + +const devOnly = (block) => (__DEV__?block:null); + +f(result => (result ? result : candidate), "foobar"); + +const obj = { + foo: "foo", + bar: "bar", + text: () => (typeof text === "function" ? text() : text), +}; diff --git a/tests/format/js/inner-paren-spacing/throw.js b/tests/format/js/inner-paren-spacing/throw.js new file mode 100644 index 0000000000..8987db34e3 --- /dev/null +++ b/tests/format/js/inner-paren-spacing/throw.js @@ -0,0 +1,7 @@ +function f() { + throw (foo.bar()); +} + +lint(ast, { + with: () => throw new Error("avoid using 'with' statements.") + }); diff --git a/tests/format/js/inner-paren-spacing/try-catch.js b/tests/format/js/inner-paren-spacing/try-catch.js new file mode 100644 index 0000000000..069c217964 --- /dev/null +++ b/tests/format/js/inner-paren-spacing/try-catch.js @@ -0,0 +1,3 @@ +try { foo() } +catch (e) { bar() } +finally { await baz() } diff --git a/tests/format/js/inner-paren-spacing/with.js b/tests/format/js/inner-paren-spacing/with.js new file mode 100644 index 0000000000..ee94c7356f --- /dev/null +++ b/tests/format/js/inner-paren-spacing/with.js @@ -0,0 +1 @@ +with (0) { }; diff --git a/tests/format/js/method-chain/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/method-chain/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..9f4ad0b570 --- /dev/null +++ b/tests/format/js/method-chain/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,1692 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`bracket_0.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +function a() { + function b() { + queryThenMutateDOM( + () => { + title = SomeThing.call(root, 'someLongStringThatPushesThisTextReallyFar')[0]; + } + ); + } +} + +=====================================output===================================== +function a() { + function b() { + queryThenMutateDOM( () => { + title = SomeThing.call( + root, + "someLongStringThatPushesThisTextReallyFar" + )[ 0 ]; + } ); + } +} + +================================================================================ +`; + +exports[`bracket_0-1.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +const thingamabobMetaAlias = +path.scope.getProgramParent().path.get("body")[0].node; + +=====================================output===================================== +const thingamabobMetaAlias = path.scope + .getProgramParent() + .path.get( "body" )[ 0 ].node; + +================================================================================ +`; + +exports[`break-last-call.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +export default store => { + return callApi(endpoint, schema).then( + response => next(actionWith({ + response, + type: successType + })), + error => next(actionWith({ + type: failureType, + error: error.message || 'Something bad happened' + })) + ) +} + +it('should group messages with same created time', () => { + expect( + groupMessages(messages).toJS(), + ).toEqual({ + '11/01/2017 13:36': [ + {message: 'test', messageType: 'SMS', status: 'Unknown', created: '11/01/2017 13:36'}, + {message: 'test', messageType: 'Email', status: 'Unknown', created: '11/01/2017 13:36'}, + ], + '09/01/2017 17:25': [ + {message: 'te', messageType: 'SMS', status: 'Unknown', created: '09/01/2017 17:25'}, + {message: 'te', messageType: 'Email', status: 'Unknown', created: '09/01/2017 17:25'}, + ], + '11/01/2017 13:33': [ + {message: 'test', messageType: 'SMS', status: 'Unknown', created: '11/01/2017 13:33'}, + {message: 'test', messageType: 'Email', status: 'Unknown', created: '11/01/2017 13:33'}, + ], + '11/01/2017 13:37': [ + {message: 'test', messageType: 'SMS', status: 'Unknown', created: '11/01/2017 13:37'}, + {message: 'test', messageType: 'Email', status: 'Unknown', created: '11/01/2017 13:37'}, + ], + }); +}); + +=====================================output===================================== +export default store => { + return callApi( endpoint, schema ).then( + response => + next( + actionWith( { + response, + type: successType, + } ) + ), + error => + next( + actionWith( { + type: failureType, + error: error.message || "Something bad happened", + } ) + ) + ); +}; + +it( "should group messages with same created time", () => { + expect( groupMessages( messages ).toJS() ).toEqual( { + "11/01/2017 13:36": [ + { + message: "test", + messageType: "SMS", + status: "Unknown", + created: "11/01/2017 13:36", + }, + { + message: "test", + messageType: "Email", + status: "Unknown", + created: "11/01/2017 13:36", + }, + ], + "09/01/2017 17:25": [ + { + message: "te", + messageType: "SMS", + status: "Unknown", + created: "09/01/2017 17:25", + }, + { + message: "te", + messageType: "Email", + status: "Unknown", + created: "09/01/2017 17:25", + }, + ], + "11/01/2017 13:33": [ + { + message: "test", + messageType: "SMS", + status: "Unknown", + created: "11/01/2017 13:33", + }, + { + message: "test", + messageType: "Email", + status: "Unknown", + created: "11/01/2017 13:33", + }, + ], + "11/01/2017 13:37": [ + { + message: "test", + messageType: "SMS", + status: "Unknown", + created: "11/01/2017 13:37", + }, + { + message: "test", + messageType: "Email", + status: "Unknown", + created: "11/01/2017 13:37", + }, + ], + } ); +} ); + +================================================================================ +`; + +exports[`break-last-member.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +SomeVeryLongUpperCaseConstant.someVeryLongCallExpression().some_very_long_member_expression +weNeedToReachTheEightyCharacterLimitXXXXXXXXXXXXXXXXX.someNode + .childrenInAnArray[0]; +superSupersuperSupersuperSupersuperSupersuperSuperLong.exampleOfOrderOfGetterAndSetterReordered; +superSupersuperSupersuperSupersuperSupersuperSuperLong.exampleOfOrderOfGetterAndSetterReordered[0]; + +expect( + findDOMNode(component.instance()).getElementsByClassName(styles.inner)[0].style.paddingRight +).toBe('1000px'); + +const { course, conflicts = [], index, scheduleId, studentId, something } = a.this.props; + +const { course2, conflicts2 = [], index2, scheduleId2, studentId2, something2 } = this.props; + +const { + updated, + author: { identifier: ownerId }, + location, + category: categories, +} = rawAd.entry; + +=====================================output===================================== +SomeVeryLongUpperCaseConstant.someVeryLongCallExpression() + .some_very_long_member_expression; +weNeedToReachTheEightyCharacterLimitXXXXXXXXXXXXXXXXX.someNode + .childrenInAnArray[ 0 ]; +superSupersuperSupersuperSupersuperSupersuperSuperLong.exampleOfOrderOfGetterAndSetterReordered; +superSupersuperSupersuperSupersuperSupersuperSuperLong + .exampleOfOrderOfGetterAndSetterReordered[ 0 ]; + +expect( + findDOMNode( component.instance() ).getElementsByClassName( + styles.inner + )[ 0 ].style.paddingRight +).toBe( "1000px" ); + +const { + course, + conflicts = [], + index, + scheduleId, + studentId, + something, +} = a.this.props; + +const { + course2, + conflicts2 = [], + index2, + scheduleId2, + studentId2, + something2, +} = this.props; + +const { + updated, + author: { identifier: ownerId }, + location, + category: categories, +} = rawAd.entry; + +================================================================================ +`; + +exports[`break-multiple.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +object.foo().bar().baz(); + +foo().bar().baz(); + +foo().bar.baz(); + +=====================================output===================================== +object.foo().bar().baz(); + +foo().bar().baz(); + +foo().bar.baz(); + +================================================================================ +`; + +exports[`comment.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +function f() { + return observableFromSubscribeFunction() + // Debounce manually rather than using editor.onDidStopChanging so that the debounce time is + // configurable. + .debounceTime(debounceInterval); +} + +_.a(a) + /* very very very very very very very long such that it is longer than 80 columns */ + .a() + +_.a( + a +)/* very very very very very very very long such that it is longer than 80 columns */ +.a(); + +_.a( + a +) /* very very very very very very very long such that it is longer than 80 columns */.a(); + +Something + // $FlowFixMe(>=0.41.0) + .getInstance(this.props.dao) + .getters() + +// Warm-up first +measure() + .then(() => { + SomethingLong(); + }); + +measure() // Warm-up first + .then(() => { + SomethingLong(); + }); + +const configModel = this.baseConfigurationService.getCache().consolidated // global/default values (do NOT modify) + .merge(this.cachedWorkspaceConfig); + +this.doWriteConfiguration(target, value, options) // queue up writes to prevent race conditions + .then(() => null, + error => { + return options.donotNotifyError ? TPromise.wrapError(error) : this.onError(error, target, value); + }); + +ret = __DEV__ ? + // $FlowFixMe: this type differs according to the env +vm.runInContext(source, ctx) +: a + +angular.module('AngularAppModule') + // Hello, I am comment. + .constant('API_URL', 'http://localhost:8080/api'); + +=====================================output===================================== +function f() { + return ( + observableFromSubscribeFunction() + // Debounce manually rather than using editor.onDidStopChanging so that the debounce time is + // configurable. + .debounceTime( debounceInterval ) + ); +} + +_.a( a ) + /* very very very very very very very long such that it is longer than 80 columns */ + .a(); + +_.a( + a +) /* very very very very very very very long such that it is longer than 80 columns */ + .a(); + +_.a( + a +) /* very very very very very very very long such that it is longer than 80 columns */ + .a(); + +Something + // $FlowFixMe(>=0.41.0) + .getInstance( this.props.dao ) + .getters(); + +// Warm-up first +measure().then( () => { + SomethingLong(); +} ); + +measure() // Warm-up first + .then( () => { + SomethingLong(); + } ); + +const configModel = this.baseConfigurationService + .getCache() + .consolidated // global/default values (do NOT modify) + .merge( this.cachedWorkspaceConfig ); + +this.doWriteConfiguration( target, value, options ) // queue up writes to prevent race conditions + .then( + () => null, + error => { + return options.donotNotifyError + ? TPromise.wrapError( error ) + : this.onError( error, target, value ); + } + ); + +ret = __DEV__ + ? // $FlowFixMe: this type differs according to the env + vm.runInContext( source, ctx ) + : a; + +angular + .module( "AngularAppModule" ) + // Hello, I am comment. + .constant( "API_URL", "http://localhost:8080/api" ); + +================================================================================ +`; + +exports[`complex-args.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +client.execute( + Post.selectAll() + .where(Post.id.eq(42)) + .where(Post.published.eq(true)) +); + +=====================================output===================================== +client.execute( + Post.selectAll().where( Post.id.eq( 42 ) ).where( Post.published.eq( true ) ) +); + +================================================================================ +`; + +exports[`computed.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +nock(/test/) + .matchHeader('Accept', 'application/json') + [httpMethodNock(method)]('/foo') + .reply(200, { + foo: 'bar', + }); + +=====================================output===================================== +nock( /test/ ) + .matchHeader( "Accept", "application/json" ) + [ httpMethodNock( method ) ]( "/foo" ) + .reply( 200, { + foo: "bar", + } ); + +================================================================================ +`; + +exports[`computed-merge.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +[].forEach(key => { + data[key]('foo') + .then(() => console.log('bar')) + .catch(() => console.log('baz')); +}); + +[].forEach(key => { + data('foo') + [key]('bar') + .then(() => console.log('bar')) + .catch(() => console.log('baz')); +}); + +window.Data[key]("foo") + .then(() => a) + .catch(() => b); + +=====================================output===================================== +[].forEach( key => { + data[ key ]( "foo" ) + .then( () => console.log( "bar" ) ) + .catch( () => console.log( "baz" ) ); +} ); + +[].forEach( key => { + data( "foo" ) + [ key ]( "bar" ) + .then( () => console.log( "bar" ) ) + .catch( () => console.log( "baz" ) ); +} ); + +window.Data[ key ]( "foo" ) + .then( () => a ) + .catch( () => b ); + +================================================================================ +`; + +exports[`conditional.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +(a ? b : c).d(); + +(a ? b : c).d().e(); + +(a ? b : c).d().e().f(); + +(valid + ? helper.responseBody(this.currentUser) + : helper.responseBody(this.defaultUser)) +.map(); + +(valid + ? helper.responseBody(this.currentUser) + : helper.responseBody(this.defaultUser)) +.map().filter(); + +(valid + ? helper.responseBody(this.currentUser) + : helper.responseBody(defaultUser)) +.map(); + +object[valid + ? helper.responseBody(this.currentUser) + : helper.responseBody(defaultUser)] +.map(); + +=====================================output===================================== +( a ? b : c ).d(); + +( a ? b : c ).d().e(); + +( a ? b : c ).d().e().f(); + +( valid + ? helper.responseBody( this.currentUser ) + : helper.responseBody( this.defaultUser ) +).map(); + +( valid + ? helper.responseBody( this.currentUser ) + : helper.responseBody( this.defaultUser ) +) + .map() + .filter(); + +( valid + ? helper.responseBody( this.currentUser ) + : helper.responseBody( defaultUser ) +).map(); + +object[ + valid + ? helper.responseBody( this.currentUser ) + : helper.responseBody( defaultUser ) +].map(); + +================================================================================ +`; + +exports[`cypress.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +cy.get('option:first') + .should('be.selected') + .and('have.value', 'Metallica') + +cy.get(".ready") + .should("have.text", "FOO") + .should("have.css", "color", "#aaa"); + +=====================================output===================================== +cy.get( "option:first" ) + .should( "be.selected" ) + .and( "have.value", "Metallica" ); + +cy.get( ".ready" ) + .should( "have.text", "FOO" ) + .should( "have.css", "color", "#aaa" ); + +================================================================================ +`; + +exports[`d3.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +d3.select('body') + .append('circle') + .at({ width: 30, fill: '#f0f' }) + .st({ fontWeight: 600 }) + +const myScale = d3.scaleLinear() + .domain([1950, 1980]) + .range([0, width]) + +not.d3.select('body') + .append('circle') + .at({ width: 30, fill: '#f0f' }) + .st({ fontWeight: 600 }) + +not.d3.scaleLinear() + .domain([1950, 1980]) + .range([0, width]) + +=====================================output===================================== +d3.select( "body" ) + .append( "circle" ) + .at( { width: 30, fill: "#f0f" } ) + .st( { fontWeight: 600 } ); + +const myScale = d3.scaleLinear().domain( [ 1950, 1980 ] ).range( [ 0, width ] ); + +not.d3 + .select( "body" ) + .append( "circle" ) + .at( { width: 30, fill: "#f0f" } ) + .st( { fontWeight: 600 } ); + +not.d3.scaleLinear().domain( [ 1950, 1980 ] ).range( [ 0, width ] ); + +================================================================================ +`; + +exports[`first_long.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +export default function theFunction(action$, store) { + return action$.ofType(THE_ACTION).switchMap(action => Observable + .webSocket({ + url: THE_URL, + more: stuff(), + evenMore: stuff({ + value1: true, + value2: false, + value3: false + }) + }) + .filter(data => theFilter(data)) + .map(({ theType, ...data }) => theMap(theType, data)) + .retryWhen(errors => errors)); +} + +function f() { + return this._getWorker(workerOptions)({ + filePath, + hasteImplModulePath: this._options.hasteImplModulePath, + }).then( + metadata => { + // \`1\` for truthy values instead of \`true\` to save cache space. + fileMetadata[H.VISITED] = 1; + const metadataId = metadata.id; + const metadataModule = metadata.module; + if (metadataId && metadataModule) { + fileMetadata[H.ID] = metadataId; + setModule(metadataId, metadataModule); + } + fileMetadata[H.DEPENDENCIES] = metadata.dependencies || []; + } + ); +} + +=====================================output===================================== +export default function theFunction( action$, store ) { + return action$.ofType( THE_ACTION ).switchMap( action => + Observable.webSocket( { + url: THE_URL, + more: stuff(), + evenMore: stuff( { + value1: true, + value2: false, + value3: false, + } ), + } ) + .filter( data => theFilter( data ) ) + .map( ( { theType, ...data } ) => theMap( theType, data ) ) + .retryWhen( errors => errors ) + ); +} + +function f() { + return this._getWorker( workerOptions )( { + filePath, + hasteImplModulePath: this._options.hasteImplModulePath, + } ).then( metadata => { + // \`1\` for truthy values instead of \`true\` to save cache space. + fileMetadata[ H.VISITED ] = 1; + const metadataId = metadata.id; + const metadataModule = metadata.module; + if ( metadataId && metadataModule ) { + fileMetadata[ H.ID ] = metadataId; + setModule( metadataId, metadataModule ); + } + fileMetadata[ H.DEPENDENCIES ] = metadata.dependencies || []; + } ); +} + +================================================================================ +`; + +exports[`fluent-configuration.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +domain + .concept('Page') + .val('title', 'string') + .vals('widgets', 'Widget') +domain + .concept('Widget') + .val('title', 'string') + .val('color', 'Color') + .val('foo', 'Foo') + .val('bar', 'Bar') +domain + .concept('Widget') + .val('title', 'string') + .val('color', 'Color') +domain + .concept(CONCEPT_NAME) + .val('title') + .vals() + +=====================================output===================================== +domain.concept( "Page" ).val( "title", "string" ).vals( "widgets", "Widget" ); +domain + .concept( "Widget" ) + .val( "title", "string" ) + .val( "color", "Color" ) + .val( "foo", "Foo" ) + .val( "bar", "Bar" ); +domain.concept( "Widget" ).val( "title", "string" ).val( "color", "Color" ); +domain.concept( CONCEPT_NAME ).val( "title" ).vals(); + +================================================================================ +`; + +exports[`inline_merge.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +Object.keys( + availableLocales({ + test: true + }) +) +.forEach(locale => { + // ... +}); + +this.layoutPartsToHide = this.utils.hashset( + _.flatMap(this.visibilityHandlers, fn => fn()) + .concat(this.record.resolved_legacy_visrules) + .filter(Boolean) +); + +var jqxhr = $.ajax("example.php") + .done(doneFn) + .fail(failFn); + +=====================================output===================================== +Object.keys( + availableLocales( { + test: true, + } ) +).forEach( locale => { + // ... +} ); + +this.layoutPartsToHide = this.utils.hashset( + _.flatMap( this.visibilityHandlers, fn => fn() ) + .concat( this.record.resolved_legacy_visrules ) + .filter( Boolean ) +); + +var jqxhr = $.ajax( "example.php" ).done( doneFn ).fail( failFn ); + +================================================================================ +`; + +exports[`issue-3594.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +const fetched = fetch("/foo"); +fetched + .then(response => response.json()) + .then(json => processThings(json.data.things)); + +let column = new Column(null, conn) + .table(data.table) + .json(data.column); + +=====================================output===================================== +const fetched = fetch( "/foo" ); +fetched + .then( response => response.json() ) + .then( json => processThings( json.data.things ) ); + +let column = new Column( null, conn ).table( data.table ).json( data.column ); + +================================================================================ +`; + +exports[`issue-3621.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +const palindrome = str => { + const s = str.toLowerCase().replace(/[\\W_]/g, ''); + return s === s.split('').reverse().join(''); +}; + +const apiCurrencies = api().currencies().all() + +expect(cells.at(1).render().text()).toBe('link text1') +expect(cells.at(2).render().text()).toBe('link text2') +expect(cells.at(3).render().text()).toBe('link text3') +expect(cells.at(4).render().text()).toBe('link text4') + +=====================================output===================================== +const palindrome = str => { + const s = str.toLowerCase().replace( /[\\W_]/g, "" ); + return s === s.split( "" ).reverse().join( "" ); +}; + +const apiCurrencies = api().currencies().all(); + +expect( cells.at( 1 ).render().text() ).toBe( "link text1" ); +expect( cells.at( 2 ).render().text() ).toBe( "link text2" ); +expect( cells.at( 3 ).render().text() ).toBe( "link text3" ); +expect( cells.at( 4 ).render().text() ).toBe( "link text4" ); + +================================================================================ +`; + +exports[`issue-4125.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +// examples from https://github.com/prettier/prettier/issues/4125 + +const sha256 = (data) => crypto.createHash("sha256").update(data).digest("hex"); + +req.checkBody('id').isInt().optional(); +req.checkBody('name').notEmpty().optional(); + +const x = moment().add(1, 'day').valueOf() + +// should stay on one line: +const y = obj.foo(1).foo(2).foo(3); +const z = obj.foo(-1).foo(import('2')).foo(!x).check(/[A-Z]/); + +// better on multiple lines: +somePromise.then(format).then((val)=>doSomething(val)).catch((err)=>handleError(err)) + +// you can still force multi-line chaining with a comment: +const sha256_2 = (data) => + crypto // breakme + .createHash("sha256") + .update(data) + .digest("hex"); + +// examples from https://github.com/prettier/prettier/pull/4765 + +if ($(el).attr("href").includes("/wiki/")) { +} + +if ($(el).attr("href").includes("/wiki/")) { + if ($(el).attr("xyz").includes("/whatever/")) { + if ($(el).attr("hello").includes("/world/")) { + } + } +} + +const parseNumbers = s => s.split('').map(Number).sort() + +function palindrome(a, b) { + return a.slice().reverse().join(',') === b.slice().sort().join(','); +} + +// examples from https://github.com/prettier/prettier/issues/1565 + +d3.select("body").selectAll("p").data([1, 2, 3]).enter().style("color", "white"); + +Object.keys(props).filter(key => key in own === false).reduce((a, key) => { + a[key] = props[key]; + return a; +}, {}) + +point().x(4).y(3).z(6).plot(); + +assert.equal(this.$().text().trim(), '1000'); + +something().then(() => doSomethingElse()).then(result => dontForgetThisAsWell(result)) + +db.branch( + db.table('users').filter({ email }).count(), + db.table('users').filter({ email: 'a@b.com' }).count(), + db.table('users').insert({ email }), + db.table('users').filter({ email }), +) + +sandbox.stub(config, 'get').withArgs('env').returns('dev') + +const date = moment.utc(userInput).hour(0).minute(0).second(0) + +fetchUser(id) + .then(fetchAccountForUser) + .catch(handleFetchError) + +fetchUser(id) // + .then(fetchAccountForUser) + .catch(handleFetchError) + +// examples from https://github.com/prettier/prettier/issues/3107 + +function HelloWorld() { + window.FooClient.setVars({ + locale: getFooLocale({ page }), + authorizationToken: data.token, + }).initVerify('foo_container'); + + fejax.ajax({ + url: '/verification/', + dataType: 'json', + }).then( + (data) => { + this.setState({ isLoading: false }); + this.initWidget(data); + }, + (data) => { + this.logImpression('foo_fetch_error', data); + Flash.error(I18n.t('offline_identity.foo_issue')); + }, + ); +} + +action$.ofType(ActionTypes.SEARCHED_USERS) + .map(action => action.payload.query) + .filter(q => !!q) + .switchMap(q => + Observable.timer(800) // debounce + .takeUntil(action$.ofType(ActionTypes.CLEARED_SEARCH_RESULTS)) + .mergeMap(() => + Observable.merge( + Observable.of(replace(\`?q=\${q}\`)), + ajax + .getJSON(\`https://api.github.com/search/users?q=\${q}\`) + .map(res => res.items) + .map(receiveUsers) + ) + ) + ); + +window.FooClient + .setVars({ + locale: getFooLocale({ page }), + authorizationToken: data.token, + }) + .initVerify('foo_container'); + +it('gets triggered by mouseenter', () => { + const wrapper = shallow(); + wrapper.dive().find(Button).prop(); +}); + +const a1 = x.a(true).b(null).c(123) +const a2 = x.d('').e(\`\`).f(g) +const a3 = x.d('').e(\`\${123}\`).f(g) +const a4 = x.h(i.j).k(l()).m([n, o]) +class X { + y() { + const j = x.a(this).b(super.cde()).f(/g/).h(new i()).j(); + } +} + +// should break when call expressions get complex +x.a().b([c, [d, [e]]]).f() +x.a().b(c(d(e()))).f() +x.a().b(\`\${c(d())}\`).f() + +xyz.a().b().c(a(a(b(c(d().p).p).p).p)) + +var l = base + .replace(/^\\w*:\\/\\//, '') + .replace(/\\/$/, '') + .split('/').length + + +=====================================output===================================== +// examples from https://github.com/prettier/prettier/issues/4125 + +const sha256 = data => + crypto.createHash( "sha256" ).update( data ).digest( "hex" ); + +req.checkBody( "id" ).isInt().optional(); +req.checkBody( "name" ).notEmpty().optional(); + +const x = moment().add( 1, "day" ).valueOf(); + +// should stay on one line: +const y = obj.foo( 1 ).foo( 2 ).foo( 3 ); +const z = obj.foo( - 1 ).foo( import( "2" ) ).foo( ! x ).check( /[A-Z]/ ); + +// better on multiple lines: +somePromise + .then( format ) + .then( val => doSomething( val ) ) + .catch( err => handleError( err ) ); + +// you can still force multi-line chaining with a comment: +const sha256_2 = data => + crypto // breakme + .createHash( "sha256" ) + .update( data ) + .digest( "hex" ); + +// examples from https://github.com/prettier/prettier/pull/4765 + +if ( $( el ).attr( "href" ).includes( "/wiki/" ) ) { +} + +if ( $( el ).attr( "href" ).includes( "/wiki/" ) ) { + if ( $( el ).attr( "xyz" ).includes( "/whatever/" ) ) { + if ( $( el ).attr( "hello" ).includes( "/world/" ) ) { + } + } +} + +const parseNumbers = s => s.split( "" ).map( Number ).sort(); + +function palindrome( a, b ) { + return a.slice().reverse().join( "," ) === b.slice().sort().join( "," ); +} + +// examples from https://github.com/prettier/prettier/issues/1565 + +d3.select( "body" ) + .selectAll( "p" ) + .data( [ 1, 2, 3 ] ) + .enter() + .style( "color", "white" ); + +Object.keys( props ) + .filter( key => key in own === false ) + .reduce( ( a, key ) => { + a[ key ] = props[ key ]; + return a; + }, {} ); + +point().x( 4 ).y( 3 ).z( 6 ).plot(); + +assert.equal( this.$().text().trim(), "1000" ); + +something() + .then( () => doSomethingElse() ) + .then( result => dontForgetThisAsWell( result ) ); + +db.branch( + db.table( "users" ).filter( { email } ).count(), + db.table( "users" ).filter( { email: "a@b.com" } ).count(), + db.table( "users" ).insert( { email } ), + db.table( "users" ).filter( { email } ) +); + +sandbox.stub( config, "get" ).withArgs( "env" ).returns( "dev" ); + +const date = moment.utc( userInput ).hour( 0 ).minute( 0 ).second( 0 ); + +fetchUser( id ).then( fetchAccountForUser ).catch( handleFetchError ); + +fetchUser( id ) // + .then( fetchAccountForUser ) + .catch( handleFetchError ); + +// examples from https://github.com/prettier/prettier/issues/3107 + +function HelloWorld() { + window.FooClient.setVars( { + locale: getFooLocale( { page } ), + authorizationToken: data.token, + } ).initVerify( "foo_container" ); + + fejax + .ajax( { + url: "/verification/", + dataType: "json", + } ) + .then( + data => { + this.setState( { isLoading: false } ); + this.initWidget( data ); + }, + data => { + this.logImpression( "foo_fetch_error", data ); + Flash.error( I18n.t( "offline_identity.foo_issue" ) ); + } + ); +} + +action$ + .ofType( ActionTypes.SEARCHED_USERS ) + .map( action => action.payload.query ) + .filter( q => !! q ) + .switchMap( q => + Observable.timer( 800 ) // debounce + .takeUntil( action$.ofType( ActionTypes.CLEARED_SEARCH_RESULTS ) ) + .mergeMap( () => + Observable.merge( + Observable.of( replace( \`?q=\${q}\` ) ), + ajax + .getJSON( \`https://api.github.com/search/users?q=\${q}\` ) + .map( res => res.items ) + .map( receiveUsers ) + ) + ) + ); + +window.FooClient.setVars( { + locale: getFooLocale( { page } ), + authorizationToken: data.token, +} ).initVerify( "foo_container" ); + +it( "gets triggered by mouseenter", () => { + const wrapper = shallow( ); + wrapper.dive().find( Button ).prop(); +} ); + +const a1 = x.a( true ).b( null ).c( 123 ); +const a2 = x.d( "" ).e( \`\` ).f( g ); +const a3 = x.d( "" ).e( \`\${ 123 }\` ).f( g ); +const a4 = x.h( i.j ).k( l() ).m( [ n, o ] ); +class X { + y() { + const j = x.a( this ).b( super.cde() ).f( /g/ ).h( new i() ).j(); + } +} + +// should break when call expressions get complex +x.a() + .b( [ c, [ d, [ e ] ] ] ) + .f(); +x.a() + .b( c( d( e() ) ) ) + .f(); +x.a() + .b( \`\${ c( d() ) }\` ) + .f(); + +xyz + .a() + .b() + .c( a( a( b( c( d().p ).p ).p ).p ) ); + +var l = base + .replace( /^\\w*:\\/\\//, "" ) + .replace( /\\/$/, "" ) + .split( "/" ).length; + +================================================================================ +`; + +exports[`logical.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +const someLongVariableName = (idx( + this.props, + props => props.someLongPropertyName +) || [] +).map(edge => edge.node); + +(veryLongVeryLongVeryLong || e).map(tickets => + TicketRecord.createFromSomeLongString()); + +(veryLongVeryLongVeryLong || e).map(tickets => + TicketRecord.createFromSomeLongString()).filter(obj => !!obj); + +(veryLongVeryLongVeryLong || anotherVeryLongVeryLongVeryLong || veryVeryVeryLongError).map(tickets => + TicketRecord.createFromSomeLongString()); + +(veryLongVeryLongVeryLong || anotherVeryLongVeryLongVeryLong || veryVeryVeryLongError).map(tickets => + TicketRecord.createFromSomeLongString()).filter(obj => !!obj); + +=====================================output===================================== +const someLongVariableName = ( + idx( this.props, props => props.someLongPropertyName ) || [] +).map( edge => edge.node ); + +( veryLongVeryLongVeryLong || e ).map( tickets => + TicketRecord.createFromSomeLongString() +); + +( veryLongVeryLongVeryLong || e ) + .map( tickets => TicketRecord.createFromSomeLongString() ) + .filter( obj => !! obj ); + +( + veryLongVeryLongVeryLong || + anotherVeryLongVeryLongVeryLong || + veryVeryVeryLongError +).map( tickets => TicketRecord.createFromSomeLongString() ); + +( + veryLongVeryLongVeryLong || + anotherVeryLongVeryLongVeryLong || + veryVeryVeryLongError +) + .map( tickets => TicketRecord.createFromSomeLongString() ) + .filter( obj => !! obj ); + +================================================================================ +`; + +exports[`multiple-members.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +if (testConfig.ENABLE_ONLINE_TESTS === "true") { + describe("POST /users/me/pet", function() { + it("saves pet", function() { + function assert(pet) { + expect(pet).to.have.property("OwnerAddress").that.deep.equals({ + AddressLine1: "Alexanderstrasse", + AddressLine2: "", + PostalCode: "10999", + Region: "Berlin", + City: "Berlin", + Country: "DE" + }); + } + }); + }); +} + +wrapper.find('SomewhatLongNodeName').prop('longPropFunctionName')().then(function() { + doSomething(); +}); + +wrapper.find('SomewhatLongNodeName').prop('longPropFunctionName')('argument').then(function() { + doSomething(); +}); + +wrapper.find('SomewhatLongNodeName').prop('longPropFunctionName', 'second argument that pushes this group past 80 characters')('argument').then(function() { + doSomething(); +}); + +wrapper.find('SomewhatLongNodeName').prop('longPropFunctionName')('argument', 'second argument that pushes this group past 80 characters').then(function() { + doSomething(); +}); + +=====================================output===================================== +if ( testConfig.ENABLE_ONLINE_TESTS === "true" ) { + describe( "POST /users/me/pet", function () { + it( "saves pet", function () { + function assert( pet ) { + expect( pet ).to.have.property( "OwnerAddress" ).that.deep.equals( { + AddressLine1: "Alexanderstrasse", + AddressLine2: "", + PostalCode: "10999", + Region: "Berlin", + City: "Berlin", + Country: "DE", + } ); + } + } ); + } ); +} + +wrapper + .find( "SomewhatLongNodeName" ) + .prop( "longPropFunctionName" )() + .then( function () { + doSomething(); + } ); + +wrapper + .find( "SomewhatLongNodeName" ) + .prop( "longPropFunctionName" )( "argument" ) + .then( function () { + doSomething(); + } ); + +wrapper + .find( "SomewhatLongNodeName" ) + .prop( + "longPropFunctionName", + "second argument that pushes this group past 80 characters" + )( "argument" ) + .then( function () { + doSomething(); + } ); + +wrapper + .find( "SomewhatLongNodeName" ) + .prop( "longPropFunctionName" )( + "argument", + "second argument that pushes this group past 80 characters" + ) + .then( function () { + doSomething(); + } ); + +================================================================================ +`; + +exports[`object-literal.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +of("test") + .pipe(throwIfEmpty()) + .subscribe({ + error(err) { + thrown = err; + } + }); + +of("test") + .pipe(throwIfEmpty()) + .subscribe({ + get foo() { + bar(); + } + }); + +=====================================output===================================== +of( "test" ) + .pipe( throwIfEmpty() ) + .subscribe( { + error( err ) { + thrown = err; + }, + } ); + +of( "test" ) + .pipe( throwIfEmpty() ) + .subscribe( { + get foo() { + bar(); + }, + } ); + +================================================================================ +`; + +exports[`pr-7889.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +const Profile = view.with({ name: (state) => state.name }).as((props) => ( +
+

Hello, {props.name}

+
+)) + +const Profile2 = view.with({ name }).as((props) => ( +
+

Hello, {props.name}

+
+)) + +=====================================output===================================== +const Profile = view.with( { name: state => state.name } ).as( props => ( +
+

Hello, { props.name }

+
+) ); + +const Profile2 = view.with( { name } ).as( props => ( +
+

Hello, { props.name }

+
+) ); + +================================================================================ +`; + +exports[`short-names.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +const svgJsFiles = fs + .readdirSync(svgDir) + .filter(f => svgJsFileExtRegex.test(f)) + .map(f => path.join(svgDir, f)); + +=====================================output===================================== +const svgJsFiles = fs + .readdirSync( svgDir ) + .filter( f => svgJsFileExtRegex.test( f ) ) + .map( f => path.join( svgDir, f ) ); + +================================================================================ +`; + +exports[`simple-args.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +const fieldsToSend = _(["id", extra]).without("transition").uniq(); + +console.log(values.filter(isValid).map(extractId).slice(-5, -1)); + +=====================================output===================================== +const fieldsToSend = _( [ "id", extra ] ).without( "transition" ).uniq(); + +console.log( values.filter( isValid ).map( extractId ).slice( - 5, - 1 ) ); + +================================================================================ +`; + +exports[`square_0.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +const version = someLongString + .split('jest version =') + .pop() + .split(EOL)[0] + .trim(); + +const component = find('.org-lclp-edit-copy-url-banner__link')[0] + .getAttribute('href') + .indexOf(this.landingPageLink); + +=====================================output===================================== +const version = someLongString + .split( "jest version =" ) + .pop() + .split( EOL )[ 0 ] + .trim(); + +const component = find( ".org-lclp-edit-copy-url-banner__link" )[ 0 ] + .getAttribute( "href" ) + .indexOf( this.landingPageLink ); + +================================================================================ +`; + +exports[`test.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +method().then(x => x) + ["abc"](x => x) + [abc](x => x); + +({}.a().b()); +({}).a().b(); + +=====================================output===================================== +method() + .then( x => x ) + [ "abc" ]( x => x ) + [ abc ]( x => x ); + +( {}.a().b() ); +( {}.a().b() ); + +================================================================================ +`; + +exports[`this.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +const sel = this.connections + .concat(this.activities.concat(this.operators)) + .filter(x => x.selected); + +=====================================output===================================== +const sel = this.connections + .concat( this.activities.concat( this.operators ) ) + .filter( x => x.selected ); + +================================================================================ +`; diff --git a/tests/format/js/method-chain/with-inner-spacing/jsfmt.spec.js b/tests/format/js/method-chain/with-inner-spacing/jsfmt.spec.js new file mode 100644 index 0000000000..b54dbc4098 --- /dev/null +++ b/tests/format/js/method-chain/with-inner-spacing/jsfmt.spec.js @@ -0,0 +1,17 @@ +// [prettierx] test script notice: +// This test script runs for test files in parent directory, +// **not** on any files in *this* directory. + +const dirPath = `${__dirname}/..`; + +run_spec(dirPath, ["babel", "babel-flow", "flow", "typescript"], { + // [prettierx] recommended setting with --paren-spacing + arrowParens: "avoid", + // [prettierx] test with --paren-spacing + spaceInParens: true, + arrayBracketSpacing: true, + computedPropertySpacing: true, + spaceUnaryOps: true, + templateCurlySpacing: true, + typeAngleBracketSpacing: true, +}); diff --git a/tests/format/js/no-indent-chains/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/no-indent-chains/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..6f6ff86e45 --- /dev/null +++ b/tests/format/js/no-indent-chains/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,111 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`member-chain.js - {"indentChains":false,"arrowParens":"avoid"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +indentChains: false +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +foo.doSomething("Hello World").doAnotherThing("Foo", { foo: bar }) + // App configuration. + .doOneMoreThing(config) + .run(() => console.log("Bar")); + +bigDeal + .doSomething("Hello World") + + // Hello world + .doAnotherThing("Foo", { foo: bar }) + + // App configuration. + .doOneMoreThing(config) + + .run(() => console.log("Bar")); + + +bar.baz + .doSomething("Hello World") + + // Hello world + .foo.bar.doAnotherThing("Foo", { foo: bar }) + + .doOneMoreThing(config) + .bar.run(() => console.log("Bar")); + +( + somethingGood ? thisIsIt : maybeNot +) + // Hello world + .doSomething("Hello World") + .doAnotherThing("Foo", { foo: bar }) // Run this + .run(() => console.log("Bar")); // Do this + +helloWorld + .text() + .then(t => t); + +(veryLongVeryLongVeryLong || + anotherVeryLongVeryLongVeryLong || + veryVeryVeryLongError +) + .map(tickets => TicketRecord.createFromSomeLongString()) + + .filter(obj => Boolean(obj)); + +const sel = this.connections + .concat(this.activities.concat(this.operators)) + .filter(x => x.selected); + +=====================================output===================================== +foo +.doSomething("Hello World") +.doAnotherThing("Foo", { foo: bar }) +// App configuration. +.doOneMoreThing(config) +.run(() => console.log("Bar")); + +bigDeal +.doSomething("Hello World") + +// Hello world +.doAnotherThing("Foo", { foo: bar }) + +// App configuration. +.doOneMoreThing(config) + +.run(() => console.log("Bar")); + +bar.baz +.doSomething("Hello World") + +// Hello world +.foo.bar.doAnotherThing("Foo", { foo: bar }) + +.doOneMoreThing(config) +.bar.run(() => console.log("Bar")); + +(somethingGood ? thisIsIt : maybeNot) +// Hello world +.doSomething("Hello World") +.doAnotherThing("Foo", { foo: bar }) // Run this +.run(() => console.log("Bar")); // Do this + +helloWorld.text().then(t => t); + +( + veryLongVeryLongVeryLong || + anotherVeryLongVeryLongVeryLong || + veryVeryVeryLongError +) +.map(tickets => TicketRecord.createFromSomeLongString()) + +.filter(obj => Boolean(obj)); + +const sel = this.connections +.concat(this.activities.concat(this.operators)) +.filter(x => x.selected); + +================================================================================ +`; diff --git a/tests/format/js/no-indent-chains/jsfmt.spec.js b/tests/format/js/no-indent-chains/jsfmt.spec.js new file mode 100644 index 0000000000..1c2c8603e8 --- /dev/null +++ b/tests/format/js/no-indent-chains/jsfmt.spec.js @@ -0,0 +1,5 @@ +run_spec(__dirname, ["babel", "babel-flow", "flow", "typescript"], { + indentChains: false, + // recommended: + arrowParens: "avoid", +}); diff --git a/tests/format/js/no-indent-chains/member-chain.js b/tests/format/js/no-indent-chains/member-chain.js new file mode 100644 index 0000000000..5a6d0d9f4b --- /dev/null +++ b/tests/format/js/no-indent-chains/member-chain.js @@ -0,0 +1,49 @@ +foo.doSomething("Hello World").doAnotherThing("Foo", { foo: bar }) + // App configuration. + .doOneMoreThing(config) + .run(() => console.log("Bar")); + +bigDeal + .doSomething("Hello World") + + // Hello world + .doAnotherThing("Foo", { foo: bar }) + + // App configuration. + .doOneMoreThing(config) + + .run(() => console.log("Bar")); + + +bar.baz + .doSomething("Hello World") + + // Hello world + .foo.bar.doAnotherThing("Foo", { foo: bar }) + + .doOneMoreThing(config) + .bar.run(() => console.log("Bar")); + +( + somethingGood ? thisIsIt : maybeNot +) + // Hello world + .doSomething("Hello World") + .doAnotherThing("Foo", { foo: bar }) // Run this + .run(() => console.log("Bar")); // Do this + +helloWorld + .text() + .then(t => t); + +(veryLongVeryLongVeryLong || + anotherVeryLongVeryLongVeryLong || + veryVeryVeryLongError +) + .map(tickets => TicketRecord.createFromSomeLongString()) + + .filter(obj => Boolean(obj)); + +const sel = this.connections + .concat(this.activities.concat(this.operators)) + .filter(x => x.selected); diff --git a/tests/format/js/no-indent-chains/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/no-indent-chains/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..aa058cdeb6 --- /dev/null +++ b/tests/format/js/no-indent-chains/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,113 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`member-chain.js - {"indentChains":false,"spaceInParens":true,"spaceUnaryOps":true,"arrowParens":"avoid"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +indentChains: false +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true + | printWidth +=====================================input====================================== +foo.doSomething("Hello World").doAnotherThing("Foo", { foo: bar }) + // App configuration. + .doOneMoreThing(config) + .run(() => console.log("Bar")); + +bigDeal + .doSomething("Hello World") + + // Hello world + .doAnotherThing("Foo", { foo: bar }) + + // App configuration. + .doOneMoreThing(config) + + .run(() => console.log("Bar")); + + +bar.baz + .doSomething("Hello World") + + // Hello world + .foo.bar.doAnotherThing("Foo", { foo: bar }) + + .doOneMoreThing(config) + .bar.run(() => console.log("Bar")); + +( + somethingGood ? thisIsIt : maybeNot +) + // Hello world + .doSomething("Hello World") + .doAnotherThing("Foo", { foo: bar }) // Run this + .run(() => console.log("Bar")); // Do this + +helloWorld + .text() + .then(t => t); + +(veryLongVeryLongVeryLong || + anotherVeryLongVeryLongVeryLong || + veryVeryVeryLongError +) + .map(tickets => TicketRecord.createFromSomeLongString()) + + .filter(obj => Boolean(obj)); + +const sel = this.connections + .concat(this.activities.concat(this.operators)) + .filter(x => x.selected); + +=====================================output===================================== +foo +.doSomething( "Hello World" ) +.doAnotherThing( "Foo", { foo: bar } ) +// App configuration. +.doOneMoreThing( config ) +.run( () => console.log( "Bar" ) ); + +bigDeal +.doSomething( "Hello World" ) + +// Hello world +.doAnotherThing( "Foo", { foo: bar } ) + +// App configuration. +.doOneMoreThing( config ) + +.run( () => console.log( "Bar" ) ); + +bar.baz +.doSomething( "Hello World" ) + +// Hello world +.foo.bar.doAnotherThing( "Foo", { foo: bar } ) + +.doOneMoreThing( config ) +.bar.run( () => console.log( "Bar" ) ); + +( somethingGood ? thisIsIt : maybeNot ) +// Hello world +.doSomething( "Hello World" ) +.doAnotherThing( "Foo", { foo: bar } ) // Run this +.run( () => console.log( "Bar" ) ); // Do this + +helloWorld.text().then( t => t ); + +( + veryLongVeryLongVeryLong || + anotherVeryLongVeryLongVeryLong || + veryVeryVeryLongError +) +.map( tickets => TicketRecord.createFromSomeLongString() ) + +.filter( obj => Boolean( obj ) ); + +const sel = this.connections +.concat( this.activities.concat( this.operators ) ) +.filter( x => x.selected ); + +================================================================================ +`; diff --git a/tests/format/js/no-indent-chains/with-inner-spacing/jsfmt.spec.js b/tests/format/js/no-indent-chains/with-inner-spacing/jsfmt.spec.js new file mode 100644 index 0000000000..a9d40bb31c --- /dev/null +++ b/tests/format/js/no-indent-chains/with-inner-spacing/jsfmt.spec.js @@ -0,0 +1,13 @@ +// [prettierx] test script notice: +// This test script runs for test files in parent directory, +// **not** on any files in *this* directory. + +const dirPath = `${__dirname}/..`; + +run_spec(dirPath, ["babel", "babel-flow", "flow", "typescript"], { + indentChains: false, + spaceInParens: true, + spaceUnaryOps: true, + // recommended: + arrowParens: "avoid", +}); diff --git a/tests/format/js/no-semi/additional-member-expressions/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/no-semi/additional-member-expressions/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..7a8bfaa547 --- /dev/null +++ b/tests/format/js/no-semi/additional-member-expressions/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,40 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`member-expressions.js - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +semi: false + | printWidth +=====================================input====================================== +// asi with MemberExpression & BinaryExpression: +x ; (a + b).c + +// asi with MemberExpression & LogicalExpression: +x ; (a || b).c + +// no asi: +x ; ab.c + +// asi with MemberExpression, computed property & BinaryExpression: +x ; (a + b)[c] + +=====================================output===================================== +// asi with MemberExpression & BinaryExpression: +x +;(a + b).c + +// asi with MemberExpression & LogicalExpression: +x +;(a || b).c + +// no asi: +x +ab.c + +// asi with MemberExpression, computed property & BinaryExpression: +x +;(a + b)[c] + +================================================================================ +`; diff --git a/tests/format/js/no-semi/additional-member-expressions/jsfmt.spec.js b/tests/format/js/no-semi/additional-member-expressions/jsfmt.spec.js new file mode 100644 index 0000000000..34ea90a5b0 --- /dev/null +++ b/tests/format/js/no-semi/additional-member-expressions/jsfmt.spec.js @@ -0,0 +1,3 @@ +run_spec(__dirname, ["babel", "babel-flow", "flow", "typescript"], { + semi: false, +}); diff --git a/tests/format/js/no-semi/additional-member-expressions/member-expressions.js b/tests/format/js/no-semi/additional-member-expressions/member-expressions.js new file mode 100644 index 0000000000..65429b5d71 --- /dev/null +++ b/tests/format/js/no-semi/additional-member-expressions/member-expressions.js @@ -0,0 +1,11 @@ +// asi with MemberExpression & BinaryExpression: +x ; (a + b).c + +// asi with MemberExpression & LogicalExpression: +x ; (a || b).c + +// no asi: +x ; ab.c + +// asi with MemberExpression, computed property & BinaryExpression: +x ; (a + b)[c] diff --git a/tests/format/js/space-before-function-paren/eslint-compat/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/space-before-function-paren/eslint-compat/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..93790ffd0b --- /dev/null +++ b/tests/format/js/space-before-function-paren/eslint-compat/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,152 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`eslint.js - {"spaceBeforeFunctionParen":true,"trailingComma":"none"} format 1`] = ` +====================================options===================================== +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceBeforeFunctionParen: true +trailingComma: "none" + | printWidth +=====================================input====================================== +/*eslint space-before-function-paren: "error"*/ +/*eslint-env es6*/ + +function foo() { + // ... +} + +var bar = function() { + // ... +}; + +var bar = function foo() { + // ... +}; + +class Foo { + constructor() { + // ... + } + bar() { + // ... + } +} + +var foo = { + bar() { + // ... + } +}; + +var foo = async() => 1 + +=====================================output===================================== +/*eslint space-before-function-paren: "error"*/ +/*eslint-env es6*/ + +function foo () { + // ... +} + +var bar = function () { + // ... +}; + +var bar = function foo () { + // ... +}; + +class Foo { + constructor () { + // ... + } + bar () { + // ... + } +} + +var foo = { + bar () { + // ... + } +}; + +var foo = async () => 1; + +================================================================================ +`; + +exports[`eslint.js - {"trailingComma":"none"} format 1`] = ` +====================================options===================================== +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" + | printWidth +=====================================input====================================== +/*eslint space-before-function-paren: "error"*/ +/*eslint-env es6*/ + +function foo() { + // ... +} + +var bar = function() { + // ... +}; + +var bar = function foo() { + // ... +}; + +class Foo { + constructor() { + // ... + } + bar() { + // ... + } +} + +var foo = { + bar() { + // ... + } +}; + +var foo = async() => 1 + +=====================================output===================================== +/*eslint space-before-function-paren: "error"*/ +/*eslint-env es6*/ + +function foo() { + // ... +} + +var bar = function () { + // ... +}; + +var bar = function foo() { + // ... +}; + +class Foo { + constructor() { + // ... + } + bar() { + // ... + } +} + +var foo = { + bar() { + // ... + } +}; + +var foo = async () => 1; + +================================================================================ +`; diff --git a/tests/format/js/space-before-function-paren/eslint-compat/eslint.js b/tests/format/js/space-before-function-paren/eslint-compat/eslint.js new file mode 100644 index 0000000000..d77c43bb35 --- /dev/null +++ b/tests/format/js/space-before-function-paren/eslint-compat/eslint.js @@ -0,0 +1,31 @@ +/*eslint space-before-function-paren: "error"*/ +/*eslint-env es6*/ + +function foo() { + // ... +} + +var bar = function() { + // ... +}; + +var bar = function foo() { + // ... +}; + +class Foo { + constructor() { + // ... + } + bar() { + // ... + } +} + +var foo = { + bar() { + // ... + } +}; + +var foo = async() => 1 diff --git a/tests/format/js/space-before-function-paren/eslint-compat/jsfmt.spec.js b/tests/format/js/space-before-function-paren/eslint-compat/jsfmt.spec.js new file mode 100644 index 0000000000..08839af0ce --- /dev/null +++ b/tests/format/js/space-before-function-paren/eslint-compat/jsfmt.spec.js @@ -0,0 +1,9 @@ +run_spec(__dirname, ["babel", "babel-flow", "flow", "typescript"], { + // "Standard JS": + spaceBeforeFunctionParen: true, + trailingComma: "none", +}); +run_spec(__dirname, ["babel", "babel-flow", "flow", "typescript"], { + // "Standard JS": + trailingComma: "none", +}); diff --git a/tests/format/js/space-before-function-paren/tslint-compat/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/space-before-function-paren/tslint-compat/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..2937880131 --- /dev/null +++ b/tests/format/js/space-before-function-paren/tslint-compat/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,240 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`tsbaz.ts - {"spaceBeforeFunctionParen":true,"trailingComma":"none"} format 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 +spaceBeforeFunctionParen: true +trailingComma: "none" + | printWidth +=====================================input====================================== +// Results of using spaceBeforeFunctionParen: true setting +// should match results of using the following +// tslint rule (with one exception marked): +// "space-before-function-paren": [true, "always"] +// (with no rules from "tslint:recommended") + +function foo() { + // ... +} + +var bar = function() { + // ... +}; + +var bar = function foo() { + // ... +}; + +function baz(a: T) { + // ... +} + +// tslint seems to miss this one: +var baz = function(a: T) { + // ... +}; + +var baz = function foo(a: T) { + // ... +}; + +class Foo { + constructor() { + // ... + } + public bar() { + // ... + } + public baz(a: T) { + // ... + } +} + +var foo = { + bar() { + // ... + }, + baz(a: T) { + // ... + } +}; + +var foo = async() => 1; + +=====================================output===================================== +// Results of using spaceBeforeFunctionParen: true setting +// should match results of using the following +// tslint rule (with one exception marked): +// "space-before-function-paren": [true, "always"] +// (with no rules from "tslint:recommended") + +function foo () { + // ... +} + +var bar = function () { + // ... +}; + +var bar = function foo () { + // ... +}; + +function baz (a: T) { + // ... +} + +// tslint seems to miss this one: +var baz = function (a: T) { + // ... +}; + +var baz = function foo (a: T) { + // ... +}; + +class Foo { + constructor () { + // ... + } + public bar () { + // ... + } + public baz (a: T) { + // ... + } +} + +var foo = { + bar () { + // ... + }, + baz (a: T) { + // ... + } +}; + +var foo = async () => 1; + +================================================================================ +`; + +exports[`tsbaz.ts - {"trailingComma":"none"} format 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 +trailingComma: "none" + | printWidth +=====================================input====================================== +// Results of using spaceBeforeFunctionParen: true setting +// should match results of using the following +// tslint rule (with one exception marked): +// "space-before-function-paren": [true, "always"] +// (with no rules from "tslint:recommended") + +function foo() { + // ... +} + +var bar = function() { + // ... +}; + +var bar = function foo() { + // ... +}; + +function baz(a: T) { + // ... +} + +// tslint seems to miss this one: +var baz = function(a: T) { + // ... +}; + +var baz = function foo(a: T) { + // ... +}; + +class Foo { + constructor() { + // ... + } + public bar() { + // ... + } + public baz(a: T) { + // ... + } +} + +var foo = { + bar() { + // ... + }, + baz(a: T) { + // ... + } +}; + +var foo = async() => 1; + +=====================================output===================================== +// Results of using spaceBeforeFunctionParen: true setting +// should match results of using the following +// tslint rule (with one exception marked): +// "space-before-function-paren": [true, "always"] +// (with no rules from "tslint:recommended") + +function foo() { + // ... +} + +var bar = function () { + // ... +}; + +var bar = function foo() { + // ... +}; + +function baz(a: T) { + // ... +} + +// tslint seems to miss this one: +var baz = function (a: T) { + // ... +}; + +var baz = function foo(a: T) { + // ... +}; + +class Foo { + constructor() { + // ... + } + public bar() { + // ... + } + public baz(a: T) { + // ... + } +} + +var foo = { + bar() { + // ... + }, + baz(a: T) { + // ... + } +}; + +var foo = async () => 1; + +================================================================================ +`; diff --git a/tests/format/js/space-before-function-paren/tslint-compat/jsfmt.spec.js b/tests/format/js/space-before-function-paren/tslint-compat/jsfmt.spec.js new file mode 100644 index 0000000000..432ee2d489 --- /dev/null +++ b/tests/format/js/space-before-function-paren/tslint-compat/jsfmt.spec.js @@ -0,0 +1,10 @@ +run_spec(__dirname, ["typescript"], { + // "Standard JS": + spaceBeforeFunctionParen: true, + trailingComma: "none", +}); + +run_spec(__dirname, ["typescript"], { + // "Standard JS": + trailingComma: "none", +}); diff --git a/tests/format/js/space-before-function-paren/tslint-compat/tsbaz.ts b/tests/format/js/space-before-function-paren/tslint-compat/tsbaz.ts new file mode 100644 index 0000000000..fac9641fde --- /dev/null +++ b/tests/format/js/space-before-function-paren/tslint-compat/tsbaz.ts @@ -0,0 +1,53 @@ +// Results of using spaceBeforeFunctionParen: true setting +// should match results of using the following +// tslint rule (with one exception marked): +// "space-before-function-paren": [true, "always"] +// (with no rules from "tslint:recommended") + +function foo() { + // ... +} + +var bar = function() { + // ... +}; + +var bar = function foo() { + // ... +}; + +function baz(a: T) { + // ... +} + +// tslint seems to miss this one: +var baz = function(a: T) { + // ... +}; + +var baz = function foo(a: T) { + // ... +}; + +class Foo { + constructor() { + // ... + } + public bar() { + // ... + } + public baz(a: T) { + // ... + } +} + +var foo = { + bar() { + // ... + }, + baz(a: T) { + // ... + } +}; + +var foo = async() => 1; diff --git a/tests/format/js/space-before-function-paren/tslint-compat/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/space-before-function-paren/tslint-compat/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..052dd721a1 --- /dev/null +++ b/tests/format/js/space-before-function-paren/tslint-compat/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,244 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`tsbaz.ts - {"spaceInParens":true,"typeAngleBracketSpacing":true,"spaceBeforeFunctionParen":true,"trailingComma":"none"} format 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 +spaceBeforeFunctionParen: true +spaceInParens: true +trailingComma: "none" +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +// Results of using spaceBeforeFunctionParen: true setting +// should match results of using the following +// tslint rule (with one exception marked): +// "space-before-function-paren": [true, "always"] +// (with no rules from "tslint:recommended") + +function foo() { + // ... +} + +var bar = function() { + // ... +}; + +var bar = function foo() { + // ... +}; + +function baz(a: T) { + // ... +} + +// tslint seems to miss this one: +var baz = function(a: T) { + // ... +}; + +var baz = function foo(a: T) { + // ... +}; + +class Foo { + constructor() { + // ... + } + public bar() { + // ... + } + public baz(a: T) { + // ... + } +} + +var foo = { + bar() { + // ... + }, + baz(a: T) { + // ... + } +}; + +var foo = async() => 1; + +=====================================output===================================== +// Results of using spaceBeforeFunctionParen: true setting +// should match results of using the following +// tslint rule (with one exception marked): +// "space-before-function-paren": [true, "always"] +// (with no rules from "tslint:recommended") + +function foo () { + // ... +} + +var bar = function () { + // ... +}; + +var bar = function foo () { + // ... +}; + +function baz< T > ( a: T ) { + // ... +} + +// tslint seems to miss this one: +var baz = function < T > ( a: T ) { + // ... +}; + +var baz = function foo< T > ( a: T ) { + // ... +}; + +class Foo { + constructor () { + // ... + } + public bar () { + // ... + } + public baz< T > ( a: T ) { + // ... + } +} + +var foo = { + bar () { + // ... + }, + baz< T > ( a: T ) { + // ... + } +}; + +var foo = async () => 1; + +================================================================================ +`; + +exports[`tsbaz.ts - {"spaceInParens":true,"typeAngleBracketSpacing":true,"trailingComma":"none"} format 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 +spaceInParens: true +trailingComma: "none" +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +// Results of using spaceBeforeFunctionParen: true setting +// should match results of using the following +// tslint rule (with one exception marked): +// "space-before-function-paren": [true, "always"] +// (with no rules from "tslint:recommended") + +function foo() { + // ... +} + +var bar = function() { + // ... +}; + +var bar = function foo() { + // ... +}; + +function baz(a: T) { + // ... +} + +// tslint seems to miss this one: +var baz = function(a: T) { + // ... +}; + +var baz = function foo(a: T) { + // ... +}; + +class Foo { + constructor() { + // ... + } + public bar() { + // ... + } + public baz(a: T) { + // ... + } +} + +var foo = { + bar() { + // ... + }, + baz(a: T) { + // ... + } +}; + +var foo = async() => 1; + +=====================================output===================================== +// Results of using spaceBeforeFunctionParen: true setting +// should match results of using the following +// tslint rule (with one exception marked): +// "space-before-function-paren": [true, "always"] +// (with no rules from "tslint:recommended") + +function foo() { + // ... +} + +var bar = function () { + // ... +}; + +var bar = function foo() { + // ... +}; + +function baz< T >( a: T ) { + // ... +} + +// tslint seems to miss this one: +var baz = function < T >( a: T ) { + // ... +}; + +var baz = function foo< T >( a: T ) { + // ... +}; + +class Foo { + constructor() { + // ... + } + public bar() { + // ... + } + public baz< T >( a: T ) { + // ... + } +} + +var foo = { + bar() { + // ... + }, + baz< T >( a: T ) { + // ... + } +}; + +var foo = async () => 1; + +================================================================================ +`; diff --git a/tests/format/js/space-before-function-paren/tslint-compat/with-inner-spacing/jsfmt.spec.js b/tests/format/js/space-before-function-paren/tslint-compat/with-inner-spacing/jsfmt.spec.js new file mode 100644 index 0000000000..b94ded0130 --- /dev/null +++ b/tests/format/js/space-before-function-paren/tslint-compat/with-inner-spacing/jsfmt.spec.js @@ -0,0 +1,20 @@ +// [prettierx] test script notice: +// This test script runs for test files in parent directory, +// **not** on any files in *this* directory. + +const dirPath = `${__dirname}/..`; + +run_spec(dirPath, ["typescript"], { + spaceInParens: true, + typeAngleBracketSpacing: true, + // "Standard JS": + spaceBeforeFunctionParen: true, + trailingComma: "none", +}); + +run_spec(dirPath, ["typescript"], { + spaceInParens: true, + typeAngleBracketSpacing: true, + // "Standard JS": + trailingComma: "none", +}); diff --git a/tests/format/js/standard/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/standard/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..78c3574441 --- /dev/null +++ b/tests/format/js/standard/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,2172 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`correct.js - {"endOfLine":"lf","yieldStarSpacing":true,"generatorStarSpacing":true,"offsetTernaryExpressions":true,"spaceBeforeFunctionParen":true,"singleQuote":true,"jsxSingleQuote":true,"semi":false,"trailingComma":"none","arrowParens":"avoid"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +endOfLine: "lf" +generatorStarSpacing: true +jsxSingleQuote: true +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +semi: false +singleQuote: true +spaceBeforeFunctionParen: true +trailingComma: "none" +yieldStarSpacing: true + | printWidth +=====================================input====================================== +// Needs to be at the top but belongs to object-curly-spacing +import { fooA } from 'bar' + +// Needs to be at the top but belongs to indent rule +import { + foosjdfhalsjkdhflasjdhfajashdlfjahsdlfjashdlfjaksdsadfaso, + barsjdfhalsjkdhflasjdhfajashdlfjahsdlfjashdlfjaksdsadfaso, + bazsjdfhalsjkdhflasjdhfajashdlfjahsdlfjashdlfjaksdsadfaso +} from 'qux' + +// "arrow-spacing": ["error", { "before": true, "after": true }] +a => {} +;() => {} +a => a +;() => { + '\\n' +} + +// "block-spacing": [ "error", "always" ], +function foo () { + return true +} +if (foo) { + bar = 0 +} + +// "brace-style": [ "error", "1tbs", { "allowSingleLine": true } ], +function foo1 () { + return true +} +if (foo) { + bar() +} +if (foo) { + bar() +} else { + baz() +} +try { + somethingRisky() +} catch (e) { + handleError() +} + +// "comma-spacing": [ "error", { "before": false, "after": true } ], +var fooB = 1 +var baz = 3 +var arr = [1, 2] +var arr = [1, , 3] +var obj = { foo: 'bar', baz: 'qur' } +foo(a, b) +new Foo(a, b) +function foo2 (a, b) {} +a, b + +// "eol-last": "error", +// cannot be tested here, but true (Unix-style new lines) + +// "func-call-spacing": [ "error", "never" ], +fn() + +// "generator-star-spacing": [ "error", { "before": true, "after": true } ], +function * generator1 () {} +var anonymous = function * () {} +var shorthand = { * generator () {} } +class Example { + async * foo () {} +} + +// "indent": [ +// "error", +// 2, +// { +// "SwitchCase": 1, +// "VariableDeclarator": 1, +// "outerIIFEBody": 1, +// "MemberExpression": 1, +// "FunctionDeclaration": { "parameters": 1, "body": 1 }, +// "FunctionExpression": { "parameters": 1, "body": 1 }, +// "CallExpression": { "arguments": 1 }, +// "ArrayExpression": 1, +// "ObjectExpression": 1, +// "ImportDeclaration": 1, +// "flatTernaryExpressions": false, +// "ignoreComments": false +// } +// ], + +switch (a) { + case 'a': + break + case 'b': + break +} + +var aajshdfaljskdhflakjshdflkjashdlfjkhasldkjfhlasjkdfhlaskjdhfalsjkdfha1, + bajshdfaljskdhflakjshdflkjashdlfjkhasldkjfhlasjkdfhlaskjdhfalsjkdfha2, + bajshdfaljskdhflakjshdflkjashdlfjkhasldkjfhlasjkdfhlaskjdhfalsjkdfha3 +let aajshdfaljskdhflakjshdflkjashdlfjkhasldkjfhlasjkdfhlaskjdhfalsjkdfha4, + bajshdfaljskdhflakjshdflkjashdlfjkhasldkjfhlasjkdfhlaskjdhfalsjkdfha5, + bajshdfaljskdhflakjshdflkjashdlfjkhasldkjfhlasjkdfhlaskjdhfalsjkdfha6 +const a = 1 +const b = 2 +const c = 3 +;(function () { + function foo (x) { + return x + 1 + } +})() +if (y) { + console.log('foo') +} +function foo3 ( + barverylongverylongverylongverylongverylongverylongverylongverylong, + bazverylongverylongverylongverylongverylongverylongverylongverylong, + quxverylongverylongverylongverylongverylongverylongverylongverylong +) { + qux() +} +foo( + barverylongverylongverylongverylongverylongverylongverylongverylong, + bazverylongverylongverylongverylongverylongverylongverylongverylong, + quxverylongverylongverylongverylongverylongverylongverylongverylong +) +var fooC = [ + barverylongverylongverylongverylongverylongverylongverylongverylong, + bazverylongverylongverylongverylongverylongverylongverylongverylong, + quxverylongverylongverylongverylongverylongverylongverylongverylong +] +var fooD = { + barverylongverylongverylongverylongverylongverylongverylongverylong: 1, + bazverylongverylongverylongverylongverylongverylongverylongverylong: 2, + quxverylongverylongverylongverylongverylongverylongverylongverylong: 3 +} +var d = barverylongverylongverylongverylongverylongverylongverylongverylong + ? bar + : barverylongverylongverylongverylongverylongverylongverylongverylong + +// "key-spacing": [ "error", { "beforeColon": false, "afterColon": true } ], +var obj = { foo: 42 } + +// "keyword-spacing": [ "error", { "before": true, "after": true } ], +if (foo) { + // ... +} else if (bar) { + // ... +} else { + // ... +} + +// "no-multi-spaces": "error", +var e = 1 +if (foo === 'bar') { +} +a << b +var arr = [1, 2] +a ? b : c + +// "no-multiple-empty-lines": [ "error", { "max": 1, "maxEOF": 0 } ], +// cannot be tested here, but true + +// "no-trailing-spaces": "error", +// cannot be tested here, but true + +// "no-whitespace-before-property": "error", +foo.bar +foo[bar] +foo.bar.baz +foo.bar().baz() + +// "object-curly-spacing": [ "error", "always" ], +var obj = {} +var obj = { foo: 'bar' } +var obj = { foo: { bar: 'baz' }, qux: 'quxx' } +var obj = { + foo: 'bar' +} +var { destructured } = destructure + +// "object-property-newline": [ "error", { "allowMultiplePropertiesPerLine": true } ], +const obj1 = { foo: 'foo', bar: 'bar' } +const obj2 = { + foo: 'foo', + bar: 'bar', + baz: 'baz' +} +const user = process.argv[2] +const obj3 = { + user, + [process.argv[3] ? 'foo' : 'bar']: 0, + baz: [1, 2, 4, 8] +} + +// "padded-blocks": [ "error", { "blocks": "never", "switches": "never", "classes": "never" } ], +if (a) { + b() +} +if (a) { + b() +} +class A { + constructor () { + // ... + } +} +switch (a) { + case 0: + foo() +} + +// "rest-spread-spacing": [ "error", "never" ], +fn(...args) +function fn (...args) { + console.log(args) +} +let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 } +let n = { x, y, ...z } + +// "semi-spacing": [ "error", { "before": false, "after": true } ], +for (;;) {} + +// "space-before-blocks": [ "error", "always" ], +if (a) { + b() +} +if (a) { + b() +} else { + c() +} +function a1 () {} +for (;;) { + b() +} +try { +} catch (a) {} + +// "space-before-function-paren": [ "error", "always" ], +function foo4 () { + // ... +} + +var bar = function () { + // ... +} + +var bar = function foo () { + // ... +} + +class Foo { + constructor () { + // ... + } + + get foo () { + // ... + } + + set bar (param) { + // ... + } +} + +var foo5 = { + bar () { + // ... + } +} + +var foo6 = async () => 1 + +// "space-in-parens": [ "error", "never" ], +foo() + +foo('bar') + +var foo7 = (1 + 2) * 3 +;(function () { + return 'bar' +})() + +// "space-infix-ops": "error", +a + b +a + b +a ? b : c +const aB = { b: 1 } +var { d = 0 } = bar +function foo8 (a = 0) {} + +// "space-unary-ops": [ "error", { "words": true, "nonwords": false } ], +delete foo.bar +new Foo() +void 0 +;-foo +;+'3' +++foo +foo-- + +// "spaced-comment": [ +// "error", +// "always", +// { +// "line": { "markers": [ "*package", "!", "/", ",", "=" ] }, +// "block": { +// "balanced": true, +// "markers": [ "*package", "!", ",", ":", "::", "flow-include" ], +// "exceptions": [ "*" ] +// } +// } +// ], + +/* eslint spaced-comment: ["error", "always"] */ +// This is a comment with a whitespace at the beginning +/* This is a comment with a whitespace at the beginning */ +/* + * This is a comment with a whitespace at the beginning + */ +/* +This comment has a newline +*/ + +// "template-curly-spacing": [ "error", "never" ], +;\`hello, \${people.name}!\` +;\`hello, \${ + people.name.some.long.property.that.cannot.fit.in[80].characters.limit.for + .prettier +}!\` + +// "template-tag-spacing": [ "error", "never" ], +func\`Hello world\` + +// "unicode-bom": [ "error", "never" ], +var abc + +// "yield-star-spacing": [ "error", "both" ] +function * generator2 () { + yield * other() +} + +// "jsx-quotes": ["error", "prefer-single"], +;() =>
+ +=====================================output===================================== +// Needs to be at the top but belongs to object-curly-spacing +import { fooA } from 'bar' + +// Needs to be at the top but belongs to indent rule +import { + foosjdfhalsjkdhflasjdhfajashdlfjahsdlfjashdlfjaksdsadfaso, + barsjdfhalsjkdhflasjdhfajashdlfjahsdlfjashdlfjaksdsadfaso, + bazsjdfhalsjkdhflasjdhfajashdlfjahsdlfjashdlfjaksdsadfaso +} from 'qux' + +// "arrow-spacing": ["error", { "before": true, "after": true }] +a => {} +;() => {} +a => a +;() => { + '\\n' +} + +// "block-spacing": [ "error", "always" ], +function foo () { + return true +} +if (foo) { + bar = 0 +} + +// "brace-style": [ "error", "1tbs", { "allowSingleLine": true } ], +function foo1 () { + return true +} +if (foo) { + bar() +} +if (foo) { + bar() +} else { + baz() +} +try { + somethingRisky() +} catch (e) { + handleError() +} + +// "comma-spacing": [ "error", { "before": false, "after": true } ], +var fooB = 1 +var baz = 3 +var arr = [1, 2] +var arr = [1, , 3] +var obj = { foo: 'bar', baz: 'qur' } +foo(a, b) +new Foo(a, b) +function foo2 (a, b) {} +a, b + +// "eol-last": "error", +// cannot be tested here, but true (Unix-style new lines) + +// "func-call-spacing": [ "error", "never" ], +fn() + +// "generator-star-spacing": [ "error", { "before": true, "after": true } ], +function * generator1 () {} +var anonymous = function * () {} +var shorthand = { * generator () {} } +class Example { + async * foo () {} +} + +// "indent": [ +// "error", +// 2, +// { +// "SwitchCase": 1, +// "VariableDeclarator": 1, +// "outerIIFEBody": 1, +// "MemberExpression": 1, +// "FunctionDeclaration": { "parameters": 1, "body": 1 }, +// "FunctionExpression": { "parameters": 1, "body": 1 }, +// "CallExpression": { "arguments": 1 }, +// "ArrayExpression": 1, +// "ObjectExpression": 1, +// "ImportDeclaration": 1, +// "flatTernaryExpressions": false, +// "ignoreComments": false +// } +// ], + +switch (a) { + case 'a': + break + case 'b': + break +} + +var aajshdfaljskdhflakjshdflkjashdlfjkhasldkjfhlasjkdfhlaskjdhfalsjkdfha1, + bajshdfaljskdhflakjshdflkjashdlfjkhasldkjfhlasjkdfhlaskjdhfalsjkdfha2, + bajshdfaljskdhflakjshdflkjashdlfjkhasldkjfhlasjkdfhlaskjdhfalsjkdfha3 +let aajshdfaljskdhflakjshdflkjashdlfjkhasldkjfhlasjkdfhlaskjdhfalsjkdfha4, + bajshdfaljskdhflakjshdflkjashdlfjkhasldkjfhlasjkdfhlaskjdhfalsjkdfha5, + bajshdfaljskdhflakjshdflkjashdlfjkhasldkjfhlasjkdfhlaskjdhfalsjkdfha6 +const a = 1 +const b = 2 +const c = 3 +;(function () { + function foo (x) { + return x + 1 + } +})() +if (y) { + console.log('foo') +} +function foo3 ( + barverylongverylongverylongverylongverylongverylongverylongverylong, + bazverylongverylongverylongverylongverylongverylongverylongverylong, + quxverylongverylongverylongverylongverylongverylongverylongverylong +) { + qux() +} +foo( + barverylongverylongverylongverylongverylongverylongverylongverylong, + bazverylongverylongverylongverylongverylongverylongverylongverylong, + quxverylongverylongverylongverylongverylongverylongverylongverylong +) +var fooC = [ + barverylongverylongverylongverylongverylongverylongverylongverylong, + bazverylongverylongverylongverylongverylongverylongverylongverylong, + quxverylongverylongverylongverylongverylongverylongverylongverylong +] +var fooD = { + barverylongverylongverylongverylongverylongverylongverylongverylong: 1, + bazverylongverylongverylongverylongverylongverylongverylongverylong: 2, + quxverylongverylongverylongverylongverylongverylongverylongverylong: 3 +} +var d = barverylongverylongverylongverylongverylongverylongverylongverylong + ? bar + : barverylongverylongverylongverylongverylongverylongverylongverylong + +// "key-spacing": [ "error", { "beforeColon": false, "afterColon": true } ], +var obj = { foo: 42 } + +// "keyword-spacing": [ "error", { "before": true, "after": true } ], +if (foo) { + // ... +} else if (bar) { + // ... +} else { + // ... +} + +// "no-multi-spaces": "error", +var e = 1 +if (foo === 'bar') { +} +a << b +var arr = [1, 2] +a ? b : c + +// "no-multiple-empty-lines": [ "error", { "max": 1, "maxEOF": 0 } ], +// cannot be tested here, but true + +// "no-trailing-spaces": "error", +// cannot be tested here, but true + +// "no-whitespace-before-property": "error", +foo.bar +foo[bar] +foo.bar.baz +foo.bar().baz() + +// "object-curly-spacing": [ "error", "always" ], +var obj = {} +var obj = { foo: 'bar' } +var obj = { foo: { bar: 'baz' }, qux: 'quxx' } +var obj = { + foo: 'bar' +} +var { destructured } = destructure + +// "object-property-newline": [ "error", { "allowMultiplePropertiesPerLine": true } ], +const obj1 = { foo: 'foo', bar: 'bar' } +const obj2 = { + foo: 'foo', + bar: 'bar', + baz: 'baz' +} +const user = process.argv[2] +const obj3 = { + user, + [process.argv[3] ? 'foo' : 'bar']: 0, + baz: [1, 2, 4, 8] +} + +// "padded-blocks": [ "error", { "blocks": "never", "switches": "never", "classes": "never" } ], +if (a) { + b() +} +if (a) { + b() +} +class A { + constructor () { + // ... + } +} +switch (a) { + case 0: + foo() +} + +// "rest-spread-spacing": [ "error", "never" ], +fn(...args) +function fn (...args) { + console.log(args) +} +let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 } +let n = { x, y, ...z } + +// "semi-spacing": [ "error", { "before": false, "after": true } ], +for (;;) {} + +// "space-before-blocks": [ "error", "always" ], +if (a) { + b() +} +if (a) { + b() +} else { + c() +} +function a1 () {} +for (;;) { + b() +} +try { +} catch (a) {} + +// "space-before-function-paren": [ "error", "always" ], +function foo4 () { + // ... +} + +var bar = function () { + // ... +} + +var bar = function foo () { + // ... +} + +class Foo { + constructor () { + // ... + } + + get foo () { + // ... + } + + set bar (param) { + // ... + } +} + +var foo5 = { + bar () { + // ... + } +} + +var foo6 = async () => 1 + +// "space-in-parens": [ "error", "never" ], +foo() + +foo('bar') + +var foo7 = (1 + 2) * 3 +;(function () { + return 'bar' +})() + +// "space-infix-ops": "error", +a + b +a + b +a ? b : c +const aB = { b: 1 } +var { d = 0 } = bar +function foo8 (a = 0) {} + +// "space-unary-ops": [ "error", { "words": true, "nonwords": false } ], +delete foo.bar +new Foo() +void 0 +;-foo +;+'3' +++foo +foo-- + +// "spaced-comment": [ +// "error", +// "always", +// { +// "line": { "markers": [ "*package", "!", "/", ",", "=" ] }, +// "block": { +// "balanced": true, +// "markers": [ "*package", "!", ",", ":", "::", "flow-include" ], +// "exceptions": [ "*" ] +// } +// } +// ], + +/* eslint spaced-comment: ["error", "always"] */ +// This is a comment with a whitespace at the beginning +/* This is a comment with a whitespace at the beginning */ +/* + * This is a comment with a whitespace at the beginning + */ +/* +This comment has a newline +*/ + +// "template-curly-spacing": [ "error", "never" ], +;\`hello, \${people.name}!\` +;\`hello, \${people.name.some.long.property.that.cannot.fit.in[80].characters.limit.for.prettier}!\` + +// "template-tag-spacing": [ "error", "never" ], +func\`Hello world\` + +// "unicode-bom": [ "error", "never" ], +var abc + +// "yield-star-spacing": [ "error", "both" ] +function * generator2 () { + yield * other() +} + +// "jsx-quotes": ["error", "prefer-single"], +;() =>
+ +================================================================================ +`; + +exports[`correct-ternaries.js - {"endOfLine":"lf","yieldStarSpacing":true,"generatorStarSpacing":true,"offsetTernaryExpressions":true,"spaceBeforeFunctionParen":true,"singleQuote":true,"jsxSingleQuote":true,"semi":false,"trailingComma":"none","arrowParens":"avoid"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +endOfLine: "lf" +generatorStarSpacing: true +jsxSingleQuote: true +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +semi: false +singleQuote: true +spaceBeforeFunctionParen: true +trailingComma: "none" +yieldStarSpacing: true + | printWidth +=====================================input====================================== +/* eslint-disable no-undef, no-unused-vars, no-redefine, no-unused-expressions, + no-constant-condition, eqeqeq, react/jsx-no-undef */ +/* + Add other cases for pure StandardJS style. +*/ + +const testingValue = [1, 2, 3, 4, 5] +const resultValue = Date.now() + +const tern1 = + testingValue[0] === resultValue + ? resultValue + : testingValue[1] === resultValue + ? testingValue + ? 1 + : 0 + : testingValue[2] === resultValue + ? resultValue + : 0 + +const tern2 = + testingValue[0] === 1 + ? { + foo: 1 + } + : resultValue + ? { + bar: 1 + } + : 0 + +const tern3 = + testingValue[0] === 1 + ? { foo: 1 } === {} + ? { + foo: 1, + bar: 2 + } + : 3 + : resultValue + ? { bar: 1 } + : tern2 + ? resultValue + : { + baz: resultValue + } + +// ============================================================================= +// ternaries: func-call.js 5 + +const fn = () => {} +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ? annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave +) + +// ternaries: nested.js 5 +let icecream = + what == 'cone' + ? (p) => (p ? \`here's your \${p} cone\` : \`just the empty cone for you\`) + : (p) => \`here's your \${p} \${what}\` + +a + ? literalline + : { + 123: 12 + } + ? line + : softline + +const message = + i % 3 === 0 && i % 5 === 0 + ? 'fizzbuzz' + : i % 3 === 0 + ? 'fizz' + : i % 5 === 0 + ? 'buzz' + : String(i) + +// ============================================================================= +// ternaries: parenthesis.js 5 + +debug ? (this.state.isVisible ? 'partially visible' : 'hidden') : null +debug + ? this.state.isVisible && somethingComplex + ? 'partially visible' + : 'hidden' + : null + +;(a) => + a + ? () => { + a + } + : () => { + a + } +;(a) => a || a +;(a) => + a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a + +// ============================================================================= +// ternaries: nested.js 5 + +const value = condition1 + ? value1 + : condition2 + ? value2 + : condition3 + ? value3 + : value4 + +// +/* eslint-disable quotes, semi, no-undef, no-unused-vars */ +// @ts-nocheck +// import React from 'react' + +const foo = ( + + className={ + 'match-achievement-medal-type type' + + (medals[0].record + ? '-record' + : medals[0].unique + ? '-unique' + : medals[0].type) + } + > + {medals[0].record + ? i18n('Record') + : medals[0].unique + ? i18n('Unique') + : medals[0].type === 0 + ? i18n('Silver') + : medals[0].type === 1 + ? i18n('Gold') + : medals[0].type === 2 + ? i18n('Platinum') + : i18n('Theme')} +
+) + +const StorybookLoader = ({ match }) => + match.params.storyId === 'button' ? ( + + ) : match.params.storyId === 'color' ? ( + + ) : match.params.storyId === 'typography' ? ( + + ) : match.params.storyId === 'loading' ? ( + + ) : match.params.storyId === 'deal-list' ? ( + + ) : ( + + {'Missing story book'} + + + + + ) + +=====================================output===================================== +/* eslint-disable no-undef, no-unused-vars, no-redefine, no-unused-expressions, + no-constant-condition, eqeqeq, react/jsx-no-undef */ +/* + Add other cases for pure StandardJS style. +*/ + +const testingValue = [1, 2, 3, 4, 5] +const resultValue = Date.now() + +const tern1 = + testingValue[0] === resultValue + ? resultValue + : testingValue[1] === resultValue + ? testingValue + ? 1 + : 0 + : testingValue[2] === resultValue + ? resultValue + : 0 + +const tern2 = + testingValue[0] === 1 + ? { + foo: 1 + } + : resultValue + ? { + bar: 1 + } + : 0 + +const tern3 = + testingValue[0] === 1 + ? { foo: 1 } === {} + ? { + foo: 1, + bar: 2 + } + : 3 + : resultValue + ? { bar: 1 } + : tern2 + ? resultValue + : { + baz: resultValue + } + +// ============================================================================= +// ternaries: func-call.js 5 + +const fn = () => {} +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ? annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave +) + +// ternaries: nested.js 5 +let icecream = + what == 'cone' + ? p => (p ? \`here's your \${p} cone\` : \`just the empty cone for you\`) + : p => \`here's your \${p} \${what}\` + +a + ? literalline + : { + 123: 12 + } + ? line + : softline + +const message = + i % 3 === 0 && i % 5 === 0 + ? 'fizzbuzz' + : i % 3 === 0 + ? 'fizz' + : i % 5 === 0 + ? 'buzz' + : String(i) + +// ============================================================================= +// ternaries: parenthesis.js 5 + +debug ? (this.state.isVisible ? 'partially visible' : 'hidden') : null +debug + ? this.state.isVisible && somethingComplex + ? 'partially visible' + : 'hidden' + : null +a => + a + ? () => { + a + } + : () => { + a + } +a => a || a +a => + a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a + +// ============================================================================= +// ternaries: nested.js 5 + +const value = condition1 + ? value1 + : condition2 + ? value2 + : condition3 + ? value3 + : value4 + +// +/* eslint-disable quotes, semi, no-undef, no-unused-vars */ +// @ts-nocheck +// import React from 'react' + +const foo = ( + + className={ + 'match-achievement-medal-type type' + + (medals[0].record + ? '-record' + : medals[0].unique + ? '-unique' + : medals[0].type) + } + > + {medals[0].record + ? i18n('Record') + : medals[0].unique + ? i18n('Unique') + : medals[0].type === 0 + ? i18n('Silver') + : medals[0].type === 1 + ? i18n('Gold') + : medals[0].type === 2 + ? i18n('Platinum') + : i18n('Theme')} +
+) + +const StorybookLoader = ({ match }) => + match.params.storyId === 'button' ? ( + + ) : match.params.storyId === 'color' ? ( + + ) : match.params.storyId === 'typography' ? ( + + ) : match.params.storyId === 'loading' ? ( + + ) : match.params.storyId === 'deal-list' ? ( + + ) : ( + + {'Missing story book'} + + + + + ) + +================================================================================ +`; + +exports[`incorrect.js - {"endOfLine":"lf","yieldStarSpacing":true,"generatorStarSpacing":true,"offsetTernaryExpressions":true,"spaceBeforeFunctionParen":true,"singleQuote":true,"jsxSingleQuote":true,"semi":false,"trailingComma":"none","arrowParens":"avoid"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +endOfLine: "lf" +generatorStarSpacing: true +jsxSingleQuote: true +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +semi: false +singleQuote: true +spaceBeforeFunctionParen: true +trailingComma: "none" +yieldStarSpacing: true + | printWidth +=====================================input====================================== +// "arrow-spacing": ["error", { "before": true, "after": true }] + +()=> {}; +() =>{}; +(a)=> {}; +(a) =>{}; +a =>a; +a=> a; +()=> {'\\n'}; +() =>{'\\n'}; + +// "block-spacing": [ "error", "always" ], + +function foo1() {return true;} +if (foo) { bar = 0;} +function baz() {let i = 0; + return i; +} + +// "brace-style": [ "error", "1tbs", { "allowSingleLine": true } ], + +function foo2() +{ + return true; +} + +if (foo) +{ + bar(); +} + +try +{ + somethingRisky(); +} catch(e) +{ + handleError(); +} + +if (foo) { + bar(); +} +else { + baz(); +} + +// "comma-spacing": [ "error", { "before": false, "after": true } ], + +var foo = 1 ,bar = 2; +var arr = [1 , 2]; +var obj = {"foo": "bar" ,"baz": "qur"}; +foo(a ,b); +new Foo(a ,b); +function foo3(a ,b){} +a ,b + +// "eol-last": "error", +// cannot be tested here, but true (Unix-style new lines) + +// "func-call-spacing": [ "error", "never" ], +fn (); + +fn +(); + +// "generator-star-spacing": [ "error", { "before": true, "after": true } ], + +function* generator1() {} +var anonymous = function* () {}; +var shorthand = { * generator() {} }; +function *generator2() {} +var anonymous = function *() {}; +var shorthand = { *generator() {} }; + + +// "indent": [ +// "error", +// 2, +// { +// "SwitchCase": 1, +// "VariableDeclarator": 1, +// "outerIIFEBody": 1, +// "MemberExpression": 1, +// "FunctionDeclaration": { "parameters": 1, "body": 1 }, +// "FunctionExpression": { "parameters": 1, "body": 1 }, +// "CallExpression": { "arguments": 1 }, +// "ArrayExpression": 1, +// "ObjectExpression": 1, +// "ImportDeclaration": 1, +// "flatTernaryExpressions": false, +// "ignoreComments": false +// } +// ], + +// "key-spacing": [ "error", { "beforeColon": false, "afterColon": true } ], + +var obj = { "foo" : 42 }; +var obj = { "foo":42 }; + +// "keyword-spacing": [ "error", { "before": true, "after": true } ], + +if (foo) { + //... +}else if (bar) { + //... +}else { + //... +} + +// "no-multi-spaces": "error", + +var a = 1; +if(foo === "bar") {} +a << b +var arr = [1, 2]; +a ? b: c + +// "no-multiple-empty-lines": [ "error", { "max": 1, "maxEOF": 0 } ], +// cannot be tested here, but true + +// "no-trailing-spaces": "error", +// cannot be tested here, but true + +// "no-whitespace-before-property": "error", + +foo [bar] +foo. bar +foo .bar +foo. bar. baz +foo. bar() + .baz() +foo + .bar(). baz() + +// "object-curly-spacing": [ "error", "always" ], + +var obj = {'foo': 'bar'}; +var obj = {'foo': 'bar' }; +var obj = { baz: {'foo': 'qux'}, bar}; +var obj = {baz: { 'foo': 'qux' }, bar}; +var obj = {'foo': 'bar' +}; +var obj = { + 'foo':'bar'}; +var {destructured} = destructure; +import {fooA } from 'bar'; + +// "object-property-newline": [ "error", { "allowMultiplePropertiesPerLine": true } ], + +const obj0 = { foo: "foo", bar: "bar", baz: "baz" }; +const obj1 = { + foo: "foo", bar: "bar", baz: "baz" +}; +const obj2 = { + foo: "foo", bar: "bar", + baz: "baz" +}; +const obj3 = { + [process.argv[3] ? "foo" : "bar"]: 0, baz: [ + 1, + 2, + 4, + 8 + ] +}; +const b = "antidisestablishmentarianistically"; +const c = "yugoslavyalılaştırabildiklerimizdenmişsiniz"; +const obj4 = {a, b}; +const domain = process.argv[4]; +const obj5 = { + foo: "foo", [ + domain.includes(":") ? "complexdomain" : "simpledomain" + ]: true}; + +// "padded-blocks": [ "error", { "blocks": "never", "switches": "never", "classes": "never" } ], + + +if (a) { + + b(); + +} + +if (a) +{ + + b(); + +} + +if (a) { + + b(); +} + +if (a) { + b(); + +} + +class A { + + constructor(){ + } + +} + +switch (a) { + + case 0: foo(); + +} + +// "rest-spread-spacing": [ "error", "never" ], + +fn(... args) +function fn(... args) { console.log(args); } +let { x, y, ... z } = { x: 1, y: 2, a: 3, b: 4 }; +let n = { x, y, ... z }; + +// "semi-spacing": [ "error", { "before": false, "after": true } ], + +var foo ; +var foo;var bar; +throw new Error("error") ; +while (a) { break ; } +for (i = 0 ; i < 10 ; i++) {} +for (i = 0;i < 10;i++) {} + +// "space-before-blocks": [ "error", "always" ], + +if (a){ + b(); +} + +function fnA(){} + +for (;;){ + b(); +} + +try {} catch(a){} + +class Foo{ + constructor(){} +} + +// "space-before-function-paren": [ "error", "always" ], + +function foo4() { + // ... +} + +var bar = function() { + // ... +}; + +var bar = function foo() { + // ... +}; + +class Foo2 { + constructor() { + // ... + } +} + +var foo = { + bar() { + // ... + } +}; + +var foo = async() => 1 + +// "space-in-parens": [ "error", "never" ], + +foo( 'bar'); +foo('bar' ); +foo( 'bar' ); + +var foo = ( 1 + 2 ) * 3; +( function () { return 'bar'; }() ); + +// "space-infix-ops": "error", + +a+b +a+ b +a +b +a?b:c +const d={b:1}; +var {a=0}=bar; +function foo5(a=0) { } + +// "space-unary-ops": [ "error", { "words": true, "nonwords": false } ], + +typeof!foo; +void{foo:0}; +new[foo][0]; +delete(foo.bar); +++ foo; +foo --; +- foo; ++ "3"; + +// "spaced-comment": [ +// "error", +// "always", +// { +// "line": { "markers": [ "*package", "!", "/", ",", "=" ] }, +// "block": { +// "balanced": true, +// "markers": [ "*package", "!", ",", ":", "::", "flow-include" ], +// "exceptions": [ "*" ] +// } +// } +// ], + +/*eslint spaced-comment: ["error", "always"]*/ +//This is a comment with no whitespace at the beginning +/*This is a comment with no whitespace at the beginning */ +/* eslint spaced-comment: ["error", "always", { "block": { "balanced": true } }] */ +/* This is a comment with whitespace at the beginning but not the end*/ + +// "template-curly-spacing": [ "error", "never" ], +// (blank line here causes issues with CI for some reason) +\`hello, \${ people.name}!\`; +\`hello, \${people.name }!\`; +\`hello, \${ people.name }!\`; + +// "template-tag-spacing": [ "error", "never" ], + +func \`Hello world\`; + +// "unicode-bom": [ "error", "never" ], + +U+FEFF +var abc; + +// "yield-star-spacing": [ "error", "both" ] + + +function *generator3() { + yield *other(); +} +function* generator4() { + yield* other(); +} +function*generator5() { + yield*other(); +} + +// "jsx-quotes": ["error", "prefer-single"], +;() =>
+ +// "indent": [ +// "error", +// 2, +// { +// "SwitchCase": 1, +// "VariableDeclarator": 1, +// "outerIIFEBody": 1, +// "MemberExpression": 1, +// "FunctionDeclaration": { "parameters": 1, "body": 1 }, +// "FunctionExpression": { "parameters": 1, "body": 1 }, +// "CallExpression": { "arguments": 1 }, +// "ArrayExpression": 1, +// "ObjectExpression": 1, +// "ImportDeclaration": 1, +// "flatTernaryExpressions": false, +// "ignoreComments": false +// } +// ], +let isSpace = false +const dress = isSpace ? { + spaceSuit: 3, + oxygenCylinders: 6 + } : { + shirts: 3, + paints: 3 + } + +=====================================output===================================== +// "arrow-spacing": ["error", { "before": true, "after": true }] + +;() => {} +;() => {} +a => {} +a => {} +a => a +a => a +;() => { + '\\n' +} +;() => { + '\\n' +} + +// "block-spacing": [ "error", "always" ], + +function foo1 () { + return true +} +if (foo) { + bar = 0 +} +function baz () { + let i = 0 + return i +} + +// "brace-style": [ "error", "1tbs", { "allowSingleLine": true } ], + +function foo2 () { + return true +} + +if (foo) { + bar() +} + +try { + somethingRisky() +} catch (e) { + handleError() +} + +if (foo) { + bar() +} else { + baz() +} + +// "comma-spacing": [ "error", { "before": false, "after": true } ], + +var foo = 1, + bar = 2 +var arr = [1, 2] +var obj = { foo: 'bar', baz: 'qur' } +foo(a, b) +new Foo(a, b) +function foo3 (a, b) {} +a, b + +// "eol-last": "error", +// cannot be tested here, but true (Unix-style new lines) + +// "func-call-spacing": [ "error", "never" ], +fn() + +fn() + +// "generator-star-spacing": [ "error", { "before": true, "after": true } ], + +function * generator1 () {} +var anonymous = function * () {} +var shorthand = { * generator () {} } +function * generator2 () {} +var anonymous = function * () {} +var shorthand = { * generator () {} } + +// "indent": [ +// "error", +// 2, +// { +// "SwitchCase": 1, +// "VariableDeclarator": 1, +// "outerIIFEBody": 1, +// "MemberExpression": 1, +// "FunctionDeclaration": { "parameters": 1, "body": 1 }, +// "FunctionExpression": { "parameters": 1, "body": 1 }, +// "CallExpression": { "arguments": 1 }, +// "ArrayExpression": 1, +// "ObjectExpression": 1, +// "ImportDeclaration": 1, +// "flatTernaryExpressions": false, +// "ignoreComments": false +// } +// ], + +// "key-spacing": [ "error", { "beforeColon": false, "afterColon": true } ], + +var obj = { foo: 42 } +var obj = { foo: 42 } + +// "keyword-spacing": [ "error", { "before": true, "after": true } ], + +if (foo) { + //... +} else if (bar) { + //... +} else { + //... +} + +// "no-multi-spaces": "error", + +var a = 1 +if (foo === 'bar') { +} +a << b +var arr = [1, 2] +a ? b : c + +// "no-multiple-empty-lines": [ "error", { "max": 1, "maxEOF": 0 } ], +// cannot be tested here, but true + +// "no-trailing-spaces": "error", +// cannot be tested here, but true + +// "no-whitespace-before-property": "error", + +foo[bar] +foo.bar +foo.bar +foo.bar.baz +foo.bar().baz() +foo.bar().baz() + +// "object-curly-spacing": [ "error", "always" ], + +var obj = { foo: 'bar' } +var obj = { foo: 'bar' } +var obj = { baz: { foo: 'qux' }, bar } +var obj = { baz: { foo: 'qux' }, bar } +var obj = { foo: 'bar' } +var obj = { + foo: 'bar' +} +var { destructured } = destructure +import { fooA } from 'bar' + +// "object-property-newline": [ "error", { "allowMultiplePropertiesPerLine": true } ], + +const obj0 = { foo: 'foo', bar: 'bar', baz: 'baz' } +const obj1 = { + foo: 'foo', + bar: 'bar', + baz: 'baz' +} +const obj2 = { + foo: 'foo', + bar: 'bar', + baz: 'baz' +} +const obj3 = { + [process.argv[3] ? 'foo' : 'bar']: 0, + baz: [1, 2, 4, 8] +} +const b = 'antidisestablishmentarianistically' +const c = 'yugoslavyalılaştırabildiklerimizdenmişsiniz' +const obj4 = { a, b } +const domain = process.argv[4] +const obj5 = { + foo: 'foo', + [domain.includes(':') ? 'complexdomain' : 'simpledomain']: true +} + +// "padded-blocks": [ "error", { "blocks": "never", "switches": "never", "classes": "never" } ], + +if (a) { + b() +} + +if (a) { + b() +} + +if (a) { + b() +} + +if (a) { + b() +} + +class A { + constructor () {} +} + +switch (a) { + case 0: + foo() +} + +// "rest-spread-spacing": [ "error", "never" ], + +fn(...args) +function fn (...args) { + console.log(args) +} +let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 } +let n = { x, y, ...z } + +// "semi-spacing": [ "error", { "before": false, "after": true } ], + +var foo +var foo +var bar +throw new Error('error') +while (a) { + break +} +for (i = 0; i < 10; i++) {} +for (i = 0; i < 10; i++) {} + +// "space-before-blocks": [ "error", "always" ], + +if (a) { + b() +} + +function fnA () {} + +for (;;) { + b() +} + +try { +} catch (a) {} + +class Foo { + constructor () {} +} + +// "space-before-function-paren": [ "error", "always" ], + +function foo4 () { + // ... +} + +var bar = function () { + // ... +} + +var bar = function foo () { + // ... +} + +class Foo2 { + constructor () { + // ... + } +} + +var foo = { + bar () { + // ... + } +} + +var foo = async () => 1 + +// "space-in-parens": [ "error", "never" ], + +foo('bar') +foo('bar') +foo('bar') + +var foo = (1 + 2) * 3 +;(function () { + return 'bar' +})() + +// "space-infix-ops": "error", + +a + b +a + b +a + b +a ? b : c +const d = { b: 1 } +var { a = 0 } = bar +function foo5 (a = 0) {} + +// "space-unary-ops": [ "error", { "words": true, "nonwords": false } ], + +typeof !foo +void { foo: 0 } +new [foo][0]() +delete foo.bar +++foo +foo-- +;-foo +;+'3' + +// "spaced-comment": [ +// "error", +// "always", +// { +// "line": { "markers": [ "*package", "!", "/", ",", "=" ] }, +// "block": { +// "balanced": true, +// "markers": [ "*package", "!", ",", ":", "::", "flow-include" ], +// "exceptions": [ "*" ] +// } +// } +// ], + +/*eslint spaced-comment: ["error", "always"]*/ +//This is a comment with no whitespace at the beginning +/*This is a comment with no whitespace at the beginning */ +/* eslint spaced-comment: ["error", "always", { "block": { "balanced": true } }] */ +/* This is a comment with whitespace at the beginning but not the end*/ + +// "template-curly-spacing": [ "error", "never" ], +// (blank line here causes issues with CI for some reason) +;\`hello, \${people.name}!\` +;\`hello, \${people.name}!\` +;\`hello, \${people.name}!\` + +// "template-tag-spacing": [ "error", "never" ], + +func\`Hello world\` + +// "unicode-bom": [ "error", "never" ], + +U + FEFF +var abc + +// "yield-star-spacing": [ "error", "both" ] + +function * generator3 () { + yield * other() +} +function * generator4 () { + yield * other() +} +function * generator5 () { + yield * other() +} + +// "jsx-quotes": ["error", "prefer-single"], +;() =>
+ +// "indent": [ +// "error", +// 2, +// { +// "SwitchCase": 1, +// "VariableDeclarator": 1, +// "outerIIFEBody": 1, +// "MemberExpression": 1, +// "FunctionDeclaration": { "parameters": 1, "body": 1 }, +// "FunctionExpression": { "parameters": 1, "body": 1 }, +// "CallExpression": { "arguments": 1 }, +// "ArrayExpression": 1, +// "ObjectExpression": 1, +// "ImportDeclaration": 1, +// "flatTernaryExpressions": false, +// "ignoreComments": false +// } +// ], +let isSpace = false +const dress = isSpace + ? { + spaceSuit: 3, + oxygenCylinders: 6 + } + : { + shirts: 3, + paints: 3 + } + +================================================================================ +`; + +exports[`incorrect-ternaries.js - {"endOfLine":"lf","yieldStarSpacing":true,"generatorStarSpacing":true,"offsetTernaryExpressions":true,"spaceBeforeFunctionParen":true,"singleQuote":true,"jsxSingleQuote":true,"semi":false,"trailingComma":"none","arrowParens":"avoid"} [babel-ts] format 1`] = ` +"Unexpected token, expected \\":\\" (45:34) + 43 | let icecream = what == \\"cone\\" + 44 | ? p => (p ? \`here's your \${p} cone\` : \`just the empty cone for you\`) +> 45 | : p => \`here's your \${p} \${what}\`; + | ^ + 46 | + 47 | a + 48 | ? literalline" +`; + +exports[`incorrect-ternaries.js - {"endOfLine":"lf","yieldStarSpacing":true,"generatorStarSpacing":true,"offsetTernaryExpressions":true,"spaceBeforeFunctionParen":true,"singleQuote":true,"jsxSingleQuote":true,"semi":false,"trailingComma":"none","arrowParens":"avoid"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +endOfLine: "lf" +generatorStarSpacing: true +jsxSingleQuote: true +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +semi: false +singleQuote: true +spaceBeforeFunctionParen: true +trailingComma: "none" +yieldStarSpacing: true + | printWidth +=====================================input====================================== +/* eslint-disable no-undef, no-unused-vars, no-redefine, no-unused-expressions, + no-constant-condition, eqeqeq, react/jsx-no-undef */ +/* + Add other cases for pure StandardJS style. +*/ + + +const testingValue = [1, 2, 3, 4, 5] +const resultValue = Date.now() + +const tern1 = testingValue[0] === resultValue? resultValue + : testingValue[1] === resultValue ? testingValue + ? 1 : 0 + :testingValue[2] === resultValue + ? resultValue : 0; + +const tern2 = + testingValue[0] === 1 ? { + foo: 1 + }: resultValue ? { + bar: 1} + :0; + + const tern3 = +testingValue[0] === 1 ? {foo:1} === {}? { + foo: 1, bar: 2} : 3 : resultValue ? {bar:1} : (tern2 ? resultValue : { + baz:resultValue}) + +// ============================================================================= +// ternaries: func-call.js 5 + +const fn = () => {} +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ? annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave +); + +// ternaries: nested.js 5 +let icecream = what == "cone" +? p => (p ? \`here's your \${p} cone\` : \`just the empty cone for you\`) +: p => \`here's your \${p} \${what}\`; + +a + ? literalline + : { + 123: 12 + } + ? line + : softline + +const message = + i % 3 === 0 && i % 5 === 0 + ? "fizzbuzz" + : i % 3 === 0 + ? "fizz" + : i % 5 === 0 + ? "buzz" + : String(i); + +// ============================================================================= +// ternaries: parenthesis.js 5 + +debug ? (this.state.isVisible ? "partially visible" : "hidden") : null; +debug + ? this.state.isVisible && somethingComplex + ? "partially visible" + : "hidden" + : null; + +a => + a + ? () => { + a; + } + : () => { + a; + } +a => (a||a); +a => + a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a; + +// ============================================================================= +// ternaries: nested.js 5 + +const value = condition1 ? value1 : condition2 ? value2 : condition3 ? value3 : value4; + +// +/* eslint-disable quotes, semi, no-undef, no-unused-vars */ +// @ts-nocheck +// import React from 'react' + +const foo = ( +
+ "match-achievement-medal-type type" + + (medals[0].record + ? "-record" + : medals[0].unique + ? "-unique" + : medals[0].type) + }> + {medals[0].record + ? i18n("Record") + : medals[0].unique + ? i18n("Unique") + : medals[0].type === 0 + ? i18n("Silver") + : medals[0].type === 1 + ? i18n("Gold") + : medals[0].type === 2 + ? i18n("Platinum") + : i18n("Theme")} +
+); + +const StorybookLoader = ({ match }) => + match.params.storyId === "button" ? ( + + ) : match.params.storyId === "color" ? ( + + ) : match.params.storyId === "typography" ? ( + + ) : match.params.storyId === "loading" ? ( + + ) : match.params.storyId === "deal-list" ? ( + + ) : ( + + {"Missing story book"} + + + + +); + +=====================================output===================================== +/* eslint-disable no-undef, no-unused-vars, no-redefine, no-unused-expressions, + no-constant-condition, eqeqeq, react/jsx-no-undef */ +/* + Add other cases for pure StandardJS style. +*/ + +const testingValue = [1, 2, 3, 4, 5] +const resultValue = Date.now() + +const tern1 = + testingValue[0] === resultValue + ? resultValue + : testingValue[1] === resultValue + ? testingValue + ? 1 + : 0 + : testingValue[2] === resultValue + ? resultValue + : 0 + +const tern2 = + testingValue[0] === 1 + ? { + foo: 1 + } + : resultValue + ? { + bar: 1 + } + : 0 + +const tern3 = + testingValue[0] === 1 + ? { foo: 1 } === {} + ? { + foo: 1, + bar: 2 + } + : 3 + : resultValue + ? { bar: 1 } + : tern2 + ? resultValue + : { + baz: resultValue + } + +// ============================================================================= +// ternaries: func-call.js 5 + +const fn = () => {} +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ? annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave +) + +// ternaries: nested.js 5 +let icecream = + what == 'cone' + ? p => (p ? \`here's your \${p} cone\` : \`just the empty cone for you\`) + : p => \`here's your \${p} \${what}\` + +a + ? literalline + : { + 123: 12 + } + ? line + : softline + +const message = + i % 3 === 0 && i % 5 === 0 + ? 'fizzbuzz' + : i % 3 === 0 + ? 'fizz' + : i % 5 === 0 + ? 'buzz' + : String(i) + +// ============================================================================= +// ternaries: parenthesis.js 5 + +debug ? (this.state.isVisible ? 'partially visible' : 'hidden') : null +debug + ? this.state.isVisible && somethingComplex + ? 'partially visible' + : 'hidden' + : null + +a => + a + ? () => { + a + } + : () => { + a + } +a => a || a +a => + a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a + +// ============================================================================= +// ternaries: nested.js 5 + +const value = condition1 + ? value1 + : condition2 + ? value2 + : condition3 + ? value3 + : value4 + +// +/* eslint-disable quotes, semi, no-undef, no-unused-vars */ +// @ts-nocheck +// import React from 'react' + +const foo = ( + + className={ + 'match-achievement-medal-type type' + + (medals[0].record + ? '-record' + : medals[0].unique + ? '-unique' + : medals[0].type) + } + > + {medals[0].record + ? i18n('Record') + : medals[0].unique + ? i18n('Unique') + : medals[0].type === 0 + ? i18n('Silver') + : medals[0].type === 1 + ? i18n('Gold') + : medals[0].type === 2 + ? i18n('Platinum') + : i18n('Theme')} +
+) + +const StorybookLoader = ({ match }) => + match.params.storyId === 'button' ? ( + + ) : match.params.storyId === 'color' ? ( + + ) : match.params.storyId === 'typography' ? ( + + ) : match.params.storyId === 'loading' ? ( + + ) : match.params.storyId === 'deal-list' ? ( + + ) : ( + + {'Missing story book'} + + + + + ) + +================================================================================ +`; diff --git a/tests/format/js/standard/correct-ternaries.js b/tests/format/js/standard/correct-ternaries.js new file mode 100644 index 0000000000..89a10ff6be --- /dev/null +++ b/tests/format/js/standard/correct-ternaries.js @@ -0,0 +1,165 @@ +/* eslint-disable no-undef, no-unused-vars, no-redefine, no-unused-expressions, + no-constant-condition, eqeqeq, react/jsx-no-undef */ +/* + Add other cases for pure StandardJS style. +*/ + +const testingValue = [1, 2, 3, 4, 5] +const resultValue = Date.now() + +const tern1 = + testingValue[0] === resultValue + ? resultValue + : testingValue[1] === resultValue + ? testingValue + ? 1 + : 0 + : testingValue[2] === resultValue + ? resultValue + : 0 + +const tern2 = + testingValue[0] === 1 + ? { + foo: 1 + } + : resultValue + ? { + bar: 1 + } + : 0 + +const tern3 = + testingValue[0] === 1 + ? { foo: 1 } === {} + ? { + foo: 1, + bar: 2 + } + : 3 + : resultValue + ? { bar: 1 } + : tern2 + ? resultValue + : { + baz: resultValue + } + +// ============================================================================= +// ternaries: func-call.js 5 + +const fn = () => {} +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ? annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave +) + +// ternaries: nested.js 5 +let icecream = + what == 'cone' + ? (p) => (p ? `here's your ${p} cone` : `just the empty cone for you`) + : (p) => `here's your ${p} ${what}` + +a + ? literalline + : { + 123: 12 + } + ? line + : softline + +const message = + i % 3 === 0 && i % 5 === 0 + ? 'fizzbuzz' + : i % 3 === 0 + ? 'fizz' + : i % 5 === 0 + ? 'buzz' + : String(i) + +// ============================================================================= +// ternaries: parenthesis.js 5 + +debug ? (this.state.isVisible ? 'partially visible' : 'hidden') : null +debug + ? this.state.isVisible && somethingComplex + ? 'partially visible' + : 'hidden' + : null + +;(a) => + a + ? () => { + a + } + : () => { + a + } +;(a) => a || a +;(a) => + a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a + +// ============================================================================= +// ternaries: nested.js 5 + +const value = condition1 + ? value1 + : condition2 + ? value2 + : condition3 + ? value3 + : value4 + +// +/* eslint-disable quotes, semi, no-undef, no-unused-vars */ +// @ts-nocheck +// import React from 'react' + +const foo = ( +
+ {medals[0].record + ? i18n('Record') + : medals[0].unique + ? i18n('Unique') + : medals[0].type === 0 + ? i18n('Silver') + : medals[0].type === 1 + ? i18n('Gold') + : medals[0].type === 2 + ? i18n('Platinum') + : i18n('Theme')} +
+) + +const StorybookLoader = ({ match }) => + match.params.storyId === 'button' ? ( + + ) : match.params.storyId === 'color' ? ( + + ) : match.params.storyId === 'typography' ? ( + + ) : match.params.storyId === 'loading' ? ( + + ) : match.params.storyId === 'deal-list' ? ( + + ) : ( + + {'Missing story book'} + + + + + ) diff --git a/tests/format/js/standard/correct.js b/tests/format/js/standard/correct.js new file mode 100644 index 0000000000..05bac535c2 --- /dev/null +++ b/tests/format/js/standard/correct.js @@ -0,0 +1,342 @@ +// Needs to be at the top but belongs to object-curly-spacing +import { fooA } from 'bar' + +// Needs to be at the top but belongs to indent rule +import { + foosjdfhalsjkdhflasjdhfajashdlfjahsdlfjashdlfjaksdsadfaso, + barsjdfhalsjkdhflasjdhfajashdlfjahsdlfjashdlfjaksdsadfaso, + bazsjdfhalsjkdhflasjdhfajashdlfjahsdlfjashdlfjaksdsadfaso +} from 'qux' + +// "arrow-spacing": ["error", { "before": true, "after": true }] +a => {} +;() => {} +a => a +;() => { + '\n' +} + +// "block-spacing": [ "error", "always" ], +function foo () { + return true +} +if (foo) { + bar = 0 +} + +// "brace-style": [ "error", "1tbs", { "allowSingleLine": true } ], +function foo1 () { + return true +} +if (foo) { + bar() +} +if (foo) { + bar() +} else { + baz() +} +try { + somethingRisky() +} catch (e) { + handleError() +} + +// "comma-spacing": [ "error", { "before": false, "after": true } ], +var fooB = 1 +var baz = 3 +var arr = [1, 2] +var arr = [1, , 3] +var obj = { foo: 'bar', baz: 'qur' } +foo(a, b) +new Foo(a, b) +function foo2 (a, b) {} +a, b + +// "eol-last": "error", +// cannot be tested here, but true (Unix-style new lines) + +// "func-call-spacing": [ "error", "never" ], +fn() + +// "generator-star-spacing": [ "error", { "before": true, "after": true } ], +function * generator1 () {} +var anonymous = function * () {} +var shorthand = { * generator () {} } +class Example { + async * foo () {} +} + +// "indent": [ +// "error", +// 2, +// { +// "SwitchCase": 1, +// "VariableDeclarator": 1, +// "outerIIFEBody": 1, +// "MemberExpression": 1, +// "FunctionDeclaration": { "parameters": 1, "body": 1 }, +// "FunctionExpression": { "parameters": 1, "body": 1 }, +// "CallExpression": { "arguments": 1 }, +// "ArrayExpression": 1, +// "ObjectExpression": 1, +// "ImportDeclaration": 1, +// "flatTernaryExpressions": false, +// "ignoreComments": false +// } +// ], + +switch (a) { + case 'a': + break + case 'b': + break +} + +var aajshdfaljskdhflakjshdflkjashdlfjkhasldkjfhlasjkdfhlaskjdhfalsjkdfha1, + bajshdfaljskdhflakjshdflkjashdlfjkhasldkjfhlasjkdfhlaskjdhfalsjkdfha2, + bajshdfaljskdhflakjshdflkjashdlfjkhasldkjfhlasjkdfhlaskjdhfalsjkdfha3 +let aajshdfaljskdhflakjshdflkjashdlfjkhasldkjfhlasjkdfhlaskjdhfalsjkdfha4, + bajshdfaljskdhflakjshdflkjashdlfjkhasldkjfhlasjkdfhlaskjdhfalsjkdfha5, + bajshdfaljskdhflakjshdflkjashdlfjkhasldkjfhlasjkdfhlaskjdhfalsjkdfha6 +const a = 1 +const b = 2 +const c = 3 +;(function () { + function foo (x) { + return x + 1 + } +})() +if (y) { + console.log('foo') +} +function foo3 ( + barverylongverylongverylongverylongverylongverylongverylongverylong, + bazverylongverylongverylongverylongverylongverylongverylongverylong, + quxverylongverylongverylongverylongverylongverylongverylongverylong +) { + qux() +} +foo( + barverylongverylongverylongverylongverylongverylongverylongverylong, + bazverylongverylongverylongverylongverylongverylongverylongverylong, + quxverylongverylongverylongverylongverylongverylongverylongverylong +) +var fooC = [ + barverylongverylongverylongverylongverylongverylongverylongverylong, + bazverylongverylongverylongverylongverylongverylongverylongverylong, + quxverylongverylongverylongverylongverylongverylongverylongverylong +] +var fooD = { + barverylongverylongverylongverylongverylongverylongverylongverylong: 1, + bazverylongverylongverylongverylongverylongverylongverylongverylong: 2, + quxverylongverylongverylongverylongverylongverylongverylongverylong: 3 +} +var d = barverylongverylongverylongverylongverylongverylongverylongverylong + ? bar + : barverylongverylongverylongverylongverylongverylongverylongverylong + +// "key-spacing": [ "error", { "beforeColon": false, "afterColon": true } ], +var obj = { foo: 42 } + +// "keyword-spacing": [ "error", { "before": true, "after": true } ], +if (foo) { + // ... +} else if (bar) { + // ... +} else { + // ... +} + +// "no-multi-spaces": "error", +var e = 1 +if (foo === 'bar') { +} +a << b +var arr = [1, 2] +a ? b : c + +// "no-multiple-empty-lines": [ "error", { "max": 1, "maxEOF": 0 } ], +// cannot be tested here, but true + +// "no-trailing-spaces": "error", +// cannot be tested here, but true + +// "no-whitespace-before-property": "error", +foo.bar +foo[bar] +foo.bar.baz +foo.bar().baz() + +// "object-curly-spacing": [ "error", "always" ], +var obj = {} +var obj = { foo: 'bar' } +var obj = { foo: { bar: 'baz' }, qux: 'quxx' } +var obj = { + foo: 'bar' +} +var { destructured } = destructure + +// "object-property-newline": [ "error", { "allowMultiplePropertiesPerLine": true } ], +const obj1 = { foo: 'foo', bar: 'bar' } +const obj2 = { + foo: 'foo', + bar: 'bar', + baz: 'baz' +} +const user = process.argv[2] +const obj3 = { + user, + [process.argv[3] ? 'foo' : 'bar']: 0, + baz: [1, 2, 4, 8] +} + +// "padded-blocks": [ "error", { "blocks": "never", "switches": "never", "classes": "never" } ], +if (a) { + b() +} +if (a) { + b() +} +class A { + constructor () { + // ... + } +} +switch (a) { + case 0: + foo() +} + +// "rest-spread-spacing": [ "error", "never" ], +fn(...args) +function fn (...args) { + console.log(args) +} +let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 } +let n = { x, y, ...z } + +// "semi-spacing": [ "error", { "before": false, "after": true } ], +for (;;) {} + +// "space-before-blocks": [ "error", "always" ], +if (a) { + b() +} +if (a) { + b() +} else { + c() +} +function a1 () {} +for (;;) { + b() +} +try { +} catch (a) {} + +// "space-before-function-paren": [ "error", "always" ], +function foo4 () { + // ... +} + +var bar = function () { + // ... +} + +var bar = function foo () { + // ... +} + +class Foo { + constructor () { + // ... + } + + get foo () { + // ... + } + + set bar (param) { + // ... + } +} + +var foo5 = { + bar () { + // ... + } +} + +var foo6 = async () => 1 + +// "space-in-parens": [ "error", "never" ], +foo() + +foo('bar') + +var foo7 = (1 + 2) * 3 +;(function () { + return 'bar' +})() + +// "space-infix-ops": "error", +a + b +a + b +a ? b : c +const aB = { b: 1 } +var { d = 0 } = bar +function foo8 (a = 0) {} + +// "space-unary-ops": [ "error", { "words": true, "nonwords": false } ], +delete foo.bar +new Foo() +void 0 +;-foo +;+'3' +++foo +foo-- + +// "spaced-comment": [ +// "error", +// "always", +// { +// "line": { "markers": [ "*package", "!", "/", ",", "=" ] }, +// "block": { +// "balanced": true, +// "markers": [ "*package", "!", ",", ":", "::", "flow-include" ], +// "exceptions": [ "*" ] +// } +// } +// ], + +/* eslint spaced-comment: ["error", "always"] */ +// This is a comment with a whitespace at the beginning +/* This is a comment with a whitespace at the beginning */ +/* + * This is a comment with a whitespace at the beginning + */ +/* +This comment has a newline +*/ + +// "template-curly-spacing": [ "error", "never" ], +;`hello, ${people.name}!` +;`hello, ${ + people.name.some.long.property.that.cannot.fit.in[80].characters.limit.for + .prettier +}!` + +// "template-tag-spacing": [ "error", "never" ], +func`Hello world` + +// "unicode-bom": [ "error", "never" ], +var abc + +// "yield-star-spacing": [ "error", "both" ] +function * generator2 () { + yield * other() +} + +// "jsx-quotes": ["error", "prefer-single"], +;() =>
diff --git a/tests/format/js/standard/incorrect-ternaries.js b/tests/format/js/standard/incorrect-ternaries.js new file mode 100644 index 0000000000..7c75b8ff6f --- /dev/null +++ b/tests/format/js/standard/incorrect-ternaries.js @@ -0,0 +1,137 @@ +/* eslint-disable no-undef, no-unused-vars, no-redefine, no-unused-expressions, + no-constant-condition, eqeqeq, react/jsx-no-undef */ +/* + Add other cases for pure StandardJS style. +*/ + + +const testingValue = [1, 2, 3, 4, 5] +const resultValue = Date.now() + +const tern1 = testingValue[0] === resultValue? resultValue + : testingValue[1] === resultValue ? testingValue + ? 1 : 0 + :testingValue[2] === resultValue + ? resultValue : 0; + +const tern2 = + testingValue[0] === 1 ? { + foo: 1 + }: resultValue ? { + bar: 1} + :0; + + const tern3 = +testingValue[0] === 1 ? {foo:1} === {}? { + foo: 1, bar: 2} : 3 : resultValue ? {bar:1} : (tern2 ? resultValue : { + baz:resultValue}) + +// ============================================================================= +// ternaries: func-call.js 5 + +const fn = () => {} +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ? annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave +); + +// ternaries: nested.js 5 +let icecream = what == "cone" +? p => (p ? `here's your ${p} cone` : `just the empty cone for you`) +: p => `here's your ${p} ${what}`; + +a + ? literalline + : { + 123: 12 + } + ? line + : softline + +const message = + i % 3 === 0 && i % 5 === 0 + ? "fizzbuzz" + : i % 3 === 0 + ? "fizz" + : i % 5 === 0 + ? "buzz" + : String(i); + +// ============================================================================= +// ternaries: parenthesis.js 5 + +debug ? (this.state.isVisible ? "partially visible" : "hidden") : null; +debug + ? this.state.isVisible && somethingComplex + ? "partially visible" + : "hidden" + : null; + +a => + a + ? () => { + a; + } + : () => { + a; + } +a => (a||a); +a => + a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a; + +// ============================================================================= +// ternaries: nested.js 5 + +const value = condition1 ? value1 : condition2 ? value2 : condition3 ? value3 : value4; + +// +/* eslint-disable quotes, semi, no-undef, no-unused-vars */ +// @ts-nocheck +// import React from 'react' + +const foo = ( +
+ {medals[0].record + ? i18n("Record") + : medals[0].unique + ? i18n("Unique") + : medals[0].type === 0 + ? i18n("Silver") + : medals[0].type === 1 + ? i18n("Gold") + : medals[0].type === 2 + ? i18n("Platinum") + : i18n("Theme")} +
+); + +const StorybookLoader = ({ match }) => + match.params.storyId === "button" ? ( + + ) : match.params.storyId === "color" ? ( + + ) : match.params.storyId === "typography" ? ( + + ) : match.params.storyId === "loading" ? ( + + ) : match.params.storyId === "deal-list" ? ( + + ) : ( + + {"Missing story book"} + + + + +); diff --git a/tests/format/js/standard/incorrect.js b/tests/format/js/standard/incorrect.js new file mode 100644 index 0000000000..b264be5f46 --- /dev/null +++ b/tests/format/js/standard/incorrect.js @@ -0,0 +1,381 @@ +// "arrow-spacing": ["error", { "before": true, "after": true }] + +()=> {}; +() =>{}; +(a)=> {}; +(a) =>{}; +a =>a; +a=> a; +()=> {'\n'}; +() =>{'\n'}; + +// "block-spacing": [ "error", "always" ], + +function foo1() {return true;} +if (foo) { bar = 0;} +function baz() {let i = 0; + return i; +} + +// "brace-style": [ "error", "1tbs", { "allowSingleLine": true } ], + +function foo2() +{ + return true; +} + +if (foo) +{ + bar(); +} + +try +{ + somethingRisky(); +} catch(e) +{ + handleError(); +} + +if (foo) { + bar(); +} +else { + baz(); +} + +// "comma-spacing": [ "error", { "before": false, "after": true } ], + +var foo = 1 ,bar = 2; +var arr = [1 , 2]; +var obj = {"foo": "bar" ,"baz": "qur"}; +foo(a ,b); +new Foo(a ,b); +function foo3(a ,b){} +a ,b + +// "eol-last": "error", +// cannot be tested here, but true (Unix-style new lines) + +// "func-call-spacing": [ "error", "never" ], +fn (); + +fn +(); + +// "generator-star-spacing": [ "error", { "before": true, "after": true } ], + +function* generator1() {} +var anonymous = function* () {}; +var shorthand = { * generator() {} }; +function *generator2() {} +var anonymous = function *() {}; +var shorthand = { *generator() {} }; + + +// "indent": [ +// "error", +// 2, +// { +// "SwitchCase": 1, +// "VariableDeclarator": 1, +// "outerIIFEBody": 1, +// "MemberExpression": 1, +// "FunctionDeclaration": { "parameters": 1, "body": 1 }, +// "FunctionExpression": { "parameters": 1, "body": 1 }, +// "CallExpression": { "arguments": 1 }, +// "ArrayExpression": 1, +// "ObjectExpression": 1, +// "ImportDeclaration": 1, +// "flatTernaryExpressions": false, +// "ignoreComments": false +// } +// ], + +// "key-spacing": [ "error", { "beforeColon": false, "afterColon": true } ], + +var obj = { "foo" : 42 }; +var obj = { "foo":42 }; + +// "keyword-spacing": [ "error", { "before": true, "after": true } ], + +if (foo) { + //... +}else if (bar) { + //... +}else { + //... +} + +// "no-multi-spaces": "error", + +var a = 1; +if(foo === "bar") {} +a << b +var arr = [1, 2]; +a ? b: c + +// "no-multiple-empty-lines": [ "error", { "max": 1, "maxEOF": 0 } ], +// cannot be tested here, but true + +// "no-trailing-spaces": "error", +// cannot be tested here, but true + +// "no-whitespace-before-property": "error", + +foo [bar] +foo. bar +foo .bar +foo. bar. baz +foo. bar() + .baz() +foo + .bar(). baz() + +// "object-curly-spacing": [ "error", "always" ], + +var obj = {'foo': 'bar'}; +var obj = {'foo': 'bar' }; +var obj = { baz: {'foo': 'qux'}, bar}; +var obj = {baz: { 'foo': 'qux' }, bar}; +var obj = {'foo': 'bar' +}; +var obj = { + 'foo':'bar'}; +var {destructured} = destructure; +import {fooA } from 'bar'; + +// "object-property-newline": [ "error", { "allowMultiplePropertiesPerLine": true } ], + +const obj0 = { foo: "foo", bar: "bar", baz: "baz" }; +const obj1 = { + foo: "foo", bar: "bar", baz: "baz" +}; +const obj2 = { + foo: "foo", bar: "bar", + baz: "baz" +}; +const obj3 = { + [process.argv[3] ? "foo" : "bar"]: 0, baz: [ + 1, + 2, + 4, + 8 + ] +}; +const b = "antidisestablishmentarianistically"; +const c = "yugoslavyalılaştırabildiklerimizdenmişsiniz"; +const obj4 = {a, b}; +const domain = process.argv[4]; +const obj5 = { + foo: "foo", [ + domain.includes(":") ? "complexdomain" : "simpledomain" + ]: true}; + +// "padded-blocks": [ "error", { "blocks": "never", "switches": "never", "classes": "never" } ], + + +if (a) { + + b(); + +} + +if (a) +{ + + b(); + +} + +if (a) { + + b(); +} + +if (a) { + b(); + +} + +class A { + + constructor(){ + } + +} + +switch (a) { + + case 0: foo(); + +} + +// "rest-spread-spacing": [ "error", "never" ], + +fn(... args) +function fn(... args) { console.log(args); } +let { x, y, ... z } = { x: 1, y: 2, a: 3, b: 4 }; +let n = { x, y, ... z }; + +// "semi-spacing": [ "error", { "before": false, "after": true } ], + +var foo ; +var foo;var bar; +throw new Error("error") ; +while (a) { break ; } +for (i = 0 ; i < 10 ; i++) {} +for (i = 0;i < 10;i++) {} + +// "space-before-blocks": [ "error", "always" ], + +if (a){ + b(); +} + +function fnA(){} + +for (;;){ + b(); +} + +try {} catch(a){} + +class Foo{ + constructor(){} +} + +// "space-before-function-paren": [ "error", "always" ], + +function foo4() { + // ... +} + +var bar = function() { + // ... +}; + +var bar = function foo() { + // ... +}; + +class Foo2 { + constructor() { + // ... + } +} + +var foo = { + bar() { + // ... + } +}; + +var foo = async() => 1 + +// "space-in-parens": [ "error", "never" ], + +foo( 'bar'); +foo('bar' ); +foo( 'bar' ); + +var foo = ( 1 + 2 ) * 3; +( function () { return 'bar'; }() ); + +// "space-infix-ops": "error", + +a+b +a+ b +a +b +a?b:c +const d={b:1}; +var {a=0}=bar; +function foo5(a=0) { } + +// "space-unary-ops": [ "error", { "words": true, "nonwords": false } ], + +typeof!foo; +void{foo:0}; +new[foo][0]; +delete(foo.bar); +++ foo; +foo --; +- foo; ++ "3"; + +// "spaced-comment": [ +// "error", +// "always", +// { +// "line": { "markers": [ "*package", "!", "/", ",", "=" ] }, +// "block": { +// "balanced": true, +// "markers": [ "*package", "!", ",", ":", "::", "flow-include" ], +// "exceptions": [ "*" ] +// } +// } +// ], + +/*eslint spaced-comment: ["error", "always"]*/ +//This is a comment with no whitespace at the beginning +/*This is a comment with no whitespace at the beginning */ +/* eslint spaced-comment: ["error", "always", { "block": { "balanced": true } }] */ +/* This is a comment with whitespace at the beginning but not the end*/ + +// "template-curly-spacing": [ "error", "never" ], +// (blank line here causes issues with CI for some reason) +`hello, ${ people.name}!`; +`hello, ${people.name }!`; +`hello, ${ people.name }!`; + +// "template-tag-spacing": [ "error", "never" ], + +func `Hello world`; + +// "unicode-bom": [ "error", "never" ], + +U+FEFF +var abc; + +// "yield-star-spacing": [ "error", "both" ] + + +function *generator3() { + yield *other(); +} +function* generator4() { + yield* other(); +} +function*generator5() { + yield*other(); +} + +// "jsx-quotes": ["error", "prefer-single"], +;() =>
+ +// "indent": [ +// "error", +// 2, +// { +// "SwitchCase": 1, +// "VariableDeclarator": 1, +// "outerIIFEBody": 1, +// "MemberExpression": 1, +// "FunctionDeclaration": { "parameters": 1, "body": 1 }, +// "FunctionExpression": { "parameters": 1, "body": 1 }, +// "CallExpression": { "arguments": 1 }, +// "ArrayExpression": 1, +// "ObjectExpression": 1, +// "ImportDeclaration": 1, +// "flatTernaryExpressions": false, +// "ignoreComments": false +// } +// ], +let isSpace = false +const dress = isSpace ? { + spaceSuit: 3, + oxygenCylinders: 6 + } : { + shirts: 3, + paints: 3 + } diff --git a/tests/format/js/standard/jsfmt.spec.js b/tests/format/js/standard/jsfmt.spec.js new file mode 100644 index 0000000000..3cb10323a7 --- /dev/null +++ b/tests/format/js/standard/jsfmt.spec.js @@ -0,0 +1,18 @@ +run_spec(__dirname, ["babel", "babel-flow", "flow", "typescript"], { + // [TBD] issue with babel-ts parser: + errors: { "babel-ts": ["incorrect-ternaries.js"] }, + // explicit endOfLine setting, same as default since Prettier 2.0 + // (shows in test snapshots) + endOfLine: "lf", + // "Standard JS": + yieldStarSpacing: true, + generatorStarSpacing: true, + offsetTernaryExpressions: true, + spaceBeforeFunctionParen: true, + singleQuote: true, + jsxSingleQuote: true, + semi: false, + trailingComma: "none", + // recommended: + arrowParens: "avoid", +}); diff --git a/tests/format/js/template/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/template/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..eb5f3548fc --- /dev/null +++ b/tests/format/js/template/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,472 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`arrow.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow"] +printWidth: 80 +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" + | printWidth +=====================================input====================================== +() => a\` + a +\`; + +() => \` + a +\`; + +=====================================output===================================== +() => a\` + a +\`; + +() => \` + a +\`; + +================================================================================ +`; + +exports[`call.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow"] +printWidth: 80 +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" + | printWidth +=====================================input====================================== +insertRule(\`*, *:before, *:after { + box-sizing: inherit; +}\`); + +insertRule\`*, *:before, *:after { + box-sizing: inherit; +}\`; + +new Error(formatErrorMessage\` + This a really bad error. + Which has more than one line. +\`); + +=====================================output===================================== +insertRule( \`*, *:before, *:after { + box-sizing: inherit; +}\` ); + +insertRule\`*, *:before, *:after { + box-sizing: inherit; +}\`; + +new Error( formatErrorMessage\` + This a really bad error. + Which has more than one line. +\` ); + +================================================================================ +`; + +exports[`comment.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow"] +printWidth: 80 +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" + | printWidth +=====================================input====================================== +\` +(?:\${escapeChar}[\\\\S\\\\s]|(?:(?!\${// Using \`XRegExp.union\` safely rewrites backreferences in \`left\` and \`right\`. +// Intentionally not passing \`basicFlags\` to \`XRegExp.union\` since any syntax +// transformation resulting from those flags was already applied to \`left\` and +// \`right\` when they were passed through the XRegExp constructor above. +XRegExp.union([left, right], '', {conjunction: 'or'}).source})[^\${escapeChar}])+)+ +\`; + +\`a\${/* b */c/* d */}e\${// f +g +// h +}\`; + +=====================================output===================================== +\` +(?:\${ escapeChar }[\\\\S\\\\s]|(?:(?!\${ + // Using \`XRegExp.union\` safely rewrites backreferences in \`left\` and \`right\`. + // Intentionally not passing \`basicFlags\` to \`XRegExp.union\` since any syntax + // transformation resulting from those flags was already applied to \`left\` and + // \`right\` when they were passed through the XRegExp constructor above. + XRegExp.union( [ left, right ], "", { conjunction: "or" } ).source +})[^\${ escapeChar }])+)+ +\`; + +\`a\${ /* b */ c /* d */ }e\${ + // f + g + // h +}\`; + +================================================================================ +`; + +exports[`faulty-locations.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow"] +printWidth: 80 +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" + | printWidth +=====================================input====================================== +var o = { + [\`key\`]: () => { + // Comment + } +}; + +var x = { + y: () => Relay.QL\` + query { + \${foo}, + field, + } + \` +}; + +=====================================output===================================== +var o = { + [ \`key\` ]: () => { + // Comment + } +}; + +var x = { + y: () => Relay.QL\` + query { + \${foo}, + field, + } + \` +}; + +================================================================================ +`; + +exports[`graphql.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow"] +printWidth: 80 +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" + | printWidth +=====================================input====================================== +module.exports = Relay.createContainer( + // ... + { + fragments: { + nodes: ({solution_type, time_frame}) => Relay.QL\` + fragment on RelatedNode @relay(plural: true) { + __typename + \${OptimalSolutionsSection + .getFragment( + 'node', + {solution_type, time_frame}, + ) + } + } + \`, + }, + }, +); + +=====================================output===================================== +module.exports = Relay.createContainer( + // ... + { + fragments: { + nodes: ( { solution_type, time_frame } ) => Relay.QL\` + fragment on RelatedNode @relay(plural: true) { + __typename + \${ OptimalSolutionsSection.getFragment( "node", { + solution_type, + time_frame + } ) } + } + \` + } + } +); + +================================================================================ +`; + +exports[`indent.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow"] +printWidth: 80 +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" + | printWidth +=====================================input====================================== +const foo = () => { + { + { + { + return \` +line 1 +line 2 +... +line n +\${foo({ + many: keys, + many: keys +})} +line n + 1 +line n + 2 +line n + n +\`; + } + } + } +}; +=====================================output===================================== +const foo = () => { + { + { + { + return \` +line 1 +line 2 +... +line n +\${ foo( { + many: keys, + many: keys +} ) } +line n + 1 +line n + 2 +line n + n +\`; + } + } + } +}; + +================================================================================ +`; + +exports[`inline.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow"] +printWidth: 80 +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" + | printWidth +=====================================input====================================== +this._pipe.write(\`\\n\\n Pattern matches \${total} \${pluralizeTest}\`); +this._pipe.write( + \`\\n\\n Pattern matches \${total} \${pluralizeTest}\` +); +this._pipe + .write( + \`\\n\\n Pattern matches \${total} \${pluralizeTest}\` + ); + +this._pipe.write(\`\\n\\n Pattern matches \${total} \${pluralizeTest} but that's long\`); + +this._pipe.write( + \`\\n\\n Pattern matches \${total} \${pluralizeTest} but that's long\` +); + +this._pipe.write(\` + \\n\\n Pattern matches \${total} \${pluralizeTest} but that's long +\`); + + +() => \` + a +\`; + +() => + \` + a + \`; + + +// https://github.com/prettier/prettier/issues/5529 +editTitle += \`\${iconHTML({ class: "reply-to-glyph" })}\`; + +=====================================output===================================== +this._pipe.write( \`\\n\\n Pattern matches \${total} \${pluralizeTest}\` ); +this._pipe.write( \`\\n\\n Pattern matches \${total} \${pluralizeTest}\` ); +this._pipe.write( \`\\n\\n Pattern matches \${total} \${pluralizeTest}\` ); + +this._pipe.write( + \`\\n\\n Pattern matches \${total} \${pluralizeTest} but that's long\` +); + +this._pipe.write( + \`\\n\\n Pattern matches \${total} \${pluralizeTest} but that's long\` +); + +this._pipe.write( \` + \\n\\n Pattern matches \${total} \${pluralizeTest} but that's long +\` ); + +() => \` + a +\`; + +() => + \` + a + \`; + +// https://github.com/prettier/prettier/issues/5529 +editTitle += \`\${ iconHTML( { class: "reply-to-glyph" } ) }\`; + +================================================================================ +`; + +exports[`parenthesis.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +computedPropertySpacing: true +parsers: ["babel", "babel-flow"] +printWidth: 80 +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" + | printWidth +=====================================input====================================== +// "ArrowFunctionExpression" +(() => {})\`\`; + +// "AssignmentExpression" +(b = c)\`\`; + +// "AwaitExpression" +async function f() { + (await b)\`\`; +} + +// "BinaryExpression" +(b + c)\`\`; + +// "CallExpression" +b()\`\`; + +// "ClassExpression" +(class {})\`\`; + +// "ConditionalExpression" +(b ? c : d)\`\`; + +// "FunctionExpression" +(function() {})\`\`; + +// "LogicalExpression" +(b || c)\`\`; + +// "MemberExpression" +b.c\`\`; + +// "NewExpression" +(new B())\`\`; + +// "ObjectExpression" +({})\`\`; + +// "SequenceExpression" +(b, c)\`\`; + +// "TaggedTemplateExpression" +(\`\`)\`\`; + +// "UnaryExpression" +(void b)\`\`; + +// "UpdateExpression" +(++b)\`\`; + +// "YieldExpression" +function* d() { + (yield 1)\`\`; +} + +=====================================output===================================== +// "ArrowFunctionExpression" +( () => {} )\`\`; + +// "AssignmentExpression" +( b = c )\`\`; + +// "AwaitExpression" +async function f() { + ( await b )\`\`; +} + +// "BinaryExpression" +( b + c )\`\`; + +// "CallExpression" +b()\`\`; + +// "ClassExpression" +( class {}\`\` ); + +// "ConditionalExpression" +( b ? c : d )\`\`; + +// "FunctionExpression" +( function () {} )\`\`; + +// "LogicalExpression" +( b || c )\`\`; + +// "MemberExpression" +b.c\`\`; + +// "NewExpression" +new B()\`\`; + +// "ObjectExpression" +( {}\`\` ); + +// "SequenceExpression" +( b, c )\`\`; + +// "TaggedTemplateExpression" +\`\`\`\`; + +// "UnaryExpression" +( void b )\`\`; + +// "UpdateExpression" +( ++b )\`\`; + +// "YieldExpression" +function* d() { + ( yield 1 )\`\`; +} + +================================================================================ +`; diff --git a/tests/format/js/template/with-inner-spacing/jsfmt.spec.js b/tests/format/js/template/with-inner-spacing/jsfmt.spec.js new file mode 100644 index 0000000000..e8c5288493 --- /dev/null +++ b/tests/format/js/template/with-inner-spacing/jsfmt.spec.js @@ -0,0 +1,14 @@ +// [prettierx] test script notice: +// This test script runs for test files in parent directory, +// **not** on any files in *this* directory. + +const dirPath = `${__dirname}/..`; + +run_spec(dirPath, ["babel", "babel-flow"], { + // [prettierx] test with --paren-spacing + spaceInParens: true, + arrayBracketSpacing: true, + computedPropertySpacing: true, + templateCurlySpacing: true, + trailingComma: "none", // ("Standard JS") +}); diff --git a/tests/format/js/ternaries/with-balanced-formatting/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/ternaries/with-balanced-formatting/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..2525dded18 --- /dev/null +++ b/tests/format/js/ternaries/with-balanced-formatting/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,5865 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`binary.js - {"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" + | printWidth +=====================================input====================================== +const funnelSnapshotCard = (report === MY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2) || + (report === COMPANY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2_company_metrics) + ? + : null; + +room = room.map((row, rowIndex) => ( + row.map((col, colIndex) => ( + (rowIndex === 0 || colIndex === 0 || rowIndex === height || colIndex === width) ? 1 : 0 + )) +)) + +=====================================output===================================== +const funnelSnapshotCard = + (report === MY_OVERVIEW && !ReportGK.xar_metrics_active_capitol_v2) || + (report === COMPANY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2_company_metrics) ? ( + + ) : null; + +room = room.map((row, rowIndex) => + row.map((col, colIndex) => + rowIndex === 0 || + colIndex === 0 || + rowIndex === height || + colIndex === width + ? 1 + : 0 + ) +); + +================================================================================ +`; + +exports[`binary.js - {"tabWidth":4,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +trailingComma: "none" + | printWidth +=====================================input====================================== +const funnelSnapshotCard = (report === MY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2) || + (report === COMPANY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2_company_metrics) + ? + : null; + +room = room.map((row, rowIndex) => ( + row.map((col, colIndex) => ( + (rowIndex === 0 || colIndex === 0 || rowIndex === height || colIndex === width) ? 1 : 0 + )) +)) + +=====================================output===================================== +const funnelSnapshotCard = + (report === MY_OVERVIEW && !ReportGK.xar_metrics_active_capitol_v2) || + (report === COMPANY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2_company_metrics) ? ( + + ) : null; + +room = room.map((row, rowIndex) => + row.map((col, colIndex) => + rowIndex === 0 || + colIndex === 0 || + rowIndex === height || + colIndex === width + ? 1 + : 0 + ) +); + +================================================================================ +`; + +exports[`binary.js - {"useTabs":true,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" +useTabs: true + | printWidth +=====================================input====================================== +const funnelSnapshotCard = (report === MY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2) || + (report === COMPANY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2_company_metrics) + ? + : null; + +room = room.map((row, rowIndex) => ( + row.map((col, colIndex) => ( + (rowIndex === 0 || colIndex === 0 || rowIndex === height || colIndex === width) ? 1 : 0 + )) +)) + +=====================================output===================================== +const funnelSnapshotCard = + (report === MY_OVERVIEW && !ReportGK.xar_metrics_active_capitol_v2) || + (report === COMPANY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2_company_metrics) ? ( + + ) : null; + +room = room.map((row, rowIndex) => + row.map((col, colIndex) => + rowIndex === 0 || + colIndex === 0 || + rowIndex === height || + colIndex === width + ? 1 + : 0 + ) +); + +================================================================================ +`; + +exports[`binary.js - {"useTabs":true,"tabWidth":4,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +trailingComma: "none" +useTabs: true + | printWidth +=====================================input====================================== +const funnelSnapshotCard = (report === MY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2) || + (report === COMPANY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2_company_metrics) + ? + : null; + +room = room.map((row, rowIndex) => ( + row.map((col, colIndex) => ( + (rowIndex === 0 || colIndex === 0 || rowIndex === height || colIndex === width) ? 1 : 0 + )) +)) + +=====================================output===================================== +const funnelSnapshotCard = + (report === MY_OVERVIEW && !ReportGK.xar_metrics_active_capitol_v2) || + (report === COMPANY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2_company_metrics) ? ( + + ) : null; + +room = room.map((row, rowIndex) => + row.map((col, colIndex) => + rowIndex === 0 || + colIndex === 0 || + rowIndex === height || + colIndex === width + ? 1 + : 0 + ) +); + +================================================================================ +`; + +exports[`func-call.js - {"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" + | printWidth +=====================================input====================================== +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ? annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave +); + +=====================================output===================================== +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ? annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave +); + +================================================================================ +`; + +exports[`func-call.js - {"tabWidth":4,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +trailingComma: "none" + | printWidth +=====================================input====================================== +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ? annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave +); + +=====================================output===================================== +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ? annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave +); + +================================================================================ +`; + +exports[`func-call.js - {"useTabs":true,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" +useTabs: true + | printWidth +=====================================input====================================== +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ? annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave +); + +=====================================output===================================== +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ? annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave +); + +================================================================================ +`; + +exports[`func-call.js - {"useTabs":true,"tabWidth":4,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +trailingComma: "none" +useTabs: true + | printWidth +=====================================input====================================== +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ? annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave +); + +=====================================output===================================== +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ? annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave +); + +================================================================================ +`; + +exports[`indent.js - {"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" + | printWidth +=====================================input====================================== +aaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb : ccccccccccccccc ? ddddddddddddddd : eeeeeeeeeeeeeee ? fffffffffffffff : gggggggggggggggg + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +a + ? { + a: 0 + } + : { + a: { + a: 0 + } + ? { + a: 0 + } + : { + y: { + a: 0 + } + ? { + a: 0 + } + : { + a: 0 + } + } + } + +a + ? { + a: function() { + return a + ? { + a: [ + a + ? { + a: 0, + b: [ + a + ? [ + 0, + 1 + ] + : [] + ] + } + : [ + [ + 0, + { + a: 0 + }, + a + ? 0 + : 1 + ], + function() { + return a + ? { + a: 0 + } + : [ + { + a: 0 + }, + {} + ]; + } + ] + ] + } + : [ + a + ? function() { + a + ? a( + a + ? { + a: a( + { + a: 0 + } + ) + } + : [ + 0, + a(), + a( + a(), + { + a: 0 + }, + a + ? a() + : a( + { + a: 0 + } + ) + ), + a() + ? { + a: a(), + b: [] + } + : {} + ] + ): + a( + a() + ? { + a: 0 + } + : (function(a) { + return a() + ? [ + { + a: 0, + b: a() + } + ] + : a( + [ + a + ? { + a: 0 + } + : {}, + { + a: 0 + } + ] + ); + })( + a + ? function(a) { + return function() { + return 0; + }; + } + : function(a) { + return function() { + return 1; + } + } + ) + ); + } + : function() { + + } + ]; + } + } + : a; + +=====================================output===================================== +aaaaaaaaaaaaaaa + ? bbbbbbbbbbbbbbbbbb + : ccccccccccccccc + ? ddddddddddddddd + : eeeeeeeeeeeeeee + ? fffffffffffffff + : gggggggggggggggg; + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; + +a + ? { + a: 0 + } + : { + a: { + a: 0 + } + ? { + a: 0 + } + : { + y: { + a: 0 + } + ? { + a: 0 + } + : { + a: 0 + } + } + }; + +a + ? { + a: function () { + return a + ? { + a: [ + a + ? { + a: 0, + b: [a ? [0, 1] : []] + } + : [ + [ + 0, + { + a: 0 + }, + a ? 0 : 1 + ], + function () { + return a + ? { + a: 0 + } + : [ + { + a: 0 + }, + {} + ]; + } + ] + ] + } + : [ + a + ? function () { + a + ? a( + a + ? { + a: a({ + a: 0 + }) + } + : [ + 0, + a(), + a( + a(), + { + a: 0 + }, + a + ? a() + : a({ + a: 0 + }) + ), + a() + ? { + a: a(), + b: [] + } + : {} + ] + ) + : a( + a() + ? { + a: 0 + } + : (function (a) { + return a() + ? [ + { + a: 0, + b: a() + } + ] + : a([ + a + ? { + a: 0 + } + : {}, + { + a: 0 + } + ]); + })( + a + ? function (a) { + return function () { + return 0; + }; + } + : function (a) { + return function () { + return 1; + }; + } + ) + ); + } + : function () {} + ]; + } + } + : a; + +================================================================================ +`; + +exports[`indent.js - {"tabWidth":4,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +trailingComma: "none" + | printWidth +=====================================input====================================== +aaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb : ccccccccccccccc ? ddddddddddddddd : eeeeeeeeeeeeeee ? fffffffffffffff : gggggggggggggggg + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +a + ? { + a: 0 + } + : { + a: { + a: 0 + } + ? { + a: 0 + } + : { + y: { + a: 0 + } + ? { + a: 0 + } + : { + a: 0 + } + } + } + +a + ? { + a: function() { + return a + ? { + a: [ + a + ? { + a: 0, + b: [ + a + ? [ + 0, + 1 + ] + : [] + ] + } + : [ + [ + 0, + { + a: 0 + }, + a + ? 0 + : 1 + ], + function() { + return a + ? { + a: 0 + } + : [ + { + a: 0 + }, + {} + ]; + } + ] + ] + } + : [ + a + ? function() { + a + ? a( + a + ? { + a: a( + { + a: 0 + } + ) + } + : [ + 0, + a(), + a( + a(), + { + a: 0 + }, + a + ? a() + : a( + { + a: 0 + } + ) + ), + a() + ? { + a: a(), + b: [] + } + : {} + ] + ): + a( + a() + ? { + a: 0 + } + : (function(a) { + return a() + ? [ + { + a: 0, + b: a() + } + ] + : a( + [ + a + ? { + a: 0 + } + : {}, + { + a: 0 + } + ] + ); + })( + a + ? function(a) { + return function() { + return 0; + }; + } + : function(a) { + return function() { + return 1; + } + } + ) + ); + } + : function() { + + } + ]; + } + } + : a; + +=====================================output===================================== +aaaaaaaaaaaaaaa + ? bbbbbbbbbbbbbbbbbb + : ccccccccccccccc + ? ddddddddddddddd + : eeeeeeeeeeeeeee + ? fffffffffffffff + : gggggggggggggggg; + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; + +a + ? { + a: 0 + } + : { + a: { + a: 0 + } + ? { + a: 0 + } + : { + y: { + a: 0 + } + ? { + a: 0 + } + : { + a: 0 + } + } + }; + +a + ? { + a: function () { + return a + ? { + a: [ + a + ? { + a: 0, + b: [a ? [0, 1] : []] + } + : [ + [ + 0, + { + a: 0 + }, + a ? 0 : 1 + ], + function () { + return a + ? { + a: 0 + } + : [ + { + a: 0 + }, + {} + ]; + } + ] + ] + } + : [ + a + ? function () { + a + ? a( + a + ? { + a: a({ + a: 0 + }) + } + : [ + 0, + a(), + a( + a(), + { + a: 0 + }, + a + ? a() + : a({ + a: 0 + }) + ), + a() + ? { + a: a(), + b: [] + } + : {} + ] + ) + : a( + a() + ? { + a: 0 + } + : (function (a) { + return a() + ? [ + { + a: 0, + b: a() + } + ] + : a([ + a + ? { + a: 0 + } + : {}, + { + a: 0 + } + ]); + })( + a + ? function (a) { + return function () { + return 0; + }; + } + : function (a) { + return function () { + return 1; + }; + } + ) + ); + } + : function () {} + ]; + } + } + : a; + +================================================================================ +`; + +exports[`indent.js - {"useTabs":true,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" +useTabs: true + | printWidth +=====================================input====================================== +aaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb : ccccccccccccccc ? ddddddddddddddd : eeeeeeeeeeeeeee ? fffffffffffffff : gggggggggggggggg + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +a + ? { + a: 0 + } + : { + a: { + a: 0 + } + ? { + a: 0 + } + : { + y: { + a: 0 + } + ? { + a: 0 + } + : { + a: 0 + } + } + } + +a + ? { + a: function() { + return a + ? { + a: [ + a + ? { + a: 0, + b: [ + a + ? [ + 0, + 1 + ] + : [] + ] + } + : [ + [ + 0, + { + a: 0 + }, + a + ? 0 + : 1 + ], + function() { + return a + ? { + a: 0 + } + : [ + { + a: 0 + }, + {} + ]; + } + ] + ] + } + : [ + a + ? function() { + a + ? a( + a + ? { + a: a( + { + a: 0 + } + ) + } + : [ + 0, + a(), + a( + a(), + { + a: 0 + }, + a + ? a() + : a( + { + a: 0 + } + ) + ), + a() + ? { + a: a(), + b: [] + } + : {} + ] + ): + a( + a() + ? { + a: 0 + } + : (function(a) { + return a() + ? [ + { + a: 0, + b: a() + } + ] + : a( + [ + a + ? { + a: 0 + } + : {}, + { + a: 0 + } + ] + ); + })( + a + ? function(a) { + return function() { + return 0; + }; + } + : function(a) { + return function() { + return 1; + } + } + ) + ); + } + : function() { + + } + ]; + } + } + : a; + +=====================================output===================================== +aaaaaaaaaaaaaaa + ? bbbbbbbbbbbbbbbbbb + : ccccccccccccccc + ? ddddddddddddddd + : eeeeeeeeeeeeeee + ? fffffffffffffff + : gggggggggggggggg; + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; + +a + ? { + a: 0 + } + : { + a: { + a: 0 + } + ? { + a: 0 + } + : { + y: { + a: 0 + } + ? { + a: 0 + } + : { + a: 0 + } + } + }; + +a + ? { + a: function () { + return a + ? { + a: [ + a + ? { + a: 0, + b: [a ? [0, 1] : []] + } + : [ + [ + 0, + { + a: 0 + }, + a ? 0 : 1 + ], + function () { + return a + ? { + a: 0 + } + : [ + { + a: 0 + }, + {} + ]; + } + ] + ] + } + : [ + a + ? function () { + a + ? a( + a + ? { + a: a({ + a: 0 + }) + } + : [ + 0, + a(), + a( + a(), + { + a: 0 + }, + a + ? a() + : a({ + a: 0 + }) + ), + a() + ? { + a: a(), + b: [] + } + : {} + ] + ) + : a( + a() + ? { + a: 0 + } + : (function (a) { + return a() + ? [ + { + a: 0, + b: a() + } + ] + : a([ + a + ? { + a: 0 + } + : {}, + { + a: 0 + } + ]); + })( + a + ? function (a) { + return function () { + return 0; + }; + } + : function (a) { + return function () { + return 1; + }; + } + ) + ); + } + : function () {} + ]; + } + } + : a; + +================================================================================ +`; + +exports[`indent.js - {"useTabs":true,"tabWidth":4,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +trailingComma: "none" +useTabs: true + | printWidth +=====================================input====================================== +aaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb : ccccccccccccccc ? ddddddddddddddd : eeeeeeeeeeeeeee ? fffffffffffffff : gggggggggggggggg + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +a + ? { + a: 0 + } + : { + a: { + a: 0 + } + ? { + a: 0 + } + : { + y: { + a: 0 + } + ? { + a: 0 + } + : { + a: 0 + } + } + } + +a + ? { + a: function() { + return a + ? { + a: [ + a + ? { + a: 0, + b: [ + a + ? [ + 0, + 1 + ] + : [] + ] + } + : [ + [ + 0, + { + a: 0 + }, + a + ? 0 + : 1 + ], + function() { + return a + ? { + a: 0 + } + : [ + { + a: 0 + }, + {} + ]; + } + ] + ] + } + : [ + a + ? function() { + a + ? a( + a + ? { + a: a( + { + a: 0 + } + ) + } + : [ + 0, + a(), + a( + a(), + { + a: 0 + }, + a + ? a() + : a( + { + a: 0 + } + ) + ), + a() + ? { + a: a(), + b: [] + } + : {} + ] + ): + a( + a() + ? { + a: 0 + } + : (function(a) { + return a() + ? [ + { + a: 0, + b: a() + } + ] + : a( + [ + a + ? { + a: 0 + } + : {}, + { + a: 0 + } + ] + ); + })( + a + ? function(a) { + return function() { + return 0; + }; + } + : function(a) { + return function() { + return 1; + } + } + ) + ); + } + : function() { + + } + ]; + } + } + : a; + +=====================================output===================================== +aaaaaaaaaaaaaaa + ? bbbbbbbbbbbbbbbbbb + : ccccccccccccccc + ? ddddddddddddddd + : eeeeeeeeeeeeeee + ? fffffffffffffff + : gggggggggggggggg; + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; + +a + ? { + a: 0 + } + : { + a: { + a: 0 + } + ? { + a: 0 + } + : { + y: { + a: 0 + } + ? { + a: 0 + } + : { + a: 0 + } + } + }; + +a + ? { + a: function () { + return a + ? { + a: [ + a + ? { + a: 0, + b: [a ? [0, 1] : []] + } + : [ + [ + 0, + { + a: 0 + }, + a ? 0 : 1 + ], + function () { + return a + ? { + a: 0 + } + : [ + { + a: 0 + }, + {} + ]; + } + ] + ] + } + : [ + a + ? function () { + a + ? a( + a + ? { + a: a({ + a: 0 + }) + } + : [ + 0, + a(), + a( + a(), + { + a: 0 + }, + a + ? a() + : a({ + a: 0 + }) + ), + a() + ? { + a: a(), + b: [] + } + : {} + ] + ) + : a( + a() + ? { + a: 0 + } + : (function (a) { + return a() + ? [ + { + a: 0, + b: a() + } + ] + : a([ + a + ? { + a: 0 + } + : {}, + { + a: 0 + } + ]); + })( + a + ? function (a) { + return function () { + return 0; + }; + } + : function (a) { + return function () { + return 1; + }; + } + ) + ); + } + : function () {} + ]; + } + } + : a; + +================================================================================ +`; + +exports[`indent-after-paren.js - {"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" + | printWidth +=====================================input====================================== +foo7 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +foo8 = (condition ? firstValue : secondValue)[SomeType]; + +const foo9 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +function foo10() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo11() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo12() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +foo13 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +foo14 = (condition ? firstValue : secondValue)[SomeType]; + +const foo15 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +function foo16() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo17() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo18() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +foo19 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +foo20 = (condition ? firstValue : secondValue)[SomeType]; + +const foo21 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +function foo22() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo23() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo24() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +foo25 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +foo26 = (condition ? firstValue : secondValue)[SomeType]; + +const foo27 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +function foo28() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo29() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo30() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function* foo31() { + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo.Fooooooooooo]; +} + +const foo32 = new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +function foo33() { + return new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo34() { + throw new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo35() { + void new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +foo36 = new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo)); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo)); + +bifornCringerMoshedPerplexSawder = ( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).annularCooeedSplicesWalksWayWay + .annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay) + .annularCooeedSplicesWalksWayWay(); + +foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.()?.()?.(); + +foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)()()(); + +foo = + foo.bar.baz[ + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ]; + +const decorated = (arg, ignoreRequestError) => { + return ( + typeof arg === "string" || + (arg && arg.valueOf && typeof arg.valueOf() === "string") + ? $delegate(arg, ignoreRequestError) + : handleAsyncOperations(arg, ignoreRequestError) + ).foo(); +}; + +bifornCringerMoshedPerplexSawder = fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +) + +bifornCringerMoshedPerplexSawder = fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +) + +bifornCringerMoshedPerplexSawder = + fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +bifornCringerMoshedPerplexSawder = + fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +=====================================output===================================== +foo7 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)[Fooooooooooo]; + +foo8 = (condition ? firstValue : secondValue)[SomeType]; + +const foo9 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)[Fooooooooooo]; + +function foo10() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[Fooooooooooo]; +} + +function foo11() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[Fooooooooooo]; +} + +function foo12() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[Fooooooooooo]; +} + +foo13 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +foo14 = (condition ? firstValue : secondValue)[SomeType]; + +const foo15 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +function foo16() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo17() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo18() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +foo19 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +foo20 = (condition ? firstValue : secondValue)[SomeType]; + +const foo21 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +function foo22() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo23() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo24() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +foo25 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)?.(Fooooooooooo.Fooooooooooo); + +foo26 = (condition ? firstValue : secondValue)[SomeType]; + +const foo27 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)?.(Fooooooooooo.Fooooooooooo); + +function foo28() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.(Fooooooooooo.Fooooooooooo); +} + +function foo29() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.(Fooooooooooo.Fooooooooooo); +} + +function foo30() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.(Fooooooooooo.Fooooooooooo); +} + +function* foo31() { + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.(Fooooooooooo.Fooooooooooo); + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[Fooooooooooo.Fooooooooooo]; +} + +const foo32 = new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +function foo33() { + return new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo34() { + throw new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo35() { + void new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +foo36 = new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).Fooooooooooo.Fooooooooooo; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).Fooooooooooo.Fooooooooooo; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = ( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol +).annularCooeedSplicesWalksWayWay + .annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay) + .annularCooeedSplicesWalksWayWay(); + +foo = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)?.()?.()?.(); + +foo = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)()()(); + +foo = + foo.bar.baz[ + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ]; + +const decorated = (arg, ignoreRequestError) => { + return ( + typeof arg === "string" || + (arg && arg.valueOf && typeof arg.valueOf() === "string") + ? $delegate(arg, ignoreRequestError) + : handleAsyncOperations(arg, ignoreRequestError) + ).foo(); +}; + +bifornCringerMoshedPerplexSawder = fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +bifornCringerMoshedPerplexSawder = fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +bifornCringerMoshedPerplexSawder = + fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +bifornCringerMoshedPerplexSawder = + fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +================================================================================ +`; + +exports[`indent-after-paren.js - {"tabWidth":4,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +trailingComma: "none" + | printWidth +=====================================input====================================== +foo7 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +foo8 = (condition ? firstValue : secondValue)[SomeType]; + +const foo9 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +function foo10() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo11() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo12() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +foo13 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +foo14 = (condition ? firstValue : secondValue)[SomeType]; + +const foo15 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +function foo16() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo17() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo18() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +foo19 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +foo20 = (condition ? firstValue : secondValue)[SomeType]; + +const foo21 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +function foo22() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo23() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo24() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +foo25 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +foo26 = (condition ? firstValue : secondValue)[SomeType]; + +const foo27 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +function foo28() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo29() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo30() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function* foo31() { + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo.Fooooooooooo]; +} + +const foo32 = new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +function foo33() { + return new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo34() { + throw new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo35() { + void new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +foo36 = new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo)); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo)); + +bifornCringerMoshedPerplexSawder = ( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).annularCooeedSplicesWalksWayWay + .annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay) + .annularCooeedSplicesWalksWayWay(); + +foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.()?.()?.(); + +foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)()()(); + +foo = + foo.bar.baz[ + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ]; + +const decorated = (arg, ignoreRequestError) => { + return ( + typeof arg === "string" || + (arg && arg.valueOf && typeof arg.valueOf() === "string") + ? $delegate(arg, ignoreRequestError) + : handleAsyncOperations(arg, ignoreRequestError) + ).foo(); +}; + +bifornCringerMoshedPerplexSawder = fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +) + +bifornCringerMoshedPerplexSawder = fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +) + +bifornCringerMoshedPerplexSawder = + fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +bifornCringerMoshedPerplexSawder = + fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +=====================================output===================================== +foo7 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)[Fooooooooooo]; + +foo8 = (condition ? firstValue : secondValue)[SomeType]; + +const foo9 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)[Fooooooooooo]; + +function foo10() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[Fooooooooooo]; +} + +function foo11() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[Fooooooooooo]; +} + +function foo12() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[Fooooooooooo]; +} + +foo13 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +foo14 = (condition ? firstValue : secondValue)[SomeType]; + +const foo15 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +function foo16() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo17() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo18() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +foo19 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +foo20 = (condition ? firstValue : secondValue)[SomeType]; + +const foo21 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +function foo22() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo23() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo24() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +foo25 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)?.(Fooooooooooo.Fooooooooooo); + +foo26 = (condition ? firstValue : secondValue)[SomeType]; + +const foo27 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)?.(Fooooooooooo.Fooooooooooo); + +function foo28() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.(Fooooooooooo.Fooooooooooo); +} + +function foo29() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.(Fooooooooooo.Fooooooooooo); +} + +function foo30() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.(Fooooooooooo.Fooooooooooo); +} + +function* foo31() { + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.(Fooooooooooo.Fooooooooooo); + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[Fooooooooooo.Fooooooooooo]; +} + +const foo32 = new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +function foo33() { + return new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo34() { + throw new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo35() { + void new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +foo36 = new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).Fooooooooooo.Fooooooooooo; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).Fooooooooooo.Fooooooooooo; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = ( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol +).annularCooeedSplicesWalksWayWay + .annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay) + .annularCooeedSplicesWalksWayWay(); + +foo = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)?.()?.()?.(); + +foo = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)()()(); + +foo = + foo.bar.baz[ + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ]; + +const decorated = (arg, ignoreRequestError) => { + return ( + typeof arg === "string" || + (arg && arg.valueOf && typeof arg.valueOf() === "string") + ? $delegate(arg, ignoreRequestError) + : handleAsyncOperations(arg, ignoreRequestError) + ).foo(); +}; + +bifornCringerMoshedPerplexSawder = fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +bifornCringerMoshedPerplexSawder = fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +bifornCringerMoshedPerplexSawder = + fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +bifornCringerMoshedPerplexSawder = + fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +================================================================================ +`; + +exports[`indent-after-paren.js - {"useTabs":true,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" +useTabs: true + | printWidth +=====================================input====================================== +foo7 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +foo8 = (condition ? firstValue : secondValue)[SomeType]; + +const foo9 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +function foo10() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo11() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo12() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +foo13 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +foo14 = (condition ? firstValue : secondValue)[SomeType]; + +const foo15 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +function foo16() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo17() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo18() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +foo19 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +foo20 = (condition ? firstValue : secondValue)[SomeType]; + +const foo21 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +function foo22() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo23() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo24() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +foo25 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +foo26 = (condition ? firstValue : secondValue)[SomeType]; + +const foo27 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +function foo28() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo29() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo30() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function* foo31() { + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo.Fooooooooooo]; +} + +const foo32 = new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +function foo33() { + return new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo34() { + throw new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo35() { + void new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +foo36 = new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo)); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo)); + +bifornCringerMoshedPerplexSawder = ( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).annularCooeedSplicesWalksWayWay + .annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay) + .annularCooeedSplicesWalksWayWay(); + +foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.()?.()?.(); + +foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)()()(); + +foo = + foo.bar.baz[ + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ]; + +const decorated = (arg, ignoreRequestError) => { + return ( + typeof arg === "string" || + (arg && arg.valueOf && typeof arg.valueOf() === "string") + ? $delegate(arg, ignoreRequestError) + : handleAsyncOperations(arg, ignoreRequestError) + ).foo(); +}; + +bifornCringerMoshedPerplexSawder = fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +) + +bifornCringerMoshedPerplexSawder = fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +) + +bifornCringerMoshedPerplexSawder = + fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +bifornCringerMoshedPerplexSawder = + fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +=====================================output===================================== +foo7 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)[Fooooooooooo]; + +foo8 = (condition ? firstValue : secondValue)[SomeType]; + +const foo9 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)[Fooooooooooo]; + +function foo10() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[Fooooooooooo]; +} + +function foo11() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[Fooooooooooo]; +} + +function foo12() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[Fooooooooooo]; +} + +foo13 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +foo14 = (condition ? firstValue : secondValue)[SomeType]; + +const foo15 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +function foo16() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo17() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo18() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +foo19 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +foo20 = (condition ? firstValue : secondValue)[SomeType]; + +const foo21 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +function foo22() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo23() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo24() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +foo25 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)?.(Fooooooooooo.Fooooooooooo); + +foo26 = (condition ? firstValue : secondValue)[SomeType]; + +const foo27 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)?.(Fooooooooooo.Fooooooooooo); + +function foo28() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.(Fooooooooooo.Fooooooooooo); +} + +function foo29() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.(Fooooooooooo.Fooooooooooo); +} + +function foo30() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.(Fooooooooooo.Fooooooooooo); +} + +function* foo31() { + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.(Fooooooooooo.Fooooooooooo); + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[Fooooooooooo.Fooooooooooo]; +} + +const foo32 = new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +function foo33() { + return new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo34() { + throw new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo35() { + void new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +foo36 = new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).Fooooooooooo.Fooooooooooo; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).Fooooooooooo.Fooooooooooo; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = ( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol +).annularCooeedSplicesWalksWayWay + .annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay) + .annularCooeedSplicesWalksWayWay(); + +foo = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)?.()?.()?.(); + +foo = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)()()(); + +foo = + foo.bar.baz[ + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ]; + +const decorated = (arg, ignoreRequestError) => { + return ( + typeof arg === "string" || + (arg && arg.valueOf && typeof arg.valueOf() === "string") + ? $delegate(arg, ignoreRequestError) + : handleAsyncOperations(arg, ignoreRequestError) + ).foo(); +}; + +bifornCringerMoshedPerplexSawder = fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +bifornCringerMoshedPerplexSawder = fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +bifornCringerMoshedPerplexSawder = + fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +bifornCringerMoshedPerplexSawder = + fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +================================================================================ +`; + +exports[`indent-after-paren.js - {"useTabs":true,"tabWidth":4,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +trailingComma: "none" +useTabs: true + | printWidth +=====================================input====================================== +foo7 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +foo8 = (condition ? firstValue : secondValue)[SomeType]; + +const foo9 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +function foo10() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo11() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo12() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +foo13 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +foo14 = (condition ? firstValue : secondValue)[SomeType]; + +const foo15 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +function foo16() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo17() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo18() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +foo19 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +foo20 = (condition ? firstValue : secondValue)[SomeType]; + +const foo21 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +function foo22() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo23() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo24() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +foo25 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +foo26 = (condition ? firstValue : secondValue)[SomeType]; + +const foo27 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +function foo28() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo29() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo30() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function* foo31() { + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo.Fooooooooooo]; +} + +const foo32 = new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +function foo33() { + return new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo34() { + throw new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo35() { + void new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +foo36 = new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo)); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo)); + +bifornCringerMoshedPerplexSawder = ( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).annularCooeedSplicesWalksWayWay + .annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay) + .annularCooeedSplicesWalksWayWay(); + +foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.()?.()?.(); + +foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)()()(); + +foo = + foo.bar.baz[ + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ]; + +const decorated = (arg, ignoreRequestError) => { + return ( + typeof arg === "string" || + (arg && arg.valueOf && typeof arg.valueOf() === "string") + ? $delegate(arg, ignoreRequestError) + : handleAsyncOperations(arg, ignoreRequestError) + ).foo(); +}; + +bifornCringerMoshedPerplexSawder = fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +) + +bifornCringerMoshedPerplexSawder = fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +) + +bifornCringerMoshedPerplexSawder = + fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +bifornCringerMoshedPerplexSawder = + fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +=====================================output===================================== +foo7 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)[Fooooooooooo]; + +foo8 = (condition ? firstValue : secondValue)[SomeType]; + +const foo9 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)[Fooooooooooo]; + +function foo10() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[Fooooooooooo]; +} + +function foo11() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[Fooooooooooo]; +} + +function foo12() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[Fooooooooooo]; +} + +foo13 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +foo14 = (condition ? firstValue : secondValue)[SomeType]; + +const foo15 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +function foo16() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo17() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo18() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +foo19 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +foo20 = (condition ? firstValue : secondValue)[SomeType]; + +const foo21 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +function foo22() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo23() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo24() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +foo25 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)?.(Fooooooooooo.Fooooooooooo); + +foo26 = (condition ? firstValue : secondValue)[SomeType]; + +const foo27 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)?.(Fooooooooooo.Fooooooooooo); + +function foo28() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.(Fooooooooooo.Fooooooooooo); +} + +function foo29() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.(Fooooooooooo.Fooooooooooo); +} + +function foo30() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.(Fooooooooooo.Fooooooooooo); +} + +function* foo31() { + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.(Fooooooooooo.Fooooooooooo); + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[Fooooooooooo.Fooooooooooo]; +} + +const foo32 = new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +function foo33() { + return new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo34() { + throw new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo35() { + void new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +foo36 = new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).Fooooooooooo.Fooooooooooo; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).Fooooooooooo.Fooooooooooo; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = ( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol +).annularCooeedSplicesWalksWayWay + .annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay) + .annularCooeedSplicesWalksWayWay(); + +foo = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)?.()?.()?.(); + +foo = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)()()(); + +foo = + foo.bar.baz[ + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ]; + +const decorated = (arg, ignoreRequestError) => { + return ( + typeof arg === "string" || + (arg && arg.valueOf && typeof arg.valueOf() === "string") + ? $delegate(arg, ignoreRequestError) + : handleAsyncOperations(arg, ignoreRequestError) + ).foo(); +}; + +bifornCringerMoshedPerplexSawder = fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +bifornCringerMoshedPerplexSawder = fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +bifornCringerMoshedPerplexSawder = + fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +bifornCringerMoshedPerplexSawder = + fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +================================================================================ +`; + +exports[`nested.js - {"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" + | printWidth +=====================================input====================================== +let icecream = what == "cone" + ? p => !!p ? \`here's your \${p} cone\` : \`just the empty cone for you\` + : p => \`here's your \${p} \${what}\`; + +const value = condition1 +? value1 +: condition2 + ? value2 + : condition3 + ? value3 + : value4; + + +const StorybookLoader = ({ match }) => ( + match.params.storyId === "button" + ? + : match.params.storyId === "color" + ? + : match.params.storyId === "typography" + ? + : match.params.storyId === "loading" + ? + : match.params.storyId === "deal-list" + ? + : ( + + {'Missing story book'} + + + + + ) +) + +const message = + i % 3 === 0 && i % 5 === 0 ? + 'fizzbuzz' + : i % 3 === 0 ? + 'fizz' + : i % 5 === 0 ? + 'buzz' + : + String(i) + +const paymentMessage = state == 'success' + ? 'Payment completed successfully' + +: state == 'processing' + ? 'Payment processing' + +: state == 'invalid_cvc' + ? 'There was an issue with your CVC number' + +: state == 'invalid_expiry' + ? 'Expiry must be sometime in the past.' + + : 'There was an issue with the payment. Please contact support.' + +const paymentMessage2 = state == 'success' + ? 1 //'Payment completed successfully' + +: state == 'processing' + ? 2 //'Payment processing' + +: state == 'invalid_cvc' + ? 3 //'There was an issue with your CVC number' + +: true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + + : 5 // 'There was an issue with the payment. Please contact support.' + +const foo =
+ {medals[0].record ? ( + i18n('Record') + ) : medals[0].unique ? ( + i18n('Unique') + ) : medals[0].type === 0 ? ( + i18n('Silver') + ) : medals[0].type === 1 ? ( + i18n('Gold') + ) : medals[0].type === 2 ? ( + i18n('Platinum') + ) : ( + i18n('Theme') + )} +
+ +a + ? literalline + : { + 123: 12 + } + ? line + : softline + +=====================================output===================================== +let icecream = + what == "cone" + ? p => (!!p ? \`here's your \${p} cone\` : \`just the empty cone for you\`) + : p => \`here's your \${p} \${what}\`; + +const value = condition1 + ? value1 + : condition2 + ? value2 + : condition3 + ? value3 + : value4; + +const StorybookLoader = ({ match }) => + match.params.storyId === "button" ? ( + + ) : match.params.storyId === "color" ? ( + + ) : match.params.storyId === "typography" ? ( + + ) : match.params.storyId === "loading" ? ( + + ) : match.params.storyId === "deal-list" ? ( + + ) : ( + + {"Missing story book"} + + + + + ); + +const message = + i % 3 === 0 && i % 5 === 0 + ? "fizzbuzz" + : i % 3 === 0 + ? "fizz" + : i % 5 === 0 + ? "buzz" + : String(i); + +const paymentMessage = + state == "success" + ? "Payment completed successfully" + : state == "processing" + ? "Payment processing" + : state == "invalid_cvc" + ? "There was an issue with your CVC number" + : state == "invalid_expiry" + ? "Expiry must be sometime in the past." + : "There was an issue with the payment. Please contact support."; + +const paymentMessage2 = + state == "success" + ? 1 //'Payment completed successfully' + : state == "processing" + ? 2 //'Payment processing' + : state == "invalid_cvc" + ? 3 //'There was an issue with your CVC number' + : true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + : 5; // 'There was an issue with the payment. Please contact support.' + +const foo = ( +
+ {medals[0].record + ? i18n("Record") + : medals[0].unique + ? i18n("Unique") + : medals[0].type === 0 + ? i18n("Silver") + : medals[0].type === 1 + ? i18n("Gold") + : medals[0].type === 2 + ? i18n("Platinum") + : i18n("Theme")} +
+); + +a + ? literalline + : { + 123: 12 + } + ? line + : softline; + +================================================================================ +`; + +exports[`nested.js - {"tabWidth":4,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +trailingComma: "none" + | printWidth +=====================================input====================================== +let icecream = what == "cone" + ? p => !!p ? \`here's your \${p} cone\` : \`just the empty cone for you\` + : p => \`here's your \${p} \${what}\`; + +const value = condition1 +? value1 +: condition2 + ? value2 + : condition3 + ? value3 + : value4; + + +const StorybookLoader = ({ match }) => ( + match.params.storyId === "button" + ? + : match.params.storyId === "color" + ? + : match.params.storyId === "typography" + ? + : match.params.storyId === "loading" + ? + : match.params.storyId === "deal-list" + ? + : ( + + {'Missing story book'} + + + + + ) +) + +const message = + i % 3 === 0 && i % 5 === 0 ? + 'fizzbuzz' + : i % 3 === 0 ? + 'fizz' + : i % 5 === 0 ? + 'buzz' + : + String(i) + +const paymentMessage = state == 'success' + ? 'Payment completed successfully' + +: state == 'processing' + ? 'Payment processing' + +: state == 'invalid_cvc' + ? 'There was an issue with your CVC number' + +: state == 'invalid_expiry' + ? 'Expiry must be sometime in the past.' + + : 'There was an issue with the payment. Please contact support.' + +const paymentMessage2 = state == 'success' + ? 1 //'Payment completed successfully' + +: state == 'processing' + ? 2 //'Payment processing' + +: state == 'invalid_cvc' + ? 3 //'There was an issue with your CVC number' + +: true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + + : 5 // 'There was an issue with the payment. Please contact support.' + +const foo =
+ {medals[0].record ? ( + i18n('Record') + ) : medals[0].unique ? ( + i18n('Unique') + ) : medals[0].type === 0 ? ( + i18n('Silver') + ) : medals[0].type === 1 ? ( + i18n('Gold') + ) : medals[0].type === 2 ? ( + i18n('Platinum') + ) : ( + i18n('Theme') + )} +
+ +a + ? literalline + : { + 123: 12 + } + ? line + : softline + +=====================================output===================================== +let icecream = + what == "cone" + ? p => (!!p ? \`here's your \${p} cone\` : \`just the empty cone for you\`) + : p => \`here's your \${p} \${what}\`; + +const value = condition1 + ? value1 + : condition2 + ? value2 + : condition3 + ? value3 + : value4; + +const StorybookLoader = ({ match }) => + match.params.storyId === "button" ? ( + + ) : match.params.storyId === "color" ? ( + + ) : match.params.storyId === "typography" ? ( + + ) : match.params.storyId === "loading" ? ( + + ) : match.params.storyId === "deal-list" ? ( + + ) : ( + + {"Missing story book"} + + + + + ); + +const message = + i % 3 === 0 && i % 5 === 0 + ? "fizzbuzz" + : i % 3 === 0 + ? "fizz" + : i % 5 === 0 + ? "buzz" + : String(i); + +const paymentMessage = + state == "success" + ? "Payment completed successfully" + : state == "processing" + ? "Payment processing" + : state == "invalid_cvc" + ? "There was an issue with your CVC number" + : state == "invalid_expiry" + ? "Expiry must be sometime in the past." + : "There was an issue with the payment. Please contact support."; + +const paymentMessage2 = + state == "success" + ? 1 //'Payment completed successfully' + : state == "processing" + ? 2 //'Payment processing' + : state == "invalid_cvc" + ? 3 //'There was an issue with your CVC number' + : true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + : 5; // 'There was an issue with the payment. Please contact support.' + +const foo = ( +
+ {medals[0].record + ? i18n("Record") + : medals[0].unique + ? i18n("Unique") + : medals[0].type === 0 + ? i18n("Silver") + : medals[0].type === 1 + ? i18n("Gold") + : medals[0].type === 2 + ? i18n("Platinum") + : i18n("Theme")} +
+); + +a + ? literalline + : { + 123: 12 + } + ? line + : softline; + +================================================================================ +`; + +exports[`nested.js - {"useTabs":true,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" +useTabs: true + | printWidth +=====================================input====================================== +let icecream = what == "cone" + ? p => !!p ? \`here's your \${p} cone\` : \`just the empty cone for you\` + : p => \`here's your \${p} \${what}\`; + +const value = condition1 +? value1 +: condition2 + ? value2 + : condition3 + ? value3 + : value4; + + +const StorybookLoader = ({ match }) => ( + match.params.storyId === "button" + ? + : match.params.storyId === "color" + ? + : match.params.storyId === "typography" + ? + : match.params.storyId === "loading" + ? + : match.params.storyId === "deal-list" + ? + : ( + + {'Missing story book'} + + + + + ) +) + +const message = + i % 3 === 0 && i % 5 === 0 ? + 'fizzbuzz' + : i % 3 === 0 ? + 'fizz' + : i % 5 === 0 ? + 'buzz' + : + String(i) + +const paymentMessage = state == 'success' + ? 'Payment completed successfully' + +: state == 'processing' + ? 'Payment processing' + +: state == 'invalid_cvc' + ? 'There was an issue with your CVC number' + +: state == 'invalid_expiry' + ? 'Expiry must be sometime in the past.' + + : 'There was an issue with the payment. Please contact support.' + +const paymentMessage2 = state == 'success' + ? 1 //'Payment completed successfully' + +: state == 'processing' + ? 2 //'Payment processing' + +: state == 'invalid_cvc' + ? 3 //'There was an issue with your CVC number' + +: true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + + : 5 // 'There was an issue with the payment. Please contact support.' + +const foo =
+ {medals[0].record ? ( + i18n('Record') + ) : medals[0].unique ? ( + i18n('Unique') + ) : medals[0].type === 0 ? ( + i18n('Silver') + ) : medals[0].type === 1 ? ( + i18n('Gold') + ) : medals[0].type === 2 ? ( + i18n('Platinum') + ) : ( + i18n('Theme') + )} +
+ +a + ? literalline + : { + 123: 12 + } + ? line + : softline + +=====================================output===================================== +let icecream = + what == "cone" + ? p => (!!p ? \`here's your \${p} cone\` : \`just the empty cone for you\`) + : p => \`here's your \${p} \${what}\`; + +const value = condition1 + ? value1 + : condition2 + ? value2 + : condition3 + ? value3 + : value4; + +const StorybookLoader = ({ match }) => + match.params.storyId === "button" ? ( + + ) : match.params.storyId === "color" ? ( + + ) : match.params.storyId === "typography" ? ( + + ) : match.params.storyId === "loading" ? ( + + ) : match.params.storyId === "deal-list" ? ( + + ) : ( + + {"Missing story book"} + + + + + ); + +const message = + i % 3 === 0 && i % 5 === 0 + ? "fizzbuzz" + : i % 3 === 0 + ? "fizz" + : i % 5 === 0 + ? "buzz" + : String(i); + +const paymentMessage = + state == "success" + ? "Payment completed successfully" + : state == "processing" + ? "Payment processing" + : state == "invalid_cvc" + ? "There was an issue with your CVC number" + : state == "invalid_expiry" + ? "Expiry must be sometime in the past." + : "There was an issue with the payment. Please contact support."; + +const paymentMessage2 = + state == "success" + ? 1 //'Payment completed successfully' + : state == "processing" + ? 2 //'Payment processing' + : state == "invalid_cvc" + ? 3 //'There was an issue with your CVC number' + : true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + : 5; // 'There was an issue with the payment. Please contact support.' + +const foo = ( +
+ {medals[0].record + ? i18n("Record") + : medals[0].unique + ? i18n("Unique") + : medals[0].type === 0 + ? i18n("Silver") + : medals[0].type === 1 + ? i18n("Gold") + : medals[0].type === 2 + ? i18n("Platinum") + : i18n("Theme")} +
+); + +a + ? literalline + : { + 123: 12 + } + ? line + : softline; + +================================================================================ +`; + +exports[`nested.js - {"useTabs":true,"tabWidth":4,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +trailingComma: "none" +useTabs: true + | printWidth +=====================================input====================================== +let icecream = what == "cone" + ? p => !!p ? \`here's your \${p} cone\` : \`just the empty cone for you\` + : p => \`here's your \${p} \${what}\`; + +const value = condition1 +? value1 +: condition2 + ? value2 + : condition3 + ? value3 + : value4; + + +const StorybookLoader = ({ match }) => ( + match.params.storyId === "button" + ? + : match.params.storyId === "color" + ? + : match.params.storyId === "typography" + ? + : match.params.storyId === "loading" + ? + : match.params.storyId === "deal-list" + ? + : ( + + {'Missing story book'} + + + + + ) +) + +const message = + i % 3 === 0 && i % 5 === 0 ? + 'fizzbuzz' + : i % 3 === 0 ? + 'fizz' + : i % 5 === 0 ? + 'buzz' + : + String(i) + +const paymentMessage = state == 'success' + ? 'Payment completed successfully' + +: state == 'processing' + ? 'Payment processing' + +: state == 'invalid_cvc' + ? 'There was an issue with your CVC number' + +: state == 'invalid_expiry' + ? 'Expiry must be sometime in the past.' + + : 'There was an issue with the payment. Please contact support.' + +const paymentMessage2 = state == 'success' + ? 1 //'Payment completed successfully' + +: state == 'processing' + ? 2 //'Payment processing' + +: state == 'invalid_cvc' + ? 3 //'There was an issue with your CVC number' + +: true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + + : 5 // 'There was an issue with the payment. Please contact support.' + +const foo =
+ {medals[0].record ? ( + i18n('Record') + ) : medals[0].unique ? ( + i18n('Unique') + ) : medals[0].type === 0 ? ( + i18n('Silver') + ) : medals[0].type === 1 ? ( + i18n('Gold') + ) : medals[0].type === 2 ? ( + i18n('Platinum') + ) : ( + i18n('Theme') + )} +
+ +a + ? literalline + : { + 123: 12 + } + ? line + : softline + +=====================================output===================================== +let icecream = + what == "cone" + ? p => (!!p ? \`here's your \${p} cone\` : \`just the empty cone for you\`) + : p => \`here's your \${p} \${what}\`; + +const value = condition1 + ? value1 + : condition2 + ? value2 + : condition3 + ? value3 + : value4; + +const StorybookLoader = ({ match }) => + match.params.storyId === "button" ? ( + + ) : match.params.storyId === "color" ? ( + + ) : match.params.storyId === "typography" ? ( + + ) : match.params.storyId === "loading" ? ( + + ) : match.params.storyId === "deal-list" ? ( + + ) : ( + + {"Missing story book"} + + + + + ); + +const message = + i % 3 === 0 && i % 5 === 0 + ? "fizzbuzz" + : i % 3 === 0 + ? "fizz" + : i % 5 === 0 + ? "buzz" + : String(i); + +const paymentMessage = + state == "success" + ? "Payment completed successfully" + : state == "processing" + ? "Payment processing" + : state == "invalid_cvc" + ? "There was an issue with your CVC number" + : state == "invalid_expiry" + ? "Expiry must be sometime in the past." + : "There was an issue with the payment. Please contact support."; + +const paymentMessage2 = + state == "success" + ? 1 //'Payment completed successfully' + : state == "processing" + ? 2 //'Payment processing' + : state == "invalid_cvc" + ? 3 //'There was an issue with your CVC number' + : true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + : 5; // 'There was an issue with the payment. Please contact support.' + +const foo = ( +
+ {medals[0].record + ? i18n("Record") + : medals[0].unique + ? i18n("Unique") + : medals[0].type === 0 + ? i18n("Silver") + : medals[0].type === 1 + ? i18n("Gold") + : medals[0].type === 2 + ? i18n("Platinum") + : i18n("Theme")} +
+); + +a + ? literalline + : { + 123: 12 + } + ? line + : softline; + +================================================================================ +`; + +exports[`nested-in-condition.js - {"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" + | printWidth +=====================================input====================================== +$var = ($number % 10 >= 2 && ($number % 100 < 10 || $number % 100 >= 20) +? kochabCooieGameOnOboleUnweave +: annularCooeedSplicesWalksWayWay) + ? anodyneCondosMalateOverateRetinol + : averredBathersBoxroomBuggyNurl; + +const value = (bifornCringerMoshedPerplexSawder +? askTrovenaBeenaDependsRowans +: glimseGlyphsHazardNoopsTieTie) + ? true + ? true + : false + : true + ? true + : false; + +(bifornCringerMoshedPerplexSawder ? ( + askTrovenaBeenaDependsRowans +) : ( + glimseGlyphsHazardNoopsTieTie +)) ? ( + + + + + + + + +) : ( + + + + + +); + +=====================================output===================================== +$var = ( + $number % 10 >= 2 && ($number % 100 < 10 || $number % 100 >= 20) + ? kochabCooieGameOnOboleUnweave + : annularCooeedSplicesWalksWayWay +) + ? anodyneCondosMalateOverateRetinol + : averredBathersBoxroomBuggyNurl; + +const value = ( + bifornCringerMoshedPerplexSawder + ? askTrovenaBeenaDependsRowans + : glimseGlyphsHazardNoopsTieTie +) + ? true + ? true + : false + : true + ? true + : false; + +( + bifornCringerMoshedPerplexSawder + ? askTrovenaBeenaDependsRowans + : glimseGlyphsHazardNoopsTieTie +) ? ( + + + + + + + + +) : ( + + + + + +); + +================================================================================ +`; + +exports[`nested-in-condition.js - {"tabWidth":4,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +trailingComma: "none" + | printWidth +=====================================input====================================== +$var = ($number % 10 >= 2 && ($number % 100 < 10 || $number % 100 >= 20) +? kochabCooieGameOnOboleUnweave +: annularCooeedSplicesWalksWayWay) + ? anodyneCondosMalateOverateRetinol + : averredBathersBoxroomBuggyNurl; + +const value = (bifornCringerMoshedPerplexSawder +? askTrovenaBeenaDependsRowans +: glimseGlyphsHazardNoopsTieTie) + ? true + ? true + : false + : true + ? true + : false; + +(bifornCringerMoshedPerplexSawder ? ( + askTrovenaBeenaDependsRowans +) : ( + glimseGlyphsHazardNoopsTieTie +)) ? ( + + + + + + + + +) : ( + + + + + +); + +=====================================output===================================== +$var = ( + $number % 10 >= 2 && ($number % 100 < 10 || $number % 100 >= 20) + ? kochabCooieGameOnOboleUnweave + : annularCooeedSplicesWalksWayWay +) + ? anodyneCondosMalateOverateRetinol + : averredBathersBoxroomBuggyNurl; + +const value = ( + bifornCringerMoshedPerplexSawder + ? askTrovenaBeenaDependsRowans + : glimseGlyphsHazardNoopsTieTie +) + ? true + ? true + : false + : true + ? true + : false; + +( + bifornCringerMoshedPerplexSawder + ? askTrovenaBeenaDependsRowans + : glimseGlyphsHazardNoopsTieTie +) ? ( + + + + + + + + +) : ( + + + + + +); + +================================================================================ +`; + +exports[`nested-in-condition.js - {"useTabs":true,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" +useTabs: true + | printWidth +=====================================input====================================== +$var = ($number % 10 >= 2 && ($number % 100 < 10 || $number % 100 >= 20) +? kochabCooieGameOnOboleUnweave +: annularCooeedSplicesWalksWayWay) + ? anodyneCondosMalateOverateRetinol + : averredBathersBoxroomBuggyNurl; + +const value = (bifornCringerMoshedPerplexSawder +? askTrovenaBeenaDependsRowans +: glimseGlyphsHazardNoopsTieTie) + ? true + ? true + : false + : true + ? true + : false; + +(bifornCringerMoshedPerplexSawder ? ( + askTrovenaBeenaDependsRowans +) : ( + glimseGlyphsHazardNoopsTieTie +)) ? ( + + + + + + + + +) : ( + + + + + +); + +=====================================output===================================== +$var = ( + $number % 10 >= 2 && ($number % 100 < 10 || $number % 100 >= 20) + ? kochabCooieGameOnOboleUnweave + : annularCooeedSplicesWalksWayWay +) + ? anodyneCondosMalateOverateRetinol + : averredBathersBoxroomBuggyNurl; + +const value = ( + bifornCringerMoshedPerplexSawder + ? askTrovenaBeenaDependsRowans + : glimseGlyphsHazardNoopsTieTie +) + ? true + ? true + : false + : true + ? true + : false; + +( + bifornCringerMoshedPerplexSawder + ? askTrovenaBeenaDependsRowans + : glimseGlyphsHazardNoopsTieTie +) ? ( + + + + + + + + +) : ( + + + + + +); + +================================================================================ +`; + +exports[`nested-in-condition.js - {"useTabs":true,"tabWidth":4,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +trailingComma: "none" +useTabs: true + | printWidth +=====================================input====================================== +$var = ($number % 10 >= 2 && ($number % 100 < 10 || $number % 100 >= 20) +? kochabCooieGameOnOboleUnweave +: annularCooeedSplicesWalksWayWay) + ? anodyneCondosMalateOverateRetinol + : averredBathersBoxroomBuggyNurl; + +const value = (bifornCringerMoshedPerplexSawder +? askTrovenaBeenaDependsRowans +: glimseGlyphsHazardNoopsTieTie) + ? true + ? true + : false + : true + ? true + : false; + +(bifornCringerMoshedPerplexSawder ? ( + askTrovenaBeenaDependsRowans +) : ( + glimseGlyphsHazardNoopsTieTie +)) ? ( + + + + + + + + +) : ( + + + + + +); + +=====================================output===================================== +$var = ( + $number % 10 >= 2 && ($number % 100 < 10 || $number % 100 >= 20) + ? kochabCooieGameOnOboleUnweave + : annularCooeedSplicesWalksWayWay +) + ? anodyneCondosMalateOverateRetinol + : averredBathersBoxroomBuggyNurl; + +const value = ( + bifornCringerMoshedPerplexSawder + ? askTrovenaBeenaDependsRowans + : glimseGlyphsHazardNoopsTieTie +) + ? true + ? true + : false + : true + ? true + : false; + +( + bifornCringerMoshedPerplexSawder + ? askTrovenaBeenaDependsRowans + : glimseGlyphsHazardNoopsTieTie +) ? ( + + + + + + + + +) : ( + + + + + +); + +================================================================================ +`; + +exports[`parenthesis.js - {"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" + | printWidth +=====================================input====================================== +debug ? this.state.isVisible ? "partially visible" : "hidden" : null; +debug ? this.state.isVisible && somethingComplex ? "partially visible" : "hidden" : null; + +a => a ? () => {a} : () => {a} +a => a ? a : a +a => a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a + +=====================================output===================================== +debug ? (this.state.isVisible ? "partially visible" : "hidden") : null; +debug + ? this.state.isVisible && somethingComplex + ? "partially visible" + : "hidden" + : null; + +a => + a + ? () => { + a; + } + : () => { + a; + }; +a => (a ? a : a); +a => + a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a; + +================================================================================ +`; + +exports[`parenthesis.js - {"tabWidth":4,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +trailingComma: "none" + | printWidth +=====================================input====================================== +debug ? this.state.isVisible ? "partially visible" : "hidden" : null; +debug ? this.state.isVisible && somethingComplex ? "partially visible" : "hidden" : null; + +a => a ? () => {a} : () => {a} +a => a ? a : a +a => a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a + +=====================================output===================================== +debug ? (this.state.isVisible ? "partially visible" : "hidden") : null; +debug + ? this.state.isVisible && somethingComplex + ? "partially visible" + : "hidden" + : null; + +a => + a + ? () => { + a; + } + : () => { + a; + }; +a => (a ? a : a); +a => + a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a; + +================================================================================ +`; + +exports[`parenthesis.js - {"useTabs":true,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" +useTabs: true + | printWidth +=====================================input====================================== +debug ? this.state.isVisible ? "partially visible" : "hidden" : null; +debug ? this.state.isVisible && somethingComplex ? "partially visible" : "hidden" : null; + +a => a ? () => {a} : () => {a} +a => a ? a : a +a => a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a + +=====================================output===================================== +debug ? (this.state.isVisible ? "partially visible" : "hidden") : null; +debug + ? this.state.isVisible && somethingComplex + ? "partially visible" + : "hidden" + : null; + +a => + a + ? () => { + a; + } + : () => { + a; + }; +a => (a ? a : a); +a => + a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a; + +================================================================================ +`; + +exports[`parenthesis.js - {"useTabs":true,"tabWidth":4,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +trailingComma: "none" +useTabs: true + | printWidth +=====================================input====================================== +debug ? this.state.isVisible ? "partially visible" : "hidden" : null; +debug ? this.state.isVisible && somethingComplex ? "partially visible" : "hidden" : null; + +a => a ? () => {a} : () => {a} +a => a ? a : a +a => a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a + +=====================================output===================================== +debug ? (this.state.isVisible ? "partially visible" : "hidden") : null; +debug + ? this.state.isVisible && somethingComplex + ? "partially visible" + : "hidden" + : null; + +a => + a + ? () => { + a; + } + : () => { + a; + }; +a => (a ? a : a); +a => + a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a; + +================================================================================ +`; + +exports[`test.js - {"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" + | printWidth +=====================================input====================================== +const obj0 = conditionIsTruthy ? shortThing : otherShortThing + +const obj1 = conditionIsTruthy ? { some: 'long', object: 'with', lots: 'of', stuff } : shortThing + +const obj2 = conditionIsTruthy ? shortThing : { some: 'long', object: 'with', lots: 'of', stuff } + +const obj3 = conditionIsTruthy ? { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } : shortThing + +const obj4 = conditionIsTruthy ? shortThing : { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } + +const obj5 = conditionIsTruthy ? { some: 'long', object: 'with', lots: 'of', stuff } : { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } + +=====================================output===================================== +const obj0 = conditionIsTruthy ? shortThing : otherShortThing; + +const obj1 = conditionIsTruthy + ? { some: "long", object: "with", lots: "of", stuff } + : shortThing; + +const obj2 = conditionIsTruthy + ? shortThing + : { some: "long", object: "with", lots: "of", stuff }; + +const obj3 = conditionIsTruthy + ? { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff + } + : shortThing; + +const obj4 = conditionIsTruthy + ? shortThing + : { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff + }; + +const obj5 = conditionIsTruthy + ? { some: "long", object: "with", lots: "of", stuff } + : { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff + }; + +================================================================================ +`; + +exports[`test.js - {"tabWidth":4,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +trailingComma: "none" + | printWidth +=====================================input====================================== +const obj0 = conditionIsTruthy ? shortThing : otherShortThing + +const obj1 = conditionIsTruthy ? { some: 'long', object: 'with', lots: 'of', stuff } : shortThing + +const obj2 = conditionIsTruthy ? shortThing : { some: 'long', object: 'with', lots: 'of', stuff } + +const obj3 = conditionIsTruthy ? { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } : shortThing + +const obj4 = conditionIsTruthy ? shortThing : { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } + +const obj5 = conditionIsTruthy ? { some: 'long', object: 'with', lots: 'of', stuff } : { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } + +=====================================output===================================== +const obj0 = conditionIsTruthy ? shortThing : otherShortThing; + +const obj1 = conditionIsTruthy + ? { some: "long", object: "with", lots: "of", stuff } + : shortThing; + +const obj2 = conditionIsTruthy + ? shortThing + : { some: "long", object: "with", lots: "of", stuff }; + +const obj3 = conditionIsTruthy + ? { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff + } + : shortThing; + +const obj4 = conditionIsTruthy + ? shortThing + : { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff + }; + +const obj5 = conditionIsTruthy + ? { some: "long", object: "with", lots: "of", stuff } + : { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff + }; + +================================================================================ +`; + +exports[`test.js - {"useTabs":true,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" +useTabs: true + | printWidth +=====================================input====================================== +const obj0 = conditionIsTruthy ? shortThing : otherShortThing + +const obj1 = conditionIsTruthy ? { some: 'long', object: 'with', lots: 'of', stuff } : shortThing + +const obj2 = conditionIsTruthy ? shortThing : { some: 'long', object: 'with', lots: 'of', stuff } + +const obj3 = conditionIsTruthy ? { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } : shortThing + +const obj4 = conditionIsTruthy ? shortThing : { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } + +const obj5 = conditionIsTruthy ? { some: 'long', object: 'with', lots: 'of', stuff } : { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } + +=====================================output===================================== +const obj0 = conditionIsTruthy ? shortThing : otherShortThing; + +const obj1 = conditionIsTruthy + ? { some: "long", object: "with", lots: "of", stuff } + : shortThing; + +const obj2 = conditionIsTruthy + ? shortThing + : { some: "long", object: "with", lots: "of", stuff }; + +const obj3 = conditionIsTruthy + ? { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff + } + : shortThing; + +const obj4 = conditionIsTruthy + ? shortThing + : { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff + }; + +const obj5 = conditionIsTruthy + ? { some: "long", object: "with", lots: "of", stuff } + : { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff + }; + +================================================================================ +`; + +exports[`test.js - {"useTabs":true,"tabWidth":4,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +trailingComma: "none" +useTabs: true + | printWidth +=====================================input====================================== +const obj0 = conditionIsTruthy ? shortThing : otherShortThing + +const obj1 = conditionIsTruthy ? { some: 'long', object: 'with', lots: 'of', stuff } : shortThing + +const obj2 = conditionIsTruthy ? shortThing : { some: 'long', object: 'with', lots: 'of', stuff } + +const obj3 = conditionIsTruthy ? { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } : shortThing + +const obj4 = conditionIsTruthy ? shortThing : { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } + +const obj5 = conditionIsTruthy ? { some: 'long', object: 'with', lots: 'of', stuff } : { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } + +=====================================output===================================== +const obj0 = conditionIsTruthy ? shortThing : otherShortThing; + +const obj1 = conditionIsTruthy + ? { some: "long", object: "with", lots: "of", stuff } + : shortThing; + +const obj2 = conditionIsTruthy + ? shortThing + : { some: "long", object: "with", lots: "of", stuff }; + +const obj3 = conditionIsTruthy + ? { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff + } + : shortThing; + +const obj4 = conditionIsTruthy + ? shortThing + : { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff + }; + +const obj5 = conditionIsTruthy + ? { some: "long", object: "with", lots: "of", stuff } + : { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff + }; + +================================================================================ +`; diff --git a/tests/format/js/ternaries/with-balanced-formatting/jsfmt.spec.js b/tests/format/js/ternaries/with-balanced-formatting/jsfmt.spec.js new file mode 100644 index 0000000000..d384392d16 --- /dev/null +++ b/tests/format/js/ternaries/with-balanced-formatting/jsfmt.spec.js @@ -0,0 +1,48 @@ +// [prettierx] test script notice: +// This test script runs for test files in parent directory, +// **not** on any files in *this* directory. + +const dirPath = `${__dirname}/..`; + +run_spec(dirPath, ["babel", "babel-flow", "flow", "typescript"], { + // [prettierx] balanced ternary formatting option + // (with improved consistency with "Standard JS"): + offsetTernaryExpressions: true, + // [prettierx] more options needed for consistency with "Standard JS": + arrowParens: "avoid", + trailingComma: "none", +}); + +run_spec(dirPath, ["babel", "babel-flow", "flow", "typescript"], { + // variation from ../jsfmt.spec.js: + tabWidth: 4, + // [prettierx] balanced ternary formatting option + // (with improved consistency with "Standard JS"): + offsetTernaryExpressions: true, + // [prettierx] more options needed for consistency with "Standard JS": + arrowParens: "avoid", + trailingComma: "none", +}); + +run_spec(dirPath, ["babel", "babel-flow", "flow", "typescript"], { + // variation from ../jsfmt.spec.js: + useTabs: true, + // [prettierx] balanced ternary formatting option + // (with improved consistency with "Standard JS"): + offsetTernaryExpressions: true, + // [prettierx] more options needed for consistency with "Standard JS": + arrowParens: "avoid", + trailingComma: "none", +}); + +run_spec(dirPath, ["babel", "babel-flow", "flow", "typescript"], { + // variation from ../jsfmt.spec.js: + useTabs: true, + tabWidth: 4, + // [prettierx] balanced ternary formatting option + // (with improved consistency with "Standard JS"): + offsetTernaryExpressions: true, + // [prettierx] more options needed for consistency with "Standard JS": + arrowParens: "avoid", + trailingComma: "none", +}); diff --git a/tests/format/js/ternaries/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/ternaries/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..5b02138b17 --- /dev/null +++ b/tests/format/js/ternaries/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,1491 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`binary.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +trailingComma: "none" + | printWidth +=====================================input====================================== +const funnelSnapshotCard = (report === MY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2) || + (report === COMPANY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2_company_metrics) + ? + : null; + +room = room.map((row, rowIndex) => ( + row.map((col, colIndex) => ( + (rowIndex === 0 || colIndex === 0 || rowIndex === height || colIndex === width) ? 1 : 0 + )) +)) + +=====================================output===================================== +const funnelSnapshotCard = + ( report === MY_OVERVIEW && ! ReportGK.xar_metrics_active_capitol_v2 ) || + ( report === COMPANY_OVERVIEW && + ! ReportGK.xar_metrics_active_capitol_v2_company_metrics ) ? ( + + ) : null; + +room = room.map( ( row, rowIndex ) => + row.map( ( col, colIndex ) => + rowIndex === 0 || + colIndex === 0 || + rowIndex === height || + colIndex === width + ? 1 + : 0 + ) +); + +================================================================================ +`; + +exports[`func-call.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +trailingComma: "none" + | printWidth +=====================================input====================================== +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ? annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave +); + +=====================================output===================================== +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ? annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave +); + +================================================================================ +`; + +exports[`indent.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +trailingComma: "none" + | printWidth +=====================================input====================================== +aaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb : ccccccccccccccc ? ddddddddddddddd : eeeeeeeeeeeeeee ? fffffffffffffff : gggggggggggggggg + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +a + ? { + a: 0 + } + : { + a: { + a: 0 + } + ? { + a: 0 + } + : { + y: { + a: 0 + } + ? { + a: 0 + } + : { + a: 0 + } + } + } + +a + ? { + a: function() { + return a + ? { + a: [ + a + ? { + a: 0, + b: [ + a + ? [ + 0, + 1 + ] + : [] + ] + } + : [ + [ + 0, + { + a: 0 + }, + a + ? 0 + : 1 + ], + function() { + return a + ? { + a: 0 + } + : [ + { + a: 0 + }, + {} + ]; + } + ] + ] + } + : [ + a + ? function() { + a + ? a( + a + ? { + a: a( + { + a: 0 + } + ) + } + : [ + 0, + a(), + a( + a(), + { + a: 0 + }, + a + ? a() + : a( + { + a: 0 + } + ) + ), + a() + ? { + a: a(), + b: [] + } + : {} + ] + ): + a( + a() + ? { + a: 0 + } + : (function(a) { + return a() + ? [ + { + a: 0, + b: a() + } + ] + : a( + [ + a + ? { + a: 0 + } + : {}, + { + a: 0 + } + ] + ); + })( + a + ? function(a) { + return function() { + return 0; + }; + } + : function(a) { + return function() { + return 1; + } + } + ) + ); + } + : function() { + + } + ]; + } + } + : a; + +=====================================output===================================== +aaaaaaaaaaaaaaa + ? bbbbbbbbbbbbbbbbbb + : ccccccccccccccc + ? ddddddddddddddd + : eeeeeeeeeeeeeee + ? fffffffffffffff + : gggggggggggggggg; + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; + +a + ? { + a: 0 + } + : { + a: { + a: 0 + } + ? { + a: 0 + } + : { + y: { + a: 0 + } + ? { + a: 0 + } + : { + a: 0 + } + } + }; + +a + ? { + a: function () { + return a + ? { + a: [ + a + ? { + a: 0, + b: [ a ? [ 0, 1 ] : [] ] + } + : [ + [ + 0, + { + a: 0 + }, + a ? 0 : 1 + ], + function () { + return a + ? { + a: 0 + } + : [ + { + a: 0 + }, + {} + ]; + } + ] + ] + } + : [ + a + ? function () { + a + ? a( + a + ? { + a: a( { + a: 0 + } ) + } + : [ + 0, + a(), + a( + a(), + { + a: 0 + }, + a + ? a() + : a( { + a: 0 + } ) + ), + a() + ? { + a: a(), + b: [] + } + : {} + ] + ) + : a( + a() + ? { + a: 0 + } + : ( function ( a ) { + return a() + ? [ + { + a: 0, + b: a() + } + ] + : a( [ + a + ? { + a: 0 + } + : {}, + { + a: 0 + } + ] ); + } )( + a + ? function ( a ) { + return function () { + return 0; + }; + } + : function ( a ) { + return function () { + return 1; + }; + } + ) + ); + } + : function () {} + ]; + } + } + : a; + +================================================================================ +`; + +exports[`indent-after-paren.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +trailingComma: "none" + | printWidth +=====================================input====================================== +foo7 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +foo8 = (condition ? firstValue : secondValue)[SomeType]; + +const foo9 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +function foo10() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo11() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo12() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +foo13 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +foo14 = (condition ? firstValue : secondValue)[SomeType]; + +const foo15 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +function foo16() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo17() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo18() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +foo19 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +foo20 = (condition ? firstValue : secondValue)[SomeType]; + +const foo21 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +function foo22() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo23() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo24() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +foo25 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +foo26 = (condition ? firstValue : secondValue)[SomeType]; + +const foo27 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +function foo28() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo29() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo30() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function* foo31() { + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo.Fooooooooooo]; +} + +const foo32 = new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +function foo33() { + return new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo34() { + throw new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo35() { + void new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +foo36 = new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo)); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo)); + +bifornCringerMoshedPerplexSawder = ( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).annularCooeedSplicesWalksWayWay + .annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay) + .annularCooeedSplicesWalksWayWay(); + +foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.()?.()?.(); + +foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)()()(); + +foo = + foo.bar.baz[ + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ]; + +const decorated = (arg, ignoreRequestError) => { + return ( + typeof arg === "string" || + (arg && arg.valueOf && typeof arg.valueOf() === "string") + ? $delegate(arg, ignoreRequestError) + : handleAsyncOperations(arg, ignoreRequestError) + ).foo(); +}; + +bifornCringerMoshedPerplexSawder = fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +) + +bifornCringerMoshedPerplexSawder = fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +) + +bifornCringerMoshedPerplexSawder = + fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +bifornCringerMoshedPerplexSawder = + fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +=====================================output===================================== +foo7 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[ Fooooooooooo ]; + +foo8 = ( condition ? firstValue : secondValue )[ SomeType ]; + +const foo9 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[ Fooooooooooo ]; + +function foo10() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[ Fooooooooooo ]; +} + +function foo11() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[ Fooooooooooo ]; +} + +function foo12() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[ Fooooooooooo ]; +} + +foo13 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; + +foo14 = ( condition ? firstValue : secondValue )[ SomeType ]; + +const foo15 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; + +function foo16() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo17() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo18() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +foo19 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )( Fooooooooooo.Fooooooooooo ); + +foo20 = ( condition ? firstValue : secondValue )[ SomeType ]; + +const foo21 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )( Fooooooooooo.Fooooooooooo ); + +function foo22() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )( Fooooooooooo.Fooooooooooo ); +} + +function foo23() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )( Fooooooooooo.Fooooooooooo ); +} + +function foo24() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )( Fooooooooooo.Fooooooooooo ); +} + +foo25 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.( Fooooooooooo.Fooooooooooo ); + +foo26 = ( condition ? firstValue : secondValue )[ SomeType ]; + +const foo27 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.( Fooooooooooo.Fooooooooooo ); + +function foo28() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.( Fooooooooooo.Fooooooooooo ); +} + +function foo29() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.( Fooooooooooo.Fooooooooooo ); +} + +function foo30() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.( Fooooooooooo.Fooooooooooo ); +} + +function* foo31() { + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.( Fooooooooooo.Fooooooooooo ); + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )( Fooooooooooo.Fooooooooooo ); + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )[ Fooooooooooo.Fooooooooooo ]; +} + +const foo32 = new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )( Fooooooooooo.Fooooooooooo ); + +function foo33() { + return new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )( Fooooooooooo.Fooooooooooo ); +} + +function foo34() { + throw new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )( Fooooooooooo.Fooooooooooo ); +} + +function foo35() { + void new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )( Fooooooooooo.Fooooooooooo ); +} + +foo36 = new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )( Fooooooooooo.Fooooooooooo ); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ( glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol )[ AnnularCooeedSplicesWalksWayWay ]; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ( glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol )[ AnnularCooeedSplicesWalksWayWay ]; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ( glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).Fooooooooooo.Fooooooooooo; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ( glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).Fooooooooooo.Fooooooooooo; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ( glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol )( Fooooooooooo.Fooooooooooo ); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ( glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol )( Fooooooooooo.Fooooooooooo ); + +bifornCringerMoshedPerplexSawder = ( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).annularCooeedSplicesWalksWayWay + .annularCooeedSplicesWalksWayWay( annularCooeedSplicesWalksWayWay ) + .annularCooeedSplicesWalksWayWay(); + +foo = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )?.()?.()?.(); + +foo = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )()()(); + +foo = + foo.bar.baz[ + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ]; + +const decorated = ( arg, ignoreRequestError ) => { + return ( + typeof arg === "string" || + ( arg && arg.valueOf && typeof arg.valueOf() === "string" ) + ? $delegate( arg, ignoreRequestError ) + : handleAsyncOperations( arg, ignoreRequestError ) + ).foo(); +}; + +bifornCringerMoshedPerplexSawder = fn( + ( glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn( + ( glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +bifornCringerMoshedPerplexSawder = fn?.( + ( glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn?.( + ( glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +bifornCringerMoshedPerplexSawder = + fn[ + ( glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn[ + ( glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +bifornCringerMoshedPerplexSawder = + fn?.[ + ( glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn?.[ + ( glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +================================================================================ +`; + +exports[`nested.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +trailingComma: "none" + | printWidth +=====================================input====================================== +let icecream = what == "cone" + ? p => !!p ? \`here's your \${p} cone\` : \`just the empty cone for you\` + : p => \`here's your \${p} \${what}\`; + +const value = condition1 +? value1 +: condition2 + ? value2 + : condition3 + ? value3 + : value4; + + +const StorybookLoader = ({ match }) => ( + match.params.storyId === "button" + ? + : match.params.storyId === "color" + ? + : match.params.storyId === "typography" + ? + : match.params.storyId === "loading" + ? + : match.params.storyId === "deal-list" + ? + : ( + + {'Missing story book'} + + + + + ) +) + +const message = + i % 3 === 0 && i % 5 === 0 ? + 'fizzbuzz' + : i % 3 === 0 ? + 'fizz' + : i % 5 === 0 ? + 'buzz' + : + String(i) + +const paymentMessage = state == 'success' + ? 'Payment completed successfully' + +: state == 'processing' + ? 'Payment processing' + +: state == 'invalid_cvc' + ? 'There was an issue with your CVC number' + +: state == 'invalid_expiry' + ? 'Expiry must be sometime in the past.' + + : 'There was an issue with the payment. Please contact support.' + +const paymentMessage2 = state == 'success' + ? 1 //'Payment completed successfully' + +: state == 'processing' + ? 2 //'Payment processing' + +: state == 'invalid_cvc' + ? 3 //'There was an issue with your CVC number' + +: true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + + : 5 // 'There was an issue with the payment. Please contact support.' + +const foo =
+ {medals[0].record ? ( + i18n('Record') + ) : medals[0].unique ? ( + i18n('Unique') + ) : medals[0].type === 0 ? ( + i18n('Silver') + ) : medals[0].type === 1 ? ( + i18n('Gold') + ) : medals[0].type === 2 ? ( + i18n('Platinum') + ) : ( + i18n('Theme') + )} +
+ +a + ? literalline + : { + 123: 12 + } + ? line + : softline + +=====================================output===================================== +let icecream = + what == "cone" + ? p => ( !! p ? \`here's your \${p} cone\` : \`just the empty cone for you\` ) + : p => \`here's your \${p} \${what}\`; + +const value = condition1 + ? value1 + : condition2 + ? value2 + : condition3 + ? value3 + : value4; + +const StorybookLoader = ( { match } ) => + match.params.storyId === "button" ? ( + + ) : match.params.storyId === "color" ? ( + + ) : match.params.storyId === "typography" ? ( + + ) : match.params.storyId === "loading" ? ( + + ) : match.params.storyId === "deal-list" ? ( + + ) : ( + + { "Missing story book" } + + + + + ); + +const message = + i % 3 === 0 && i % 5 === 0 + ? "fizzbuzz" + : i % 3 === 0 + ? "fizz" + : i % 5 === 0 + ? "buzz" + : String( i ); + +const paymentMessage = + state == "success" + ? "Payment completed successfully" + : state == "processing" + ? "Payment processing" + : state == "invalid_cvc" + ? "There was an issue with your CVC number" + : state == "invalid_expiry" + ? "Expiry must be sometime in the past." + : "There was an issue with the payment. Please contact support."; + +const paymentMessage2 = + state == "success" + ? 1 //'Payment completed successfully' + : state == "processing" + ? 2 //'Payment processing' + : state == "invalid_cvc" + ? 3 //'There was an issue with your CVC number' + : true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + : 5; // 'There was an issue with the payment. Please contact support.' + +const foo = ( +
+ { medals[ 0 ].record + ? i18n( "Record" ) + : medals[ 0 ].unique + ? i18n( "Unique" ) + : medals[ 0 ].type === 0 + ? i18n( "Silver" ) + : medals[ 0 ].type === 1 + ? i18n( "Gold" ) + : medals[ 0 ].type === 2 + ? i18n( "Platinum" ) + : i18n( "Theme" ) } +
+); + +a + ? literalline + : { + 123: 12 + } + ? line + : softline; + +================================================================================ +`; + +exports[`nested-in-condition.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +trailingComma: "none" + | printWidth +=====================================input====================================== +$var = ($number % 10 >= 2 && ($number % 100 < 10 || $number % 100 >= 20) +? kochabCooieGameOnOboleUnweave +: annularCooeedSplicesWalksWayWay) + ? anodyneCondosMalateOverateRetinol + : averredBathersBoxroomBuggyNurl; + +const value = (bifornCringerMoshedPerplexSawder +? askTrovenaBeenaDependsRowans +: glimseGlyphsHazardNoopsTieTie) + ? true + ? true + : false + : true + ? true + : false; + +(bifornCringerMoshedPerplexSawder ? ( + askTrovenaBeenaDependsRowans +) : ( + glimseGlyphsHazardNoopsTieTie +)) ? ( + + + + + + + + +) : ( + + + + + +); + +=====================================output===================================== +$var = ( + $number % 10 >= 2 && ( $number % 100 < 10 || $number % 100 >= 20 ) + ? kochabCooieGameOnOboleUnweave + : annularCooeedSplicesWalksWayWay + ) + ? anodyneCondosMalateOverateRetinol + : averredBathersBoxroomBuggyNurl; + +const value = ( + bifornCringerMoshedPerplexSawder + ? askTrovenaBeenaDependsRowans + : glimseGlyphsHazardNoopsTieTie + ) + ? true + ? true + : false + : true + ? true + : false; + +( + bifornCringerMoshedPerplexSawder + ? askTrovenaBeenaDependsRowans + : glimseGlyphsHazardNoopsTieTie + ) ? ( + + + + + + + + +) : ( + + + + + +); + +================================================================================ +`; + +exports[`parenthesis.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +trailingComma: "none" + | printWidth +=====================================input====================================== +debug ? this.state.isVisible ? "partially visible" : "hidden" : null; +debug ? this.state.isVisible && somethingComplex ? "partially visible" : "hidden" : null; + +a => a ? () => {a} : () => {a} +a => a ? a : a +a => a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a + +=====================================output===================================== +debug ? ( this.state.isVisible ? "partially visible" : "hidden" ) : null; +debug + ? this.state.isVisible && somethingComplex + ? "partially visible" + : "hidden" + : null; + +a => + a + ? () => { + a; + } + : () => { + a; + }; +a => ( a ? a : a ); +a => + a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a; + +================================================================================ +`; + +exports[`test.js - {"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"spaceUnaryOps":true,"templateCurlySpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +spaceUnaryOps: true +templateCurlySpacing: true +trailingComma: "none" + | printWidth +=====================================input====================================== +const obj0 = conditionIsTruthy ? shortThing : otherShortThing + +const obj1 = conditionIsTruthy ? { some: 'long', object: 'with', lots: 'of', stuff } : shortThing + +const obj2 = conditionIsTruthy ? shortThing : { some: 'long', object: 'with', lots: 'of', stuff } + +const obj3 = conditionIsTruthy ? { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } : shortThing + +const obj4 = conditionIsTruthy ? shortThing : { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } + +const obj5 = conditionIsTruthy ? { some: 'long', object: 'with', lots: 'of', stuff } : { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } + +=====================================output===================================== +const obj0 = conditionIsTruthy ? shortThing : otherShortThing; + +const obj1 = conditionIsTruthy + ? { some: "long", object: "with", lots: "of", stuff } + : shortThing; + +const obj2 = conditionIsTruthy + ? shortThing + : { some: "long", object: "with", lots: "of", stuff }; + +const obj3 = conditionIsTruthy + ? { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff + } + : shortThing; + +const obj4 = conditionIsTruthy + ? shortThing + : { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff + }; + +const obj5 = conditionIsTruthy + ? { some: "long", object: "with", lots: "of", stuff } + : { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff + }; + +================================================================================ +`; diff --git a/tests/format/js/ternaries/with-inner-spacing/jsfmt.spec.js b/tests/format/js/ternaries/with-inner-spacing/jsfmt.spec.js new file mode 100644 index 0000000000..d92c604816 --- /dev/null +++ b/tests/format/js/ternaries/with-inner-spacing/jsfmt.spec.js @@ -0,0 +1,17 @@ +// [prettierx] test script notice: +// This test script runs for test files in parent directory, +// **not** on any files in *this* directory. + +const dirPath = `${__dirname}/..`; + +run_spec(dirPath, ["babel", "babel-flow", "flow", "typescript"], { + spaceInParens: true, + arrayBracketSpacing: true, + computedPropertySpacing: true, + spaceUnaryOps: true, + templateCurlySpacing: true, + // [prettierx] recommended option: + arrowParens: "avoid", + // [prettierx] "Standard JS" setting: + trailingComma: "none", +}); diff --git a/tests/format/js/ternary-object-expressions/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/ternary-object-expressions/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..359819f3fb --- /dev/null +++ b/tests/format/js/ternary-object-expressions/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,297 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`crewdress.js - {"tabWidth":4} format 1`] = ` +====================================options===================================== +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 + | printWidth +=====================================input====================================== +const isSpace = false + +const dress = isSpace ? { + spaceSuit: 3, + oxygenCylinders: 6 + } : { + shirts: 3, + paints: 3 + } + +=====================================output===================================== +const isSpace = false; + +const dress = isSpace + ? { + spaceSuit: 3, + oxygenCylinders: 6, + } + : { + shirts: 3, + paints: 3, + }; + +================================================================================ +`; + +exports[`crewdress.js - {"useTabs":true,"tabWidth":4} format 1`] = ` +====================================options===================================== +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +useTabs: true + | printWidth +=====================================input====================================== +const isSpace = false + +const dress = isSpace ? { + spaceSuit: 3, + oxygenCylinders: 6 + } : { + shirts: 3, + paints: 3 + } + +=====================================output===================================== +const isSpace = false; + +const dress = isSpace + ? { + spaceSuit: 3, + oxygenCylinders: 6, + } + : { + shirts: 3, + paints: 3, + }; + +================================================================================ +`; + +exports[`crewdress.js - {"useTabs":true} format 1`] = ` +====================================options===================================== +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +useTabs: true + | printWidth +=====================================input====================================== +const isSpace = false + +const dress = isSpace ? { + spaceSuit: 3, + oxygenCylinders: 6 + } : { + shirts: 3, + paints: 3 + } + +=====================================output===================================== +const isSpace = false; + +const dress = isSpace + ? { + spaceSuit: 3, + oxygenCylinders: 6, + } + : { + shirts: 3, + paints: 3, + }; + +================================================================================ +`; + +exports[`crewdress.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +const isSpace = false + +const dress = isSpace ? { + spaceSuit: 3, + oxygenCylinders: 6 + } : { + shirts: 3, + paints: 3 + } + +=====================================output===================================== +const isSpace = false; + +const dress = isSpace + ? { + spaceSuit: 3, + oxygenCylinders: 6, + } + : { + shirts: 3, + paints: 3, + }; + +================================================================================ +`; + +exports[`nested-ternary-promises.js - {"tabWidth":4} format 1`] = ` +====================================options===================================== +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 + | printWidth +=====================================input====================================== +// check for consistent formatting as discussed in: +// - https://github.com/eslint/eslint/issues/13971 +// - https://github.com/standard/standard/issues/1624 +// - https://github.com/brodybits/prettierx/issues/41 + +function test1() { + return condition1 + ? condition2 + ? new Promise(1) + : new Promise(2) + : condition3 + ? new Promise(3) + : new Promise(4) +} + +=====================================output===================================== +// check for consistent formatting as discussed in: +// - https://github.com/eslint/eslint/issues/13971 +// - https://github.com/standard/standard/issues/1624 +// - https://github.com/brodybits/prettierx/issues/41 + +function test1() { + return condition1 + ? condition2 + ? new Promise(1) + : new Promise(2) + : condition3 + ? new Promise(3) + : new Promise(4); +} + +================================================================================ +`; + +exports[`nested-ternary-promises.js - {"useTabs":true,"tabWidth":4} format 1`] = ` +====================================options===================================== +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +useTabs: true + | printWidth +=====================================input====================================== +// check for consistent formatting as discussed in: +// - https://github.com/eslint/eslint/issues/13971 +// - https://github.com/standard/standard/issues/1624 +// - https://github.com/brodybits/prettierx/issues/41 + +function test1() { + return condition1 + ? condition2 + ? new Promise(1) + : new Promise(2) + : condition3 + ? new Promise(3) + : new Promise(4) +} + +=====================================output===================================== +// check for consistent formatting as discussed in: +// - https://github.com/eslint/eslint/issues/13971 +// - https://github.com/standard/standard/issues/1624 +// - https://github.com/brodybits/prettierx/issues/41 + +function test1() { + return condition1 + ? condition2 + ? new Promise(1) + : new Promise(2) + : condition3 + ? new Promise(3) + : new Promise(4); +} + +================================================================================ +`; + +exports[`nested-ternary-promises.js - {"useTabs":true} format 1`] = ` +====================================options===================================== +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +useTabs: true + | printWidth +=====================================input====================================== +// check for consistent formatting as discussed in: +// - https://github.com/eslint/eslint/issues/13971 +// - https://github.com/standard/standard/issues/1624 +// - https://github.com/brodybits/prettierx/issues/41 + +function test1() { + return condition1 + ? condition2 + ? new Promise(1) + : new Promise(2) + : condition3 + ? new Promise(3) + : new Promise(4) +} + +=====================================output===================================== +// check for consistent formatting as discussed in: +// - https://github.com/eslint/eslint/issues/13971 +// - https://github.com/standard/standard/issues/1624 +// - https://github.com/brodybits/prettierx/issues/41 + +function test1() { + return condition1 + ? condition2 + ? new Promise(1) + : new Promise(2) + : condition3 + ? new Promise(3) + : new Promise(4); +} + +================================================================================ +`; + +exports[`nested-ternary-promises.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +// check for consistent formatting as discussed in: +// - https://github.com/eslint/eslint/issues/13971 +// - https://github.com/standard/standard/issues/1624 +// - https://github.com/brodybits/prettierx/issues/41 + +function test1() { + return condition1 + ? condition2 + ? new Promise(1) + : new Promise(2) + : condition3 + ? new Promise(3) + : new Promise(4) +} + +=====================================output===================================== +// check for consistent formatting as discussed in: +// - https://github.com/eslint/eslint/issues/13971 +// - https://github.com/standard/standard/issues/1624 +// - https://github.com/brodybits/prettierx/issues/41 + +function test1() { + return condition1 + ? condition2 + ? new Promise(1) + : new Promise(2) + : condition3 + ? new Promise(3) + : new Promise(4); +} + +================================================================================ +`; diff --git a/tests/format/js/ternary-object-expressions/crewdress.js b/tests/format/js/ternary-object-expressions/crewdress.js new file mode 100644 index 0000000000..b3706f1d05 --- /dev/null +++ b/tests/format/js/ternary-object-expressions/crewdress.js @@ -0,0 +1,9 @@ +const isSpace = false + +const dress = isSpace ? { + spaceSuit: 3, + oxygenCylinders: 6 + } : { + shirts: 3, + paints: 3 + } diff --git a/tests/format/js/ternary-object-expressions/jsfmt.spec.js b/tests/format/js/ternary-object-expressions/jsfmt.spec.js new file mode 100644 index 0000000000..387ee76713 --- /dev/null +++ b/tests/format/js/ternary-object-expressions/jsfmt.spec.js @@ -0,0 +1,11 @@ +run_spec(__dirname, ["babel", "babel-flow", "flow", "typescript"]); +run_spec(__dirname, ["babel", "babel-flow", "flow", "typescript"], { + tabWidth: 4, +}); +run_spec(__dirname, ["babel", "babel-flow", "flow", "typescript"], { + useTabs: true, +}); +run_spec(__dirname, ["babel", "babel-flow", "flow", "typescript"], { + useTabs: true, + tabWidth: 4, +}); diff --git a/tests/format/js/ternary-object-expressions/nested-ternary-promises.js b/tests/format/js/ternary-object-expressions/nested-ternary-promises.js new file mode 100644 index 0000000000..8765e34ee3 --- /dev/null +++ b/tests/format/js/ternary-object-expressions/nested-ternary-promises.js @@ -0,0 +1,14 @@ +// check for consistent formatting as discussed in: +// - https://github.com/eslint/eslint/issues/13971 +// - https://github.com/standard/standard/issues/1624 +// - https://github.com/brodybits/prettierx/issues/41 + +function test1() { + return condition1 + ? condition2 + ? new Promise(1) + : new Promise(2) + : condition3 + ? new Promise(3) + : new Promise(4) +} diff --git a/tests/format/js/ternary-object-expressions/with-balanced-formatting/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/ternary-object-expressions/with-balanced-formatting/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..463683435e --- /dev/null +++ b/tests/format/js/ternary-object-expressions/with-balanced-formatting/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,321 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`crewdress.js - {"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" + | printWidth +=====================================input====================================== +const isSpace = false + +const dress = isSpace ? { + spaceSuit: 3, + oxygenCylinders: 6 + } : { + shirts: 3, + paints: 3 + } + +=====================================output===================================== +const isSpace = false; + +const dress = isSpace + ? { + spaceSuit: 3, + oxygenCylinders: 6 + } + : { + shirts: 3, + paints: 3 + }; + +================================================================================ +`; + +exports[`crewdress.js - {"tabWidth":4,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +trailingComma: "none" + | printWidth +=====================================input====================================== +const isSpace = false + +const dress = isSpace ? { + spaceSuit: 3, + oxygenCylinders: 6 + } : { + shirts: 3, + paints: 3 + } + +=====================================output===================================== +const isSpace = false; + +const dress = isSpace + ? { + spaceSuit: 3, + oxygenCylinders: 6 + } + : { + shirts: 3, + paints: 3 + }; + +================================================================================ +`; + +exports[`crewdress.js - {"useTabs":true,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" +useTabs: true + | printWidth +=====================================input====================================== +const isSpace = false + +const dress = isSpace ? { + spaceSuit: 3, + oxygenCylinders: 6 + } : { + shirts: 3, + paints: 3 + } + +=====================================output===================================== +const isSpace = false; + +const dress = isSpace + ? { + spaceSuit: 3, + oxygenCylinders: 6 + } + : { + shirts: 3, + paints: 3 + }; + +================================================================================ +`; + +exports[`crewdress.js - {"useTabs":true,"tabWidth":4,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +trailingComma: "none" +useTabs: true + | printWidth +=====================================input====================================== +const isSpace = false + +const dress = isSpace ? { + spaceSuit: 3, + oxygenCylinders: 6 + } : { + shirts: 3, + paints: 3 + } + +=====================================output===================================== +const isSpace = false; + +const dress = isSpace + ? { + spaceSuit: 3, + oxygenCylinders: 6 + } + : { + shirts: 3, + paints: 3 + }; + +================================================================================ +`; + +exports[`nested-ternary-promises.js - {"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" + | printWidth +=====================================input====================================== +// check for consistent formatting as discussed in: +// - https://github.com/eslint/eslint/issues/13971 +// - https://github.com/standard/standard/issues/1624 +// - https://github.com/brodybits/prettierx/issues/41 + +function test1() { + return condition1 + ? condition2 + ? new Promise(1) + : new Promise(2) + : condition3 + ? new Promise(3) + : new Promise(4) +} + +=====================================output===================================== +// check for consistent formatting as discussed in: +// - https://github.com/eslint/eslint/issues/13971 +// - https://github.com/standard/standard/issues/1624 +// - https://github.com/brodybits/prettierx/issues/41 + +function test1() { + return condition1 + ? condition2 + ? new Promise(1) + : new Promise(2) + : condition3 + ? new Promise(3) + : new Promise(4); +} + +================================================================================ +`; + +exports[`nested-ternary-promises.js - {"tabWidth":4,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +trailingComma: "none" + | printWidth +=====================================input====================================== +// check for consistent formatting as discussed in: +// - https://github.com/eslint/eslint/issues/13971 +// - https://github.com/standard/standard/issues/1624 +// - https://github.com/brodybits/prettierx/issues/41 + +function test1() { + return condition1 + ? condition2 + ? new Promise(1) + : new Promise(2) + : condition3 + ? new Promise(3) + : new Promise(4) +} + +=====================================output===================================== +// check for consistent formatting as discussed in: +// - https://github.com/eslint/eslint/issues/13971 +// - https://github.com/standard/standard/issues/1624 +// - https://github.com/brodybits/prettierx/issues/41 + +function test1() { + return condition1 + ? condition2 + ? new Promise(1) + : new Promise(2) + : condition3 + ? new Promise(3) + : new Promise(4); +} + +================================================================================ +`; + +exports[`nested-ternary-promises.js - {"useTabs":true,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +trailingComma: "none" +useTabs: true + | printWidth +=====================================input====================================== +// check for consistent formatting as discussed in: +// - https://github.com/eslint/eslint/issues/13971 +// - https://github.com/standard/standard/issues/1624 +// - https://github.com/brodybits/prettierx/issues/41 + +function test1() { + return condition1 + ? condition2 + ? new Promise(1) + : new Promise(2) + : condition3 + ? new Promise(3) + : new Promise(4) +} + +=====================================output===================================== +// check for consistent formatting as discussed in: +// - https://github.com/eslint/eslint/issues/13971 +// - https://github.com/standard/standard/issues/1624 +// - https://github.com/brodybits/prettierx/issues/41 + +function test1() { + return condition1 + ? condition2 + ? new Promise(1) + : new Promise(2) + : condition3 + ? new Promise(3) + : new Promise(4); +} + +================================================================================ +`; + +exports[`nested-ternary-promises.js - {"useTabs":true,"tabWidth":4,"offsetTernaryExpressions":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrowParens: "avoid" +offsetTernaryExpressions: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +trailingComma: "none" +useTabs: true + | printWidth +=====================================input====================================== +// check for consistent formatting as discussed in: +// - https://github.com/eslint/eslint/issues/13971 +// - https://github.com/standard/standard/issues/1624 +// - https://github.com/brodybits/prettierx/issues/41 + +function test1() { + return condition1 + ? condition2 + ? new Promise(1) + : new Promise(2) + : condition3 + ? new Promise(3) + : new Promise(4) +} + +=====================================output===================================== +// check for consistent formatting as discussed in: +// - https://github.com/eslint/eslint/issues/13971 +// - https://github.com/standard/standard/issues/1624 +// - https://github.com/brodybits/prettierx/issues/41 + +function test1() { + return condition1 + ? condition2 + ? new Promise(1) + : new Promise(2) + : condition3 + ? new Promise(3) + : new Promise(4); +} + +================================================================================ +`; diff --git a/tests/format/js/ternary-object-expressions/with-balanced-formatting/jsfmt.spec.js b/tests/format/js/ternary-object-expressions/with-balanced-formatting/jsfmt.spec.js new file mode 100644 index 0000000000..6a457a2e8b --- /dev/null +++ b/tests/format/js/ternary-object-expressions/with-balanced-formatting/jsfmt.spec.js @@ -0,0 +1,48 @@ +// [prettierx] test script notice: +// This test script runs for test files in parent directory, +// **not** on any files in *this* directory. + +const dirPath = `${__dirname}/..`; + +run_spec(dirPath, ["babel", "babel-flow", "flow", "typescript"], { + // [prettierx] balanced ternary formatting option, + // for consistency with "Standard JS": + offsetTernaryExpressions: true, + // [prettierx] more options needed for consistency with "Standard JS": + arrowParens: "avoid", + trailingComma: "none", +}); + +run_spec(dirPath, ["babel", "babel-flow", "flow", "typescript"], { + // variation from ../jsfmt.spec.js: + tabWidth: 4, + // [prettierx] balanced ternary formatting option, + // for consistency with "Standard JS": + offsetTernaryExpressions: true, + // [prettierx] more options needed for consistency with "Standard JS": + arrowParens: "avoid", + trailingComma: "none", +}); + +run_spec(dirPath, ["babel", "babel-flow", "flow", "typescript"], { + // variation from ../jsfmt.spec.js: + useTabs: true, + // [prettierx] balanced ternary formatting option, + // for consistency with "Standard JS": + offsetTernaryExpressions: true, + // [prettierx] more options needed for consistency with "Standard JS": + arrowParens: "avoid", + trailingComma: "none", +}); + +run_spec(dirPath, ["babel", "babel-flow", "flow", "typescript"], { + // variation from ../jsfmt.spec.js: + useTabs: true, + tabWidth: 4, + // [prettierx] balanced ternary formatting option, + // for consistency with "Standard JS": + offsetTernaryExpressions: true, + // [prettierx] more options needed for consistency with "Standard JS": + arrowParens: "avoid", + trailingComma: "none", +}); diff --git a/tests/format/js/test-declarations/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/test-declarations/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..b1b56fb02e --- /dev/null +++ b/tests/format/js/test-declarations/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,695 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`angular_async.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"typeAngleBracketSpacing":true,"templateCurlySpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +beforeEach(async(() => { + // code +})); + +beforeEach(done => + foo() + .bar() + .bar(), +); + +afterAll(async(() => { + console.log('Hello'); +})); + +afterAll(done => + foo() + .bar() + .bar(), +); + +it('should create the app', async(() => { + //code +})); + +it("does something really long and complicated so I have to write a very long name for the test", async(() => { + // code +})); + +/* +* isTestCall(parent) should only be called when parent exists +* and parent.type is CallExpression. This test makes sure that +* no errors are thrown when calling isTestCall(parent) +*/ +function x() { async(() => {}) } + +=====================================output===================================== +beforeEach( async( () => { + // code +} ) ); + +beforeEach( done => foo().bar().bar() ); + +afterAll( async( () => { + console.log( "Hello" ); +} ) ); + +afterAll( done => foo().bar().bar() ); + +it( "should create the app", async( () => { + //code +} ) ); + +it( "does something really long and complicated so I have to write a very long name for the test", async( () => { + // code +} ) ); + +/* + * isTestCall(parent) should only be called when parent exists + * and parent.type is CallExpression. This test makes sure that + * no errors are thrown when calling isTestCall(parent) + */ +function x() { + async( () => {} ); +} + +================================================================================ +`; + +exports[`angular_fakeAsync.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"typeAngleBracketSpacing":true,"templateCurlySpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +beforeEach(fakeAsync(() => { + // code +})); + +afterAll(fakeAsync(() => { + console.log('Hello'); +})); + +it('should create the app', fakeAsync(() => { + //code +})); + +it("does something really long and complicated so I have to write a very long name for the test", fakeAsync(() => { + // code +})); + +it("does something really long and complicated so I have to write a very long name for the test", fakeAsync(() => new SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS)); + +/* +* isTestCall(parent) should only be called when parent exists +* and parent.type is CallExpression. This test makes sure that +* no errors are thrown when calling isTestCall(parent) +*/ +function x() { fakeAsync(() => {}) } + +=====================================output===================================== +beforeEach( fakeAsync( () => { + // code +} ) ); + +afterAll( fakeAsync( () => { + console.log( "Hello" ); +} ) ); + +it( "should create the app", fakeAsync( () => { + //code +} ) ); + +it( "does something really long and complicated so I have to write a very long name for the test", fakeAsync( () => { + // code +} ) ); + +it( "does something really long and complicated so I have to write a very long name for the test", fakeAsync( () => + new SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS() ) ); + +/* + * isTestCall(parent) should only be called when parent exists + * and parent.type is CallExpression. This test makes sure that + * no errors are thrown when calling isTestCall(parent) + */ +function x() { + fakeAsync( () => {} ); +} + +================================================================================ +`; + +exports[`angularjs_inject.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"typeAngleBracketSpacing":true,"templateCurlySpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +beforeEach(inject(($fooService, $barService) => { + // code +})); + +afterAll(inject(($fooService, $barService) => { + console.log('Hello'); +})); + +it('should create the app', inject(($fooService, $barService) => { + //code +})); + +it("does something really long and complicated so I have to write a very long name for the test", inject(() => { + // code +})); + +it("does something really long and complicated so I have to write a very long name for the test", inject(($fooServiceLongName, $barServiceLongName) => { + // code +})); + +/* +* isTestCall(parent) should only be called when parent exists +* and parent.type is CallExpression. This test makes sure that +* no errors are thrown when calling isTestCall(parent) +*/ +function x() { inject(() => {}) } + +=====================================output===================================== +beforeEach( inject( ( $fooService, $barService ) => { + // code +} ) ); + +afterAll( inject( ( $fooService, $barService ) => { + console.log( "Hello" ); +} ) ); + +it( "should create the app", inject( ( $fooService, $barService ) => { + //code +} ) ); + +it( "does something really long and complicated so I have to write a very long name for the test", inject( () => { + // code +} ) ); + +it( "does something really long and complicated so I have to write a very long name for the test", inject( ( + $fooServiceLongName, + $barServiceLongName +) => { + // code +} ) ); + +/* + * isTestCall(parent) should only be called when parent exists + * and parent.type is CallExpression. This test makes sure that + * no errors are thrown when calling isTestCall(parent) + */ +function x() { + inject( () => {} ); +} + +================================================================================ +`; + +exports[`jest-each.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"typeAngleBracketSpacing":true,"templateCurlySpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +describe.each\` +a|b|expected +\${11 } | \${ 1 }|\${222} +\${1-1}|\${2+2}|\${ 3333} +\${2+1+2}|\${1111}|\${3} +\`('$a + $b', ({a, b, expected}) => { + test(\`returns \${expected}\`, () => { + expect(a + b).toBe(expected); + }); + + test(\`returned value not be greater than \${expected}\`, () => { + expect(a + b).not.toBeGreaterThan(expected); + }); + + test(\`returned value not be less than \${expected}\`, () => { + expect(a + b).not.toBeLessThan(expected); + }); +}); + +describe.only.each\` +a|b|expected +\${11 } | \${ 1 }|\${222}|\${'unknown column 1'}|\${'unknown column 2'} +\${1-1}|\${2+2}|\${ 3333} +\${2+1+2}|\${1111}|\${3} |\${'unknown column xyz'} +\` + +describe.only.each\` +|| +\${11 } | \${ 1 }|\${222}|\${'unknown column 1'}|\${'unknown column 2'} +\${1-1}|\${2+2}|\${ 3333} +\${2+1+2}|\${1111}|\${3} |\${'unknown column xyz'} +\` + +describe.each\`a | b | expected +\${1} | \${1} | \${2} +\${1} | \${2} | \${3} +\${2} | \${1} | \${3}\` + +// an example to demo multiline quasi +describe.each\`a | b | expected +\${11111111111} | \${a().b(x => x).c().d()} | \${2} +\${1} | \${2} | \${3} +\${2} | \${1} | \${3}\` + +describe.each([1, 2, 3])("test", a => { + expect(a).toBe(a); +}); + +test.only.each([[1, 1, 2], [1, 2, 3], [2, 1, 3]])( + ".add(%i, %i)", (a, b, expected) => { + expect(a + b).toBe(expected); + } +); + +test.each([ + { a: "1", b: 1 }, + { a: "2", b: 2 }, + { a: "3", b: 3 }, +])("test", ({ a, b }) => { + expect(Number(a)).toBe(b); + } +); + +=====================================output===================================== +describe.each\` + a | b | expected + \${ 11 } | \${ 1 } | \${ 222 } + \${ 1 - 1 } | \${ 2 + 2 } | \${ 3333 } + \${ 2 + 1 + 2 } | \${ 1111 } | \${ 3 } +\`( "$a + $b", ( { a, b, expected } ) => { + test( \`returns \${expected}\`, () => { + expect( a + b ).toBe( expected ); + } ); + + test( \`returned value not be greater than \${expected}\`, () => { + expect( a + b ).not.toBeGreaterThan( expected ); + } ); + + test( \`returned value not be less than \${expected}\`, () => { + expect( a + b ).not.toBeLessThan( expected ); + } ); +} ); + +describe.only.each\` + a | b | expected + \${ 11 } | \${ 1 } | \${ 222 } | \${ "unknown column 1" } | \${ "unknown column 2" } + \${ 1 - 1 } | \${ 2 + 2 } | \${ 3333 } + \${ 2 + 1 + 2 } | \${ 1111 } | \${ 3 } | \${ "unknown column xyz" } +\`; + +describe.only.each\` + | | + \${ 11 } | \${ 1 } | \${ 222 } | \${ "unknown column 1" } | \${ "unknown column 2" } + \${ 1 - 1 } | \${ 2 + 2 } | \${ 3333 } + \${ 2 + 1 + 2 } | \${ 1111 } | \${ 3 } | \${ "unknown column xyz" } +\`; + +describe.each\` + a | b | expected + \${ 1 } | \${ 1 } | \${ 2 } + \${ 1 } | \${ 2 } | \${ 3 } + \${ 2 } | \${ 1 } | \${ 3 } +\`; + +// an example to demo multiline quasi +describe.each\` + a | b | expected + \${ 11111111111 } | \${ a() + .b( x => x ) + .c() + .d() } | \${ 2 } + \${ 1 } | \${ 2 } | \${ 3 } + \${ 2 } | \${ 1 } | \${ 3 } +\`; + +describe.each( [ 1, 2, 3 ] )( "test", a => { + expect( a ).toBe( a ); +} ); + +test.only.each( [ + [ 1, 1, 2 ], + [ 1, 2, 3 ], + [ 2, 1, 3 ], +] )( ".add(%i, %i)", ( a, b, expected ) => { + expect( a + b ).toBe( expected ); +} ); + +test.each( [ + { a: "1", b: 1 }, + { a: "2", b: 2 }, + { a: "3", b: 3 }, +] )( "test", ( { a, b } ) => { + expect( Number( a ) ).toBe( b ); +} ); + +================================================================================ +`; + +exports[`jest-each-template-string.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"typeAngleBracketSpacing":true,"templateCurlySpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +test.each\` +a | b | c +\${1} | \${[{ start: 5, end: 15 }]} | \${[1,2,3,4,5,6,7,8]} +\${1}| \${[{ start: 5, end: 15 }]} | \${["test", "string", "for", "prettier"]} +\${3} | \${[{ start: 5, end: 15 }]} | \${[]} +\${4} | \${[{ start: 1, end: 3 },{ start: 15, end: 20 },]} | \${[]} +\`("example test", ({a, b, c}) => {}) + + +test.each\` +a | +\${[{ a: 1, b: 3 },{ c: 15, d: 20 }]}| +\${[{ start: 1, end: 3 },{ start: 15, end: 20 }, { start: 15, end: 20 },]}| +\`("example test", ({a, b, c}) => {}) + +=====================================output===================================== +test.each\` + a | b | c + \${ 1 } | \${ [ { start: 5, end: 15 } ] } | \${ [ 1, 2, 3, 4, 5, 6, 7, 8 ] } + \${ 1 } | \${ [ { start: 5, end: 15 } ] } | \${ [ "test", "string", "for", "prettier" ] } + \${ 3 } | \${ [ { start: 5, end: 15 } ] } | \${ [] } + \${ 4 } | \${ [ { start: 1, end: 3 }, { start: 15, end: 20 } ] } | \${ [] } +\`( "example test", ( { a, b, c } ) => {} ); + +test.each\` + a | + \${ [ { a: 1, b: 3 }, { c: 15, d: 20 } ] } + \${ [ { start: 1, end: 3 }, { start: 15, end: 20 }, { start: 15, end: 20 } ] } +\`( "example test", ( { a, b, c } ) => {} ); + +================================================================================ +`; + +exports[`test_declarations.js - {"arrowParens":"avoid","spaceInParens":true,"arrayBracketSpacing":true,"typeAngleBracketSpacing":true,"templateCurlySpacing":true} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceInParens: true +templateCurlySpacing: true +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +// Shouldn't break + +it("does something really long and complicated so I have to write a very long name for the test", () => { + console.log("hello!"); +}); + +it("does something really long and complicated so I have to write a very long name for the test", function() { + console.log("hello!"); +}); + +it("does something really long and complicated so I have to write a very long name for the test", function(done) { + console.log("hello!"); +}); + +it("does something really long and complicated so I have to write a very long name for the test", function myAssertions(done) { + console.log("hello!"); +}); + +it(\`does something really long and complicated so I have to write a very long name for the test\`, function() { + console.log("hello!"); +}); + +it(\`{foo + bar} does something really long and complicated so I have to write a very long name for the test\`, function() { + console.log("hello!"); +}); + +it(\`handles + some + newlines + does something really long and complicated so I have to write a very long name for the test\`, () => { + console.log("hello!"); +}) + +test("does something really long and complicated so I have to write a very long name for the test", (done) => { + console.log("hello!"); +}); + +test(\`does something really long and complicated so I have to write a very long name for the test\`, (done) => { + console.log("hello!"); +}); + +describe("does something really long and complicated so I have to write a very long name for the describe block", () => { + it("an example test", (done) => { + console.log("hello!"); + }); +}); + +describe(\`does something really long and complicated so I have to write a very long name for the describe block\`, () => { + it(\`an example test\`, (done) => { + console.log("hello!"); + }); +}); + +xdescribe("does something really long and complicated so I have to write a very long name for the describe block", () => {}); + +fdescribe("does something really long and complicated so I have to write a very long name for the describe block", () => {}); + +describe.only(\`does something really long and complicated so I have to write a very long name for the test\`, () => {}); + +describe.skip(\`does something really long and complicated so I have to write a very long name for the test\`, () => {}); + +fit("does something really long and complicated so I have to write a very long name for the describe block", () => {}); + +xit("does something really long and complicated so I have to write a very long name for the describe block", () => {}); + +it.only("does something really long and complicated so I have to write a very long name for the test", () => { + console.log("hello!"); +}); + +it.only(\`does something really long and complicated so I have to write a very long name for the test\`, () => { + console.log("hello!"); +}); + +it.skip(\`does something really long and complicated so I have to write a very long name for the test\`, () => {}); + +test.only(\`does something really long and complicated so I have to write a very long name for the test\`, () => {}); + +test.skip(\`does something really long and complicated so I have to write a very long name for the test\`, () => {}); + +ftest("does something really long and complicated so I have to write a very long name for the describe block", () => {}); + +xtest("does something really long and complicated so I have to write a very long name for the describe block", () => {}); + +skip(\`does something really long and complicated so I have to write a very long name for the test\`, () => {}); + +skip("does something really long and complicated so I have to write a very long name for the test", () => {}); + +// Should break + +it.only("does something really long and complicated so I have to write a very long name for the test", 10, () => { + console.log("hello!"); +}); + +it.only.only("does something really long and complicated so I have to write a very long name for the test", () => { + console.log("hello!"); +}); + +it.only.only("does something really long and complicated so I have to write a very long name for the test", (a, b, c) => { + console.log("hello!"); +}); + +xskip("does something really long and complicated so I have to write a very long name for the test", () => {}); + +// timeout + +it(\`handles + some + newlines + does something really long and complicated so I have to write a very long name for the test\`, () => { + console.log("hello!"); +}, 2500) + +it("does something quick", () => { + console.log("hello!") +}, 1000000000) + +it( + 'succeeds if the test finishes in time', + () => new Promise(resolve => setTimeout(resolve, 10)) +); + +it( + 'succeeds if the test finishes in time', + () => new Promise(resolve => setTimeout(resolve, 10)), + 250 +); + +=====================================output===================================== +// Shouldn't break + +it( "does something really long and complicated so I have to write a very long name for the test", () => { + console.log( "hello!" ); +} ); + +it( "does something really long and complicated so I have to write a very long name for the test", function () { + console.log( "hello!" ); +} ); + +it( "does something really long and complicated so I have to write a very long name for the test", function ( done ) { + console.log( "hello!" ); +} ); + +it( "does something really long and complicated so I have to write a very long name for the test", function myAssertions( done ) { + console.log( "hello!" ); +} ); + +it( \`does something really long and complicated so I have to write a very long name for the test\`, function () { + console.log( "hello!" ); +} ); + +it( \`{foo + bar} does something really long and complicated so I have to write a very long name for the test\`, function () { + console.log( "hello!" ); +} ); + +it( \`handles + some + newlines + does something really long and complicated so I have to write a very long name for the test\`, () => { + console.log( "hello!" ); +} ); + +test( "does something really long and complicated so I have to write a very long name for the test", done => { + console.log( "hello!" ); +} ); + +test( \`does something really long and complicated so I have to write a very long name for the test\`, done => { + console.log( "hello!" ); +} ); + +describe( "does something really long and complicated so I have to write a very long name for the describe block", () => { + it( "an example test", done => { + console.log( "hello!" ); + } ); +} ); + +describe( \`does something really long and complicated so I have to write a very long name for the describe block\`, () => { + it( \`an example test\`, done => { + console.log( "hello!" ); + } ); +} ); + +xdescribe( "does something really long and complicated so I have to write a very long name for the describe block", () => {} ); + +fdescribe( "does something really long and complicated so I have to write a very long name for the describe block", () => {} ); + +describe.only( \`does something really long and complicated so I have to write a very long name for the test\`, () => {} ); + +describe.skip( \`does something really long and complicated so I have to write a very long name for the test\`, () => {} ); + +fit( "does something really long and complicated so I have to write a very long name for the describe block", () => {} ); + +xit( "does something really long and complicated so I have to write a very long name for the describe block", () => {} ); + +it.only( "does something really long and complicated so I have to write a very long name for the test", () => { + console.log( "hello!" ); +} ); + +it.only( \`does something really long and complicated so I have to write a very long name for the test\`, () => { + console.log( "hello!" ); +} ); + +it.skip( \`does something really long and complicated so I have to write a very long name for the test\`, () => {} ); + +test.only( \`does something really long and complicated so I have to write a very long name for the test\`, () => {} ); + +test.skip( \`does something really long and complicated so I have to write a very long name for the test\`, () => {} ); + +ftest( "does something really long and complicated so I have to write a very long name for the describe block", () => {} ); + +xtest( "does something really long and complicated so I have to write a very long name for the describe block", () => {} ); + +skip( \`does something really long and complicated so I have to write a very long name for the test\`, () => {} ); + +skip( "does something really long and complicated so I have to write a very long name for the test", () => {} ); + +// Should break + +it.only( + "does something really long and complicated so I have to write a very long name for the test", + 10, + () => { + console.log( "hello!" ); + } +); + +it.only.only( + "does something really long and complicated so I have to write a very long name for the test", + () => { + console.log( "hello!" ); + } +); + +it.only.only( + "does something really long and complicated so I have to write a very long name for the test", + ( a, b, c ) => { + console.log( "hello!" ); + } +); + +xskip( + "does something really long and complicated so I have to write a very long name for the test", + () => {} +); + +// timeout + +it( \`handles + some + newlines + does something really long and complicated so I have to write a very long name for the test\`, () => { + console.log( "hello!" ); +}, 2500 ); + +it( "does something quick", () => { + console.log( "hello!" ); +}, 1000000000 ); + +it( "succeeds if the test finishes in time", () => + new Promise( resolve => setTimeout( resolve, 10 ) ) ); + +it( + "succeeds if the test finishes in time", + () => new Promise( resolve => setTimeout( resolve, 10 ) ), + 250 +); + +================================================================================ +`; diff --git a/tests/format/js/test-declarations/with-inner-spacing/jsfmt.spec.js b/tests/format/js/test-declarations/with-inner-spacing/jsfmt.spec.js new file mode 100644 index 0000000000..df86c77a0a --- /dev/null +++ b/tests/format/js/test-declarations/with-inner-spacing/jsfmt.spec.js @@ -0,0 +1,15 @@ +// [prettierx] test script notice: +// This test script runs for test files in parent directory, +// **not** on any files in *this* directory. + +const dirPath = `${__dirname}/..`; + +run_spec(dirPath, ["babel", "babel-flow", "flow", "typescript"], { + // [prettierx] recommended option, especially in combo with --paren-spacing + arrowParens: "avoid", + // [prettierx] test with --paren-spacing + spaceInParens: true, + arrayBracketSpacing: true, + typeAngleBracketSpacing: true, + templateCurlySpacing: true, +}); diff --git a/tests/format/js/tuple/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/tuple/__snapshots__/jsfmt.spec.js.snap index 1d4ee9f7aa..dfb722765c 100644 --- a/tests/format/js/tuple/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/js/tuple/__snapshots__/jsfmt.spec.js.snap @@ -48,6 +48,13 @@ assert(rest[1] === 3); ================================================================================ `; +exports[`invalid-tuple-holes.js [__babel_estree] format 1`] = ` +"Unexpected token ','. (1:4) +> 1 | #[,] + | ^ + 2 |" +`; + exports[`invalid-tuple-holes.js [babel] format 1`] = ` "Unexpected token ','. (1:4) > 1 | #[,] diff --git a/tests/format/js/tuple/jsfmt.spec.js b/tests/format/js/tuple/jsfmt.spec.js index 71a06d090b..878fdf2ab8 100644 --- a/tests/format/js/tuple/jsfmt.spec.js +++ b/tests/format/js/tuple/jsfmt.spec.js @@ -1,6 +1,7 @@ run_spec(__dirname, ["babel"], { errors: { babel: ["invalid-tuple-holes.js"], + __babel_estree: ["invalid-tuple-holes.js"], espree: true, meriyah: true, }, diff --git a/tests/format/js/yield-star-spacing/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/yield-star-spacing/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..6f1e86389b --- /dev/null +++ b/tests/format/js/yield-star-spacing/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,286 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`correct.js - {"yieldStarSpacing":true,"generatorStarSpacing":true,"spaceBeforeFunctionParen":true} format 1`] = ` +====================================options===================================== +generatorStarSpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceBeforeFunctionParen: true +yieldStarSpacing: true + | printWidth +=====================================input====================================== +// correct for: +// * "yield-star-spacing": [ "error", "both" ] +// but *not* for the following standard.js rules: +// * "generator-star-spacing": [ "error", "both" ], +// * "space-before-function-paren": [ "error", "always" ], +// * "semi": [ "error", "never" ], + +function* generator() { + yield * other(); + // ensure this one is *not* affected: + yield "done"; +} + +=====================================output===================================== +// correct for: +// * "yield-star-spacing": [ "error", "both" ] +// but *not* for the following standard.js rules: +// * "generator-star-spacing": [ "error", "both" ], +// * "space-before-function-paren": [ "error", "always" ], +// * "semi": [ "error", "never" ], + +function * generator () { + yield * other(); + // ensure this one is *not* affected: + yield "done"; +} + +================================================================================ +`; + +exports[`correct.js - {"yieldStarSpacing":true,"generatorStarSpacing":true} format 1`] = ` +====================================options===================================== +generatorStarSpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +yieldStarSpacing: true + | printWidth +=====================================input====================================== +// correct for: +// * "yield-star-spacing": [ "error", "both" ] +// but *not* for the following standard.js rules: +// * "generator-star-spacing": [ "error", "both" ], +// * "space-before-function-paren": [ "error", "always" ], +// * "semi": [ "error", "never" ], + +function* generator() { + yield * other(); + // ensure this one is *not* affected: + yield "done"; +} + +=====================================output===================================== +// correct for: +// * "yield-star-spacing": [ "error", "both" ] +// but *not* for the following standard.js rules: +// * "generator-star-spacing": [ "error", "both" ], +// * "space-before-function-paren": [ "error", "always" ], +// * "semi": [ "error", "never" ], + +function * generator () { + yield * other(); + // ensure this one is *not* affected: + yield "done"; +} + +================================================================================ +`; + +exports[`correct.js - {"yieldStarSpacing":true} format 1`] = ` +====================================options===================================== +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +yieldStarSpacing: true + | printWidth +=====================================input====================================== +// correct for: +// * "yield-star-spacing": [ "error", "both" ] +// but *not* for the following standard.js rules: +// * "generator-star-spacing": [ "error", "both" ], +// * "space-before-function-paren": [ "error", "always" ], +// * "semi": [ "error", "never" ], + +function* generator() { + yield * other(); + // ensure this one is *not* affected: + yield "done"; +} + +=====================================output===================================== +// correct for: +// * "yield-star-spacing": [ "error", "both" ] +// but *not* for the following standard.js rules: +// * "generator-star-spacing": [ "error", "both" ], +// * "space-before-function-paren": [ "error", "always" ], +// * "semi": [ "error", "never" ], + +function* generator() { + yield * other(); + // ensure this one is *not* affected: + yield "done"; +} + +================================================================================ +`; + +exports[`incorrect.js - {"yieldStarSpacing":true,"generatorStarSpacing":true,"spaceBeforeFunctionParen":true} format 1`] = ` +====================================options===================================== +generatorStarSpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +spaceBeforeFunctionParen: true +yieldStarSpacing: true + | printWidth +=====================================input====================================== +// *incorrect* for the following standard.js rules: +// * "yield-star-spacing": [ "error", "both" ] +// * "generator-star-spacing": [ "error", "both" ], +// * "space-before-function-paren": [ "error", "always" ], +// * "semi": [ "error", "never" ], + + +function *generator() { + yield *other(); + // ensure this one remains correct: + yield "done"; +} +function* generator() { + yield* other(); + // ensure this one remains correct: + yield "done"; +} +function*generator() { + yield*other(); + // ensure this one remains correct: + yield "done" +} + +=====================================output===================================== +// *incorrect* for the following standard.js rules: +// * "yield-star-spacing": [ "error", "both" ] +// * "generator-star-spacing": [ "error", "both" ], +// * "space-before-function-paren": [ "error", "always" ], +// * "semi": [ "error", "never" ], + +function * generator () { + yield * other(); + // ensure this one remains correct: + yield "done"; +} +function * generator () { + yield * other(); + // ensure this one remains correct: + yield "done"; +} +function * generator () { + yield * other(); + // ensure this one remains correct: + yield "done"; +} + +================================================================================ +`; + +exports[`incorrect.js - {"yieldStarSpacing":true,"generatorStarSpacing":true} format 1`] = ` +====================================options===================================== +generatorStarSpacing: true +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +yieldStarSpacing: true + | printWidth +=====================================input====================================== +// *incorrect* for the following standard.js rules: +// * "yield-star-spacing": [ "error", "both" ] +// * "generator-star-spacing": [ "error", "both" ], +// * "space-before-function-paren": [ "error", "always" ], +// * "semi": [ "error", "never" ], + + +function *generator() { + yield *other(); + // ensure this one remains correct: + yield "done"; +} +function* generator() { + yield* other(); + // ensure this one remains correct: + yield "done"; +} +function*generator() { + yield*other(); + // ensure this one remains correct: + yield "done" +} + +=====================================output===================================== +// *incorrect* for the following standard.js rules: +// * "yield-star-spacing": [ "error", "both" ] +// * "generator-star-spacing": [ "error", "both" ], +// * "space-before-function-paren": [ "error", "always" ], +// * "semi": [ "error", "never" ], + +function * generator () { + yield * other(); + // ensure this one remains correct: + yield "done"; +} +function * generator () { + yield * other(); + // ensure this one remains correct: + yield "done"; +} +function * generator () { + yield * other(); + // ensure this one remains correct: + yield "done"; +} + +================================================================================ +`; + +exports[`incorrect.js - {"yieldStarSpacing":true} format 1`] = ` +====================================options===================================== +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +yieldStarSpacing: true + | printWidth +=====================================input====================================== +// *incorrect* for the following standard.js rules: +// * "yield-star-spacing": [ "error", "both" ] +// * "generator-star-spacing": [ "error", "both" ], +// * "space-before-function-paren": [ "error", "always" ], +// * "semi": [ "error", "never" ], + + +function *generator() { + yield *other(); + // ensure this one remains correct: + yield "done"; +} +function* generator() { + yield* other(); + // ensure this one remains correct: + yield "done"; +} +function*generator() { + yield*other(); + // ensure this one remains correct: + yield "done" +} + +=====================================output===================================== +// *incorrect* for the following standard.js rules: +// * "yield-star-spacing": [ "error", "both" ] +// * "generator-star-spacing": [ "error", "both" ], +// * "space-before-function-paren": [ "error", "always" ], +// * "semi": [ "error", "never" ], + +function* generator() { + yield * other(); + // ensure this one remains correct: + yield "done"; +} +function* generator() { + yield * other(); + // ensure this one remains correct: + yield "done"; +} +function* generator() { + yield * other(); + // ensure this one remains correct: + yield "done"; +} + +================================================================================ +`; diff --git a/tests/format/js/yield-star-spacing/correct.js b/tests/format/js/yield-star-spacing/correct.js new file mode 100644 index 0000000000..3247ed8007 --- /dev/null +++ b/tests/format/js/yield-star-spacing/correct.js @@ -0,0 +1,12 @@ +// correct for: +// * "yield-star-spacing": [ "error", "both" ] +// but *not* for the following standard.js rules: +// * "generator-star-spacing": [ "error", "both" ], +// * "space-before-function-paren": [ "error", "always" ], +// * "semi": [ "error", "never" ], + +function* generator() { + yield * other(); + // ensure this one is *not* affected: + yield "done"; +} diff --git a/tests/format/js/yield-star-spacing/incorrect.js b/tests/format/js/yield-star-spacing/incorrect.js new file mode 100644 index 0000000000..9873526fa4 --- /dev/null +++ b/tests/format/js/yield-star-spacing/incorrect.js @@ -0,0 +1,22 @@ +// *incorrect* for the following standard.js rules: +// * "yield-star-spacing": [ "error", "both" ] +// * "generator-star-spacing": [ "error", "both" ], +// * "space-before-function-paren": [ "error", "always" ], +// * "semi": [ "error", "never" ], + + +function *generator() { + yield *other(); + // ensure this one remains correct: + yield "done"; +} +function* generator() { + yield* other(); + // ensure this one remains correct: + yield "done"; +} +function*generator() { + yield*other(); + // ensure this one remains correct: + yield "done" +} diff --git a/tests/format/js/yield-star-spacing/jsfmt.spec.js b/tests/format/js/yield-star-spacing/jsfmt.spec.js new file mode 100644 index 0000000000..db58231b45 --- /dev/null +++ b/tests/format/js/yield-star-spacing/jsfmt.spec.js @@ -0,0 +1,12 @@ +run_spec(__dirname, ["babel", "babel-flow", "flow", "typescript"], { + yieldStarSpacing: true, +}); +run_spec(__dirname, ["babel", "babel-flow", "flow", "typescript"], { + yieldStarSpacing: true, + generatorStarSpacing: true, +}); +run_spec(__dirname, ["babel", "babel-flow", "flow", "typescript"], { + yieldStarSpacing: true, + generatorStarSpacing: true, + spaceBeforeFunctionParen: true, +}); diff --git a/tests/format/jsx/do/__snapshots__/jsfmt.spec.js.snap b/tests/format/jsx/do/__snapshots__/jsfmt.spec.js.snap index 4e00195c94..419548438f 100644 --- a/tests/format/jsx/do/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/jsx/do/__snapshots__/jsfmt.spec.js.snap @@ -2,7 +2,7 @@ exports[`do.js format 1`] = ` ====================================options===================================== -parsers: ["babel"] +parsers: ["babel", "babel-flow"] printWidth: 80 | printWidth =====================================input====================================== diff --git a/tests/format/jsx/do/jsfmt.spec.js b/tests/format/jsx/do/jsfmt.spec.js index 8382eddeb1..b78cfba099 100644 --- a/tests/format/jsx/do/jsfmt.spec.js +++ b/tests/format/jsx/do/jsfmt.spec.js @@ -1 +1 @@ -run_spec(__dirname, ["babel"]); +run_spec(__dirname, ["babel", "babel-flow"]); diff --git a/tests/format/jsx/jsx/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap b/tests/format/jsx/jsx/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..720b7f12b1 --- /dev/null +++ b/tests/format/jsx/jsx/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,1511 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`array-iter.js - {"singleQuote":false,"jsxSingleQuote":false,"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +jsxSingleQuote: false +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +singleQuote: false +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +const UsersList = ({ users }) => ( +
+

Users list

+
    + {users.map(user => ( +
  • {user.name}
  • + ))} +
+
+) + +const TodoList = ({ todos }) => ( +
+
    {_.map(todos, (todo, i) => )}
+
+); + +
+ {scopes + .filter(scope => scope.value !== '') + .map((scope, i) => ( + + ))} +
+ +=====================================output===================================== +const UsersList = ( { users } ) => ( +
+

Users list

+
    + { users.map( user => ( +
  • { user.name }
  • + ) ) } +
+
+); + +const TodoList = ( { todos } ) => ( +
+
    + { _.map( todos, ( todo, i ) => ( + + ) ) } +
+
+); + +
+ { scopes + .filter( scope => scope.value !== "" ) + .map( ( scope, i ) => ( + + ) ) } +
; + +================================================================================ +`; + +exports[`attr-comments.js - {"singleQuote":false,"jsxSingleQuote":false,"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +jsxSingleQuote: false +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +singleQuote: false +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== + fn(arg) + } + propArrowWithBreak={ + // comment + arg => + fn({ + makeItBreak + }) + } + propArray={ + // comment + [el1, el2] + } + propObj={ + // comment + { key: val } + } + propTemplate={ + // comment + \`text\` + } +/>; + +=====================================output===================================== + fn( arg ) + } + propArrowWithBreak={ + // comment + arg => + fn( { + makeItBreak + } ) + } + propArray={ + // comment + [ el1, el2 ] + } + propObj={ + // comment + { key: val } + } + propTemplate={ + // comment + \`text\` + } +/>; + +================================================================================ +`; + +exports[`conditional-expression.js - {"singleQuote":false,"jsxSingleQuote":false,"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +jsxSingleQuote: false +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +singleQuote: false +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +// There are two ways to print ConditionalExpressions: "normal mode" and +// "JSX mode". This is normal mode (when breaking): +// +// test +// ? consequent +// : alternate; +// +// And this is JSX mode (when breaking): +// +// test ? ( +// consequent +// ) : ( +// alternate +// ); +// +// When non-breaking, they look the same: +// +// test ? consequent : alternate; +// +// We only print a conditional expression in JSX mode if its test, +// consequent, or alternate are JSXElements. +// Otherwise, we print in normal mode. + +// This ConditionalExpression has no JSXElements so it prints in normal mode. +// The line does not break. +normalModeNonBreaking ? "a" : "b"; + +// This ConditionalExpression has no JSXElements so it prints in normal mode. +// Its consequent is very long, so it breaks out to multiple lines. +normalModeBreaking + ? johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa + : "c"; + +// This ConditionalExpression prints in JSX mode because its test is a +// JSXElement. It is non-breaking. +// Note: I have never, ever seen someone use a JSXElement as the test in a +// ConditionalExpression. But this test is included for completeness. +
? jsxModeFromElementNonBreaking : "a"; + +// This ConditionalExpression prints in JSX mode because its consequent is a +// JSXElement. It is non-breaking. +jsxModeFromElementNonBreaking ?
: "a"; + +// This ConditionalExpression prints in JSX mode because its alternate is a +// JSXElement. It is non-breaking. +jsxModeFromElementNonBreaking ? "a" :
; + +// This ConditionalExpression prints in JSX mode because its test is a +// JSXElement. It is breaking. +// Note: I have never, ever seen someone use a JSXElement as the test in a +// ConditionalExpression. But this test is included for completeness. +
+ thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo +
? ( + "jsx mode from element breaking" +) : ( + "a" +); + +// This ConditionalExpression prints in JSX mode because its consequent is a +// JSXElement. It is breaking. +jsxModeFromElementBreaking ? ( +
+ thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo +
+) : ( + "a" +); + +// This ConditionalExpression prints in JSX mode because its alternate is a +// JSXElement. It is breaking. +jsxModeFromElementBreaking ? ( + "a" +) : ( +
+ thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo +
+); + +// This chain of ConditionalExpressions prints in JSX mode because the parent of +// the outermost ConditionalExpression is a JSXExpressionContainer. It is +// non-breaking. +
+ {a ? "a" : b ? "b" : "c"} +
; + +// This chain of ConditionalExpressions prints in JSX mode because there is a +// JSX element somewhere in the chain. It is non-breaking. +cable ? "satellite" : isPublic ? "affairs" : network ? : "dun"; + +// This chain of ConditionalExpressions prints in JSX mode because there is a +// JSX element somewhere in the chain (in this case, at the end). It is +// breaking; notice the consequents and alternates in the entire chain get +// wrapped in parens. +cable ? ( + "satellite" +) : isPublic ? ( + "affairs" +) : network ? ( +
+ thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo +
+) : "dunno"; + +// This chain of ConditionalExpressions prints in JSX mode because there is a +// JSX element somewhere in the chain (in this case, at the beginning). It is +// breaking; notice the consequents and alternates in the entire chain get +// wrapped in parens. +cable ? ( +
+ thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo +
+) : sateline ? ( + "public" +) : affairs ? ( + "network" +) : "dunno"; + +// This chain of ConditionalExpressions prints in JSX mode because there is a +// JSX element somewhere in the chain. It is breaking; notice the consequents +// and alternates in the entire chain get wrapped in parens. +
+ {properties.length > 1 || + (properties.length === 1 && properties[0].apps.size > 1) ? ( + draggingApp == null || newPropertyName == null ? ( + + ) : ( + + ) + ) : null} +
; + +// #3552 +foo ? loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong jsx : +undefined + +=====================================output===================================== +// There are two ways to print ConditionalExpressions: "normal mode" and +// "JSX mode". This is normal mode (when breaking): +// +// test +// ? consequent +// : alternate; +// +// And this is JSX mode (when breaking): +// +// test ? ( +// consequent +// ) : ( +// alternate +// ); +// +// When non-breaking, they look the same: +// +// test ? consequent : alternate; +// +// We only print a conditional expression in JSX mode if its test, +// consequent, or alternate are JSXElements. +// Otherwise, we print in normal mode. + +// This ConditionalExpression has no JSXElements so it prints in normal mode. +// The line does not break. +normalModeNonBreaking ? "a" : "b"; + +// This ConditionalExpression has no JSXElements so it prints in normal mode. +// Its consequent is very long, so it breaks out to multiple lines. +normalModeBreaking + ? johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa + : "c"; + +// This ConditionalExpression prints in JSX mode because its test is a +// JSXElement. It is non-breaking. +// Note: I have never, ever seen someone use a JSXElement as the test in a +// ConditionalExpression. But this test is included for completeness. +
? jsxModeFromElementNonBreaking : "a"; + +// This ConditionalExpression prints in JSX mode because its consequent is a +// JSXElement. It is non-breaking. +jsxModeFromElementNonBreaking ?
: "a"; + +// This ConditionalExpression prints in JSX mode because its alternate is a +// JSXElement. It is non-breaking. +jsxModeFromElementNonBreaking ? "a" :
; + +// This ConditionalExpression prints in JSX mode because its test is a +// JSXElement. It is breaking. +// Note: I have never, ever seen someone use a JSXElement as the test in a +// ConditionalExpression. But this test is included for completeness. +
+ + thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo + +
? ( + "jsx mode from element breaking" +) : ( + "a" +); + +// This ConditionalExpression prints in JSX mode because its consequent is a +// JSXElement. It is breaking. +jsxModeFromElementBreaking ? ( +
+ + thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo + +
+) : ( + "a" +); + +// This ConditionalExpression prints in JSX mode because its alternate is a +// JSXElement. It is breaking. +jsxModeFromElementBreaking ? ( + "a" +) : ( +
+ + thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo + +
+); + +// This chain of ConditionalExpressions prints in JSX mode because the parent of +// the outermost ConditionalExpression is a JSXExpressionContainer. It is +// non-breaking. +
{ a ? "a" : b ? "b" : "c" }
; + +// This chain of ConditionalExpressions prints in JSX mode because there is a +// JSX element somewhere in the chain. It is non-breaking. +cable ? "satellite" : isPublic ? "affairs" : network ? : "dun"; + +// This chain of ConditionalExpressions prints in JSX mode because there is a +// JSX element somewhere in the chain (in this case, at the end). It is +// breaking; notice the consequents and alternates in the entire chain get +// wrapped in parens. +cable ? ( + "satellite" +) : isPublic ? ( + "affairs" +) : network ? ( +
+ + thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo + +
+) : ( + "dunno" +); + +// This chain of ConditionalExpressions prints in JSX mode because there is a +// JSX element somewhere in the chain (in this case, at the beginning). It is +// breaking; notice the consequents and alternates in the entire chain get +// wrapped in parens. +cable ? ( +
+ + thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo + +
+) : sateline ? ( + "public" +) : affairs ? ( + "network" +) : ( + "dunno" +); + +// This chain of ConditionalExpressions prints in JSX mode because there is a +// JSX element somewhere in the chain. It is breaking; notice the consequents +// and alternates in the entire chain get wrapped in parens. +
+ { properties.length > 1 || + ( properties.length === 1 && properties[ 0 ].apps.size > 1 ) ? ( + draggingApp == null || newPropertyName == null ? ( + + ) : ( + + ) + ) : null } +
; + +// #3552 +foo ? ( + + loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong jsx + +) : undefined; + +================================================================================ +`; + +exports[`expression.js - {"singleQuote":false,"jsxSingleQuote":false,"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +jsxSingleQuote: false +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +singleQuote: false +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +; + +; + + + {() => ( + + + + )} +; + + + {items.map(item => ( + + + + ))} +; + + + {function() { + return ( + + + + ); + }} +; + +; + + + test + +}/>; + + doLogClick("short", "short", data)} +/>; + + + doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data) + } +/>; + + { + doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data) + }} +/>; + +, + ) => { + this.setState({ + updatedTask: this.state.updatedTask.set(key, value) + }); + }} +/>; + + + {data => doLogClick("short", "short", data)} +; + + + {data => + doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data) + } +; + + + {data => { + doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data) + }} +; + + + {( + key: "possible_key_1" | "possible_key_2" | "possible_key_3", + value: string | Immutable.List, + ) => { + this.setState({ + updatedTask: this.state.updatedTask.set(key, value) + }); + }} +; + + +
+ {Array(20) + .fill() + .map((_, i) => ( +

{i + 1}

+ ))} +
+
; + +=====================================output===================================== +; + +; + + + { () => ( + + + + ) } +; + + + { items.map( item => ( + + + + ) ) } +; + + + { function () { + return ( + + + + ); + } } +; + +; + +test } />; + + doLogClick( "short", "short", data ) } +/>; + + + doLogClick( + "long_name_long_name_long_name", + "long_name_long_name_long_name", + data + ) + } +/>; + + { + doLogClick( + "long_name_long_name_long_name", + "long_name_long_name_long_name", + data + ); + } } +/>; + + + ) => { + this.setState( { + updatedTask: this.state.updatedTask.set( key, value ) + } ); + } } +/>; + + + { data => doLogClick( "short", "short", data ) } +; + + + { data => + doLogClick( + "long_name_long_name_long_name", + "long_name_long_name_long_name", + data + ) + } +; + + + { data => { + doLogClick( + "long_name_long_name_long_name", + "long_name_long_name_long_name", + data + ); + } } +; + + + { ( + key: "possible_key_1" | "possible_key_2" | "possible_key_3", + value: string | Immutable.List< string > + ) => { + this.setState( { + updatedTask: this.state.updatedTask.set( key, value ) + } ); + } } +; + + +
+ { Array( 20 ) + .fill() + .map( ( _, i ) => ( +

{ i + 1 }

+ ) ) } +
+
; + +================================================================================ +`; + +exports[`flow_fix_me.js - {"singleQuote":false,"jsxSingleQuote":false,"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +jsxSingleQuote: false +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +singleQuote: false +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +const aDiv = ( + /* $FlowFixMe */ +
+ Foo bar +
+); + +=====================================output===================================== +const aDiv = ( + /* $FlowFixMe */ +
Foo bar
+); + +================================================================================ +`; + +exports[`html_escape.js - {"singleQuote":false,"jsxSingleQuote":false,"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +jsxSingleQuote: false +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +singleQuote: false +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +export default () => ; + +() => ; + +=====================================output===================================== +export default () => ; + +() => ; + +================================================================================ +`; + +exports[`hug.js - {"singleQuote":false,"jsxSingleQuote":false,"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +jsxSingleQuote: false +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +singleQuote: false +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +
+ {__DEV__ + ? this.renderDevApp() + :
+ {routes.map(route => ( + + ))} +
} +
; + +
+ {__DEV__ &&
+ {routes.map(route => ( + + ))} +
} +
; + +
+ {member.memberName.memberSomething + + (member.memberDef.memberSomething.signatures ? '()' : '')} +
+ +=====================================output===================================== +
+ { __DEV__ ? ( + this.renderDevApp() + ) : ( +
+ { routes.map( route => ( + + ) ) } +
+ ) } +
; + +
+ { __DEV__ && ( +
+ { routes.map( route => ( + + ) ) } +
+ ) } +
; + +
+ { member.memberName.memberSomething + + ( member.memberDef.memberSomething.signatures ? "()" : "" ) } +
; + +================================================================================ +`; + +exports[`logical-expression.js - {"singleQuote":false,"jsxSingleQuote":false,"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +jsxSingleQuote: false +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +singleQuote: false +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +
+ {a || "b"} +
; + +
+ {a && "b"} +
; + +
+ {a || } +
; + +
+ {a && } +
; + +
+ {a && make this text just so long enough to break this to the next line} +
; + +
+ {a && b && make this text just so long enough to break this to the next line} +
; + +
+ {a && +
+
+
+
} +
; + +=====================================output===================================== +
{ a || "b" }
; + +
{ a && "b" }
; + +
{ a || }
; + +
{ a && }
; + +
+ { a && ( + + make this text just so long enough to break this to the next line + + ) } +
; + +
+ { a && b && ( + + make this text just so long enough to break this to the next line + + ) } +
; + +
+ { a && ( + +
+
+
+
+ ) } +
; + +================================================================================ +`; + +exports[`object-property.js - {"singleQuote":false,"jsxSingleQuote":false,"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +jsxSingleQuote: false +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +singleQuote: false +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +const tabs = [ + { + title: "General Info", + content: ( + + ) + } +]; + +=====================================output===================================== +const tabs = [ + { + title: "General Info", + content: ( + + ) + } +]; + +================================================================================ +`; + +exports[`open-break.js - {"singleQuote":false,"jsxSingleQuote":false,"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +jsxSingleQuote: false +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +singleQuote: false +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== + { + a +}}>{header}{showSort}; + + { + a +}}>{header}; + +{\` a very long text that does not break \`}; + +=====================================output===================================== + { + a; + } } +> + { header } + { showSort } +; + + { + a; + } } +> + { header } + +; + +{ \` a very long text that does not break \` }; + +================================================================================ +`; + +exports[`parens.js - {"singleQuote":false,"jsxSingleQuote":false,"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +jsxSingleQuote: false +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +singleQuote: false +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +a = [ + , + , +]; + +
+ +f?.(
); +(
)(); +(
)?.(); + +new Foo(); +new Foo(()) + +=====================================output===================================== +a = [ + , + +]; + +
; + +f?.(
); +(
)(); +(
)?.(); + +new Foo( ); +new Foo( ); + +================================================================================ +`; + +exports[`quotes.js - {"singleQuote":false,"jsxSingleQuote":false,"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +jsxSingleQuote: false +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +singleQuote: false +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +
; +
; +
&quot;'} />; +
; +
; +
; +
; + +

+ GitHub Desktop has encountered an unrecoverable error and will need to 1231231 + restart. This has been reported to the team, but if youencounter this121312331 + repeatedly please report this issue to the GitHub 12312312312312313{' '}{' '} +

+ +=====================================output===================================== +
; +
; +
&quot;" } />; +
; +
; +
; +
; + +

+ GitHub Desktop has encountered an unrecoverable error and will need to 1231231 + restart. This has been reported to the team, but if youencounter this121312331 + repeatedly please report this issue to the GitHub 12312312312312313{ " " }{" "} +

; + +================================================================================ +`; + +exports[`return-statement.js - {"singleQuote":false,"jsxSingleQuote":false,"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +jsxSingleQuote: false +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +singleQuote: false +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +const NonBreakingArrowExpression = () =>
; + +const BreakingArrowExpression = () =>
+
+ bla bla bla +
+
; + +const NonBreakingArrowExpressionWBody = () => { + return ( +
+ ); +}; + +const BreakingArrowExpressionWBody = () => { + return
+
+ bla bla bla +
+
+}; + +const NonBreakingFunction = function() { + return ( +
+ ); +}; + +const BreakingFunction = function() { + return
+
+ bla bla bla +
+
+}; + +class NonBreakingClass extends React.component { + render() { + return ( +
+ ); + } +} + +class BreakingClass extends React.component { + render() { + return
+
+ bla bla bla +
+
; + } +} + +=====================================output===================================== +const NonBreakingArrowExpression = () =>
; + +const BreakingArrowExpression = () => ( +
+
bla bla bla
+
+); + +const NonBreakingArrowExpressionWBody = () => { + return
; +}; + +const BreakingArrowExpressionWBody = () => { + return ( +
+
bla bla bla
+
+ ); +}; + +const NonBreakingFunction = function () { + return
; +}; + +const BreakingFunction = function () { + return ( +
+
bla bla bla
+
+ ); +}; + +class NonBreakingClass extends React.component { + render() { + return
; + } +} + +class BreakingClass extends React.component { + render() { + return ( +
+
bla bla bla
+
+ ); + } +} + +================================================================================ +`; + +exports[`self-closing.js - {"singleQuote":false,"jsxSingleQuote":false,"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +jsxSingleQuote: false +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +singleQuote: false +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +; +; + +=====================================output===================================== +; +; + +================================================================================ +`; + +exports[`spacing.js - {"singleQuote":false,"jsxSingleQuote":false,"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +jsxSingleQuote: false +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +singleQuote: false +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +const Labels = { + label1: ( + + Label 1 + + ), + + label2: ( + + Label 2 + + ), + + label3: ( + + Label 3 + + ), +}; + +=====================================output===================================== +const Labels = { + label1: Label 1, + + label2: Label 2, + + label3: Label 3 +}; + +================================================================================ +`; + +exports[`template-literal-in-attr.js - {"singleQuote":false,"jsxSingleQuote":false,"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +jsxSingleQuote: false +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +singleQuote: false +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +
+
+
foo
+
+
+ +=====================================output===================================== +
+
+
+ foo +
+
+
; + +================================================================================ +`; + +exports[`ternary.js - {"singleQuote":false,"jsxSingleQuote":false,"spaceInParens":true,"arrayBracketSpacing":true,"computedPropertySpacing":true,"templateCurlySpacing":true,"typeAngleBracketSpacing":true,"arrowParens":"avoid","trailingComma":"none"} format 1`] = ` +====================================options===================================== +arrayBracketSpacing: true +arrowParens: "avoid" +computedPropertySpacing: true +jsxSingleQuote: false +parsers: ["babel", "babel-flow", "flow", "typescript"] +printWidth: 80 +singleQuote: false +spaceInParens: true +templateCurlySpacing: true +trailingComma: "none" +typeAngleBracketSpacing: true + | printWidth +=====================================input====================================== +a == 3 ? (a =

123

) : (a =

abc

); + +=====================================output===================================== +a == 3 ? ( a =

123

) : ( a =

abc

); + +================================================================================ +`; diff --git a/tests/format/jsx/jsx/with-inner-spacing/jsfmt.spec.js b/tests/format/jsx/jsx/with-inner-spacing/jsfmt.spec.js new file mode 100644 index 0000000000..56db0445ac --- /dev/null +++ b/tests/format/jsx/jsx/with-inner-spacing/jsfmt.spec.js @@ -0,0 +1,19 @@ +// [prettierx] test script notice: +// This test script runs for test files in parent directory, +// **not** on any files in *this* directory. + +const dirPath = `${__dirname}/..`; + +run_spec(dirPath, ["babel", "babel-flow", "flow", "typescript"], { + singleQuote: false, + jsxSingleQuote: false, + // [prettierx] test with --paren-spacing + spaceInParens: true, + arrayBracketSpacing: true, + computedPropertySpacing: true, + templateCurlySpacing: true, + typeAngleBracketSpacing: true, + // recommended: + arrowParens: "avoid", + trailingComma: "none", // ("Standard JS") +}); diff --git a/tests/format/markdown/markdown/__snapshots__/jsfmt.spec.js.snap b/tests/format/markdown/markdown/__snapshots__/jsfmt.spec.js.snap index 863262b3e0..bcecb6508f 100644 --- a/tests/format/markdown/markdown/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/markdown/markdown/__snapshots__/jsfmt.spec.js.snap @@ -622,17 +622,6 @@ Default | CLI Override | API Override --------|--------------|------------- \`"none"\` | --trailing-comma | trailingComma: "" -### Bracket Spacing -Print spaces between brackets in object literals. - -Valid options: - * \`true\` - Example: \`{ foo: bar }\`. - * \`false\` - Example: \`{foo: bar}\`. - -Default | CLI Override | API Override ---------|--------------|------------- -\`true\` | \`--no-bracket-spacing\` | \`bracketSpacing: \` - ### JSX Brackets Put the \`>\` of a multi-line JSX element at the end of the last line instead of being alone on the next line (does not apply to self closing elements). @@ -1640,19 +1629,6 @@ Valid options: | -------- | ------------------------------------------------------ | ------------------------------------------------------ | | \`"none"\` | --trailing-comma | trailingComma: "" | -### Bracket Spacing - -Print spaces between brackets in object literals. - -Valid options: - -- \`true\` - Example: \`{ foo: bar }\`. -- \`false\` - Example: \`{foo: bar}\`. - -| Default | CLI Override | API Override | -| ------- | ---------------------- | ------------------------ | -| \`true\` | \`--no-bracket-spacing\` | \`bracketSpacing: \` | - ### JSX Brackets Put the \`>\` of a multi-line JSX element at the end of the last line instead of @@ -2601,17 +2577,6 @@ Default | CLI Override | API Override --------|--------------|------------- \`"none"\` | --trailing-comma | trailingComma: "" -### Bracket Spacing -Print spaces between brackets in object literals. - -Valid options: - * \`true\` - Example: \`{ foo: bar }\`. - * \`false\` - Example: \`{foo: bar}\`. - -Default | CLI Override | API Override ---------|--------------|------------- -\`true\` | \`--no-bracket-spacing\` | \`bracketSpacing: \` - ### JSX Brackets Put the \`>\` of a multi-line JSX element at the end of the last line instead of being alone on the next line (does not apply to self closing elements). @@ -3619,19 +3584,6 @@ Valid options: | -------- | ------------------------------------------------------ | ------------------------------------------------------ | | \`"none"\` | --trailing-comma | trailingComma: "" | -### Bracket Spacing - -Print spaces between brackets in object literals. - -Valid options: - -- \`true\` - Example: \`{ foo: bar }\`. -- \`false\` - Example: \`{foo: bar}\`. - -| Default | CLI Override | API Override | -| ------- | ---------------------- | ------------------------ | -| \`true\` | \`--no-bracket-spacing\` | \`bracketSpacing: \` | - ### JSX Brackets Put the \`>\` of a multi-line JSX element at the end of the last line instead of diff --git a/tests/format/markdown/markdown/real-world-case.md b/tests/format/markdown/markdown/real-world-case.md index 89badcc6c7..482cf9fc3d 100644 --- a/tests/format/markdown/markdown/real-world-case.md +++ b/tests/format/markdown/markdown/real-world-case.md @@ -612,17 +612,6 @@ Default | CLI Override | API Override --------|--------------|------------- `"none"` | --trailing-comma | trailingComma: "" -### Bracket Spacing -Print spaces between brackets in object literals. - -Valid options: - * `true` - Example: `{ foo: bar }`. - * `false` - Example: `{foo: bar}`. - -Default | CLI Override | API Override ---------|--------------|------------- -`true` | `--no-bracket-spacing` | `bracketSpacing: ` - ### JSX Brackets Put the `>` of a multi-line JSX element at the end of the last line instead of being alone on the next line (does not apply to self closing elements). diff --git a/tests/format/misc/typescript-babel-only/__snapshots__/jsfmt.spec.js.snap b/tests/format/misc/typescript-babel-only/__snapshots__/jsfmt.spec.js.snap index ecaec1d3d7..45f2edd137 100644 --- a/tests/format/misc/typescript-babel-only/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/misc/typescript-babel-only/__snapshots__/jsfmt.spec.js.snap @@ -60,68 +60,6 @@ class Bar { ================================================================================ `; -exports[`ts-4.3-override-modifier.ts format 1`] = ` -====================================options===================================== -parsers: ["babel-ts"] -printWidth: 80 - | printWidth -=====================================input====================================== -class MyClass extends BaseClass { - override show() {} - public override show() {} - override size = 5; - override readonly size = 5; -} - -=====================================output===================================== -class MyClass extends BaseClass { - override show() {} - public override show() {} - override size = 5; - override readonly size = 5; -} - -================================================================================ -`; - -exports[`ts4.3-type-members-get-set.ts format 1`] = ` -====================================options===================================== -parsers: ["babel-ts"] -printWidth: 80 - | printWidth -=====================================input====================================== -interface Foo { - get foo(): string; - set bar(v); -} - -type Foo = { - get foo(): string; - set bar(v); -} - -interface Foo { - set bar(foo: string); -} - -=====================================output===================================== -interface Foo { - get foo(): string; - set bar(v); -} - -type Foo = { - get foo(): string; - set bar(v); -}; - -interface Foo { - set bar(foo: string); -} - -================================================================================ -`; - exports[`tuple-labeled-ts.ts format 1`] = ` ====================================options===================================== parsers: ["babel-ts"] diff --git a/tests/format/scss/scss/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap b/tests/format/scss/scss/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..16ef535fd3 --- /dev/null +++ b/tests/format/scss/scss/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,2382 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`arbitrary-arguments.scss - {"cssParenSpacing":true} format 1`] = ` +====================================options===================================== +cssParenSpacing: true +parsers: ["scss"] +printWidth: 80 + | printWidth +=====================================input====================================== +body { + test: foo(return-list($list)...); +} +body { + test: foo(bar($list)...); +} +body { + test: foo($list...); +} +@mixin syntax-colors($args...) { + @debug meta.keywords($args); + // (string: #080, comment: #800, variable: $60b) + + @each $name, $color in meta.keywords($args) { + pre span.stx-#{$name} { + color: $color; + } + } +} +$form-selectors: "input.name", "input.address", "input.zip" !default; +@include order(150px, $form-selectors...); +@mixin linear-gradient($direction, $gradients...) { + background-color: nth($gradients, 1); + background-image: linear-gradient($direction, $gradients...); +} +$parameters: ( + 'c': 'kittens', + 'a': true, + 'b': 42 +); +$value: dummy($parameters...); + +body { + background-color: rgba(50, 50, 50, 50); + background-color: rgba(50 50 50 50...); + background-color: rgba(50 50 .50 50...); + background-color: rgba(50 50 50. .50...); + // Input is not technically valid ( output is ), but still nice to know that the \`.\` gets dropped as it would for \`50.\` + background-color: rgba(50 50 50 50....); + width: min(50px 20px 30px...); +} + +=====================================output===================================== +body { + test: foo( return-list( $list )... ); +} +body { + test: foo( bar( $list )... ); +} +body { + test: foo( $list... ); +} +@mixin syntax-colors( $args... ) { + @debug meta.keywords( $args ); + // (string: #080, comment: #800, variable: $60b) + + @each $name, $color in meta.keywords( $args ) { + pre span.stx-#{$name} { + color: $color; + } + } +} +$form-selectors: "input.name", "input.address", "input.zip" !default; +@include order( 150px, $form-selectors... ); +@mixin linear-gradient( $direction, $gradients... ) { + background-color: nth( $gradients, 1 ); + background-image: linear-gradient( $direction, $gradients... ); +} +$parameters: ( + "c": "kittens", + "a": true, + "b": 42, +); +$value: dummy( $parameters... ); + +body { + background-color: rgba( 50, 50, 50, 50 ); + background-color: rgba( 50 50 50 50... ); + background-color: rgba( 50 50 0.5 50... ); + background-color: rgba( 50 50 50 0.5... ); + // Input is not technically valid ( output is ), but still nice to know that the \`.\` gets dropped as it would for \`50.\` + background-color: rgba( 50 50 50 50... ); + width: min( 50px 20px 30px... ); +} + +================================================================================ +`; + +exports[`comments.scss - {"cssParenSpacing":true} format 1`] = ` +====================================options===================================== +cssParenSpacing: true +parsers: ["scss"] +printWidth: 80 + | printWidth +=====================================input====================================== +// This comment won't be included in the CSS. +//This comment won't be included in the CSS. +// This comment won't be included in the CSS. + +/* But this comment will, except in compressed mode. */ +/* But this comment will, except in compressed mode. */ +/*But this comment will, except in compressed mode.*/ + +/*! This comment will be included even in compressed mode. */ + +/// Computes an exponent. +///// Computes an exponent. + +=====================================output===================================== +// This comment won't be included in the CSS. +//This comment won't be included in the CSS. +// This comment won't be included in the CSS. + +/* But this comment will, except in compressed mode. */ +/* But this comment will, except in compressed mode. */ +/*But this comment will, except in compressed mode.*/ + +/*! This comment will be included even in compressed mode. */ + +/// Computes an exponent. +///// Computes an exponent. + +================================================================================ +`; + +exports[`directives.scss - {"cssParenSpacing":true} format 1`] = ` +====================================options===================================== +cssParenSpacing: true +parsers: ["scss"] +printWidth: 80 + | printWidth +=====================================input====================================== +@qux .foo +// .bar + +{} + +=====================================output===================================== +@qux .foo +// .bar +{ +} + +================================================================================ +`; + +exports[`function-in-url.scss - {"cssParenSpacing":true} format 1`] = ` +====================================options===================================== +cssParenSpacing: true +parsers: ["scss"] +printWidth: 80 + | printWidth +=====================================input====================================== +@function concat($strings...) { + $result: ''; + @each $string in $strings { + $sum: $result + $string; + } + @return $result; +} + +a { + backround: url(concat('http://', 'example.com', '/image.png')); +} + +=====================================output===================================== +@function concat( $strings... ) { + $result: ""; + @each $string in $strings { + $sum: $result + $string; + } + @return $result; +} + +a { + backround: url( concat( "http://", "example.com", "/image.png" ) ); +} + +================================================================================ +`; + +exports[`import_comma.scss - {"cssParenSpacing":true} format 1`] = ` +====================================options===================================== +cssParenSpacing: true +parsers: ["scss"] +printWidth: 80 + | printWidth +=====================================input====================================== +@import "rounded-corners", "text-shadow"; + +=====================================output===================================== +@import "rounded-corners", "text-shadow"; + +================================================================================ +`; + +exports[`scss.scss - {"cssParenSpacing":true} format 1`] = ` +====================================options===================================== +cssParenSpacing: true +parsers: ["scss"] +printWidth: 80 + | printWidth +=====================================input====================================== +@media #{$g-breakpoint-tiny} {} +.#{$fa-css-prefix}-glass:before { content: $fa-var-glass; } +a {height: calc(#{$foo} + 1);} +div { + background: { + size: auto 60%; + position: bottom 2px left; + } +} +a { margin: 0 { left: 10px; } } + +$default: #111111 !default; +$default: #111111 !default; +$default: #111111 +!default; +$default: "very-long-long-long-long-long-long-long-long-long-long-long-value" !default; +$default: "very-long-long-long-long-long-long-long-long-long-long-long-value" !default; +$default: "very-long-long-long-long-long-long-long-long-long-long-long-value" +!default; + +$global: #111111 !global; +$global: #111111 !global; +$global: #111111 +!global; +$global: "very-long-long-long-long-long-long-long-long-long-long-long-value" !global; +$global: "very-long-long-long-long-long-long-long-long-long-long-long-value" !global; +$global: "very-long-long-long-long-long-long-long-long-long-long-long-value" +!global; + +$map: (key: value, other-key: other-value); +$map: (key: value, other-key: other-value) !default; +$map: (key: value, other-key: other-value) !default; +$map: (key: value, other-key: other-value) +!default; +$map: +(key: value, other-key: other-value) +!default; +$map: ( key : value , other-key : other-value); +$map: ( key : value , other-key : other-value ); +$map: ( + key: value, + other-key: other-value +); +$map: ( +key: value, +other-key: other-value +); +$map: ( +key +: +value, +other-key +: +other-value +); +$map: ( +key +: +value +, +other-key +: +other-value +); +$map: (very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-key: very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-value, very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-key: very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-value); +$map: ( very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-key : very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-value , very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-key : very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-value ); +$map: ( very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-key : very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-value , very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-key: very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-value ); +$map: ( + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-key: very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-value, + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-key: very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-value +); +$map: ( +very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-key: very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-value, +very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-key: very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-value +); +$map: +( +very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-key +: +very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-value +, +very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-key +: +very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-value +); +$map: ( + key: (#d82d2d, #666), + other-key: (#52bf4a, #fff), + other-other-key: (#c23435, #fff) +); +$map: ( +key: (#d82d2d, #666), +other-key: (#52bf4a, #fff), +other-other-key: (#c23435, #fff) +); +$map: ( + key : ( #d82d2d , #666 ), + other-key : ( #52bf4a , #fff ), + other-other-key : ( #c23435 , #fff ) +); +$map: ( + key : ( #d82d2d , #666 ) , + other-key : ( #52bf4a , #fff ), + other-other-key : ( #c23435 , #fff ) +); +$map: ( +key +: +( +#d82d2d, +#666 +) +, +other-key +: +( +#52bf4a, +#fff +) +, +other-other-key +: +( +#c23435 +, +#fff +) +); +$map: map-merge($map, ($key: $value)); +$map: map-merge( $map , ( $key : $value ) ); +$map: map-merge( $map , ( $key : $value ) ); +$map: map-merge( + $map, + ($key: $value) +); +$map: map-merge( +$map, +($key: $value) +); +$map: +map-merge( +$map +, +( +$key +: +$value +) +); + +$longVariable: ( +(mobile $mobile) (tablet $tablet) (desktop $desktop) (wide $wide) +); + +$list-space: "item-1" "item-2" "item-3"; +$list-space:"item-1""item-2""item-3"; +$list-space: "item-1" "item-2" "item-3" ; +$list-space: "item-1" + "item-2" + "item-3"; +$list-space +: +"item-1" +"item-2" +"item-3" +; +$list-space + +: + +"item-1" + +"item-2" + +"item-3" + +; +$list-comma: "item-1", "item-2", "item-3"; +$list-comma:"item-1","item-2","item-3"; +$list-comma: "item-1" , "item-2" , "item-3" ; +$list-comma: "item-1", + "item-2", + "item-3"; +$list-comma +: +"item-1" +, +"item-2" +, +"item-3" +; +$list-comma + +: + +"item-1" + +, + +"item-2" + +, + +"item-3" + +; +$list: "item-1.1" "item-1.2" "item-1.3", "item-2.1" "item-2.2" "item-2.3", "item-3.1" "item-3.2" "item-3.3"; +$list:"item-1.1""item-1.2""item-1.3","item-2.1""item-2.2""item-2.3","item-3.1""item-3.2""item-3.3"; +$list: "item-1.1" "item-1.2" "item-1.3" , "item-2.1" "item-2.2" "item-2.3" , "item-3.1" "item-3.2" "item-3.3" ; +$list: "item-1.1" "item-1.2" "item-1.3", + "item-2.1" "item-2.2" "item-2.3", + "item-3.1" "item-3.2" "item-3.3"; +$list +: +"item-1.1" +"item-1.2" +"item-1.3" +, +"item-2.1" +"item-2.2" +"item-2.3" +, +"item-3.1" +"item-3.2" +"item-3.3" +; +$list + +: + +"item-1.1" + +"item-1.2" + +"item-1.3" + +, + +"item-2.1" + +"item-2.2" + +"item-2.3" + +, + +"item-3.1" + +"item-3.2" + +"item-3.3" + +; +$list: (("item-1.1", "item-1.2", "item-1.3"), ("item-2.1", "item-2.2", "item-2.3"), ("item-3.1", "item-3.2", "item-3.3")); +$list:(("item-1.1","item-1.2","item-1.3"),("item-2.1","item-2.2","item-2.3"),("item-3.1","item-3.2","item-3.3")); +$list: ( ( "item-1.1" , "item-1.2" , "item-1.3" ) , ( "item-2.1" , "item-2.2" , "item-2.3" ) , ( "item-3.1" , "item-3.2" , "item-3.3" ) ) ; +$list: ( + ("item-1.1", "item-1.2", "item-1.3"), + ("item-2.1", "item-2.2", "item-2.3"), + ("item-3.1", "item-3.2", "item-3.3") +); +$list +: +( +( +"item-1.1" +, +"item-1.2" +, +"item-1.3" +) +, +( +"item-2.1" +, +"item-2.2" +, +"item-2.3" +) +, +( +"item-3.1" +, +"item-3.2" +, +"item-3.3" +) +) +; +$list + +: + +( + +( + +"item-1.1" + +, + +"item-1.2" + +, + +"item-1.3" + +) + +, + +( + +"item-2.1" + +, + +"item-2.2" + +, + +"item-2.3" + +) + +, + +( + +"item-3.1" + +, + +"item-3.2" + +, + +"item-3.3" + +) + +) + +; + +$var: (0 0) (0 0) (0 0) (0 0) (0 0) (0 0) (0 0) (0 0) (0 0) (0 0) (0 0) (0 0) (0 0) (0 0); +$space-scale: (0, "0") (0.25, "0-25") (0.5, "0-5") (0.75, "0-75") (1, "1") (1.25, "1-25") (1.5, "1-5") (1.75, "1-75") (2, "2") (2.25, "2-25") (2.5, "2-5") (2.75, "2-75") (3, "3") (3.25, "3-25") (3.5, "3-5") (3.75, "3-75") (4, "4"); + +.card-column-simple { + @include breakpoint( getBp( md ) ) { + padding: $spacing_content-sm $spacing_content-md; + } + + @include breakpoint (getBp(md)) { + &:nth-child(2n + 3) { + clear: both; + } + } + + @include breakpoint (getBp(xl)) { + &:nth-child(2n + 3) { + clear: none; + } + &:nth-child(3n + 4) { + clear: both; + } + } +} + +@warn "Warn (#{$message})."; +@warn "Warn (#{$message})."; +@warn "Warn (#{$message})."; +@warn #{$message}; +@warn "Very long long long long long long long long long long long long long line (#{$message})."; +@warn + "Very long long long long long long long long long long long long long line (#{$message})."; +@error "Error (#{$message})."; +@error "Error (#{$message})."; +@error "Error (#{$message})."; +@error #{$message}; +@error "Very long long long long long long long long long long long long long line Error (#{$message})."; +@error + "Very long long long long long long long long long long long long long line Error (#{$message})."; + +$buttonConfig: "save" 50px, 'cancel' 50px, "help" 100PX; + +$locale: "en_us"; +html[lang=#{$locale}] { + font-size: 10px; +} +$alertClass: "error"; +p.message-#{$alertClass} { + color: red; +} +$mediumBreakpoint: 768px; +@media (max-width: #{$mediumBreakpoint}) { + a { + font-size: 18px; + } +} + +p { + @media (max-width: 768px) { + font-size: 150%; + + @media (orientation: landscape) { + line-height: 75%; + } + } +} + +.popularAnimal { + background: gray; +} +.GoodBoy { + color: green; +} +.dog { + @extend .popularAnimal; + @extend .GoodBoy; + color: white; +} + +%animal { + background: gray; +} +.cat { + @extend %animal; + color: white; +} +.dog { + @extend %animal; + color: black; +} + +%mfw-standing-out { + font-size: 150%; + font-style: italic; + padding: 25px; +} +%mfwSlightlyShadowed { + @include box-shadow(black 2px 2px 10px); // from Compass +} +%MFWRounded { + @include border-radius(25px); // from Compass +} +#join-button { + @extend %mfw-standing-out; + @extend %mfwSlightlyShadowed; + @extend %MFWRounded; + background: green; + color: white; +} + +a { + &:hover { + color: red; + } +} +p { + body.no-touch & { + display: none; + } +} +.foo.bar .baz.bang, .bip.qux { + $selector: &; +} +@mixin does-parent-exist { + @if & { + &:hover { + color: red; + } + } @else { + a { + color: red; + } + } +} + +p { + @if 1 + 1 == 2 { + border: 1px solid; + } + @if 5 < 3 { + border: 2px dotted; + } + @if null { + border: 3px double; + } +} + +$mosterType: monster; +p { + @if $mosterType == ocean { + color: blue; + } @else if $mosterType == matador { + color: red; + } @else if $mosterType == monster { + color: green; + } @else if $mosterType == nightKing { + color: green; + } @else if $mosterType == VeryWickedWolf { + color: green; + } @else { + color: black; + } +} + +@for $i from 1 through 3 { + .item-#{$i} { + width: 2em * $i; + } +} + +@each $animal in puma, sea-slug, cheerfulDog, BigSalamander, "string", 'another-string', "camelCaseString", "PascalCaseString" { + .#{$animal}-icon { + background-image: url('/images/#{$animal}.png'); + } +} + +$i: 6; +@while $i > 0 { + .item-#{$i} { + width: 2em * $i; + } + $i: $i - 2; +} + +@mixin cool-border($width: 10px, $coolStyle: 'solid', $AwesomeColor: "black") { + border: $width $coolStyle $AwesomeColor; +} + +p { + @include cool-border(1px, "solid", $fff); +} +p { + @include cool-border($width: 1px, $coolStyle: 'solid', $AwesomeColor: #fff); +} +p { + @include coolBorder(); +} + +@mixin coolBorder() { + border: 10px solid #fff; +} +p { + @include coolBorder(1px, "solid", $fff); +} + +@mixin CoolBorder() { + border: 10px solid #fff; +} +p { + @include CoolBorder(1px, "solid", $fff); +} + +@mixin box-shadow($shadows...) { + -moz-box-shadow: $shadows; + -webkit-box-shadow: $shadows; + box-shadow: $shadows; +} +.shadows { + @include box-shadow(0px 4px 5px #666, 2px 6px 10px #999); +} + +@mixin apply-to-ie6-only { + * html { + @content; + } +} +@include apply-to-ie6-only { + #logo { + background-image: url(/logo.gif); + } +} + +@mixin applyToIe6Only { + * html { + @content; + } +} +@include applyToIe6Only { + #logo { + background-image: url(/logo.gif); + } +} + +@mixin ApplyToIe6Only { + * html { + @content; + } +} +@include ApplyToIe6Only { + #logo { + background-image: url(/logo.gif); + } +} + +@mixin config-icon-colors($prefix, $colors...) { + @each $i in $colors { + .#{$prefix}#{nth($i, 1)} { + color: nth($i, 2); + } + } +} +@include config-icon-colors( + "icon-", + "save" green, + "cancel" gray, + "delete" red, + 'wait' blue +); + +@function my-calculation-function($some-number, $anotherNumber, $BigNumber){ + @return $some-number + $anotherNumber + $BigNumber; +} +@function myCalculationFunction($some-number, $anotherNumber, $BigNumber){ + @return $some-number + $anotherNumber + $BigNumber; +} +@function AnotherMyCalculationFunction($some-number, $anotherNumber, $BigNumber: 100px){ + @return $some-number + $anotherNumber + $BigNumber; +} +@function border($borders...) { + @return $borders; +} +.foo { + padding: my-calculation-function(10px, 5px, 100px); + margin: myCalculationFunction($some-number: 10px, $anotherNumber: 5px, $BigNumber: 100px); + width: AnotherMyCalculationFunction(10px, 5px); + border: border(25px, 35px); +} + +$sm-only: '(min-width: 768px) and (max-width: 991px)'; +$lg-and-up: '(min-width: 1200px)'; + +@media screen and #{$sm-only, $lg-and-up} { + color: #000; +} + +.class-#{$var} { + #{$var}: #7b3d66; + #{$attr}-color: blue; + #{$prop}-#{$side}: $value; + background-#{$var}: #7b3d66; + animation-name: #{var}; + line-height: #{strip-unit($line-height)}em; + height: 1#{$var}; + width: calc(100% - #{$sidebar-width}); + max-width: calc(#{$m*100}vw #{$sign} #{$b}); + font: #{$font-size}/#{$line-height}; + content: "I have #{8 + 2} books on SASS!"; + border: #{$var} #{$var} #{$var}; + filter: #{$var}#{$var}#{$var}; + prop: #{ $var + $var } #{ $var + $var } #{ $var + $var }; + prop2: + #{ + $var + + + $var + } + + #{ + $var + + + $var + } + + #{ + $var + + + $var + } + ; + prop3: + + #{ + + $var + + + + + $var + + } + + #{ + + $var + + + + + $var + + } + + #{ + + $var + + + + + $var + + } + ; + prop4: -#{$loader-icon-duration}; + prop5: +#{$loader-icon-duration}; + prop6: calc(-#{$loader-icon-duration} + 10); + prop7: calc(10 + -#{$loader-icon-duration}); +} + +/* Framework version for the generated CSS is #{$version}. */ + +.selector { + foo: bar; + #{$active} { + baz: qux; + } +} + +.el:nth-of-type(#{$i}) {} + +@media #{$value} {} + +$foundation-dir: 'foundation'; +@import url('#{$foundation-dir}/components/grid'); +@import url(#{$foundation-dir}/components/grid); +@import url($foundation-dir/components/grid); +@import url($foundation-dir+"/components/grid"); + +@function get-font-family($family) { + @return $family; +} +@import url("//fonts.googleapis.com/css?family=#{ get-font-family('Roboto') }:100,300,500,700,900&display=swap"); +@import url(//fonts.googleapis.com/css?family=#{ get-font-family('Roboto') }:100,300,500,700,900&display=swap); + + +@keyframes loader { + 0% { + transform: translate3d(0, 0, 0); + } + + #{50% - $loader-icon-duration} { + transform: translate3d(0, $bounce-height, 0); + } + + 50% { + transform: translate3d(0, $bounce-height, 0) scale($loader-bounce-horizontal-expansion, $loader-bounce-vertical-compression); + } +} + +$icons: wifi "\\600", wifi-hotspot "\\601", weather "\\602"; + +@each $icon in $icons { + .icon-#{nth($icon, 1)}, %icon-#{nth($icon, 1)} { + content: "#{nth($icon, 2)}"; + } +} + +.foo { + prop: -($grid-gutter-width / 2); + prop1: -( $grid-gutter-width / 2 ); + prop2: -$grid-gutter-width / 2; + prop3: +($grid-gutter-width / 2); + prop4: 10px/8px; /* Plain CSS, no division */ + prop5: $width / 2; /* Uses a variable, does division */ + prop6: round(1.5) / 2; /* Uses a function, does division */ + prop7: (500px / 2); /* Uses parentheses, does division */ + prop8: 5px + 8px / 2px; //* Uses +, does division */ + prop9: (italic bold 10px/8px); /* In a list, parentheses don't count */ + prop10: #010203 + #040506; + prop11: #010203 * 2; + prop12: rgba(255, 0, 0, 0.75) + rgba(0, 255, 0, 0.75); + prop13: progid:DXImageTransform.Microsoft.gradient(enabled='false', startColorstr='#{ie-hex-str($green)}', endColorstr='#{ie-hex-str($translucent-red)}'); + prop14: e + -resize; + prop15: sans- + "serif"; + prop16: 1em + (2em * 3); + prop17: rotate(-2deg); + prop18: rotate( -2deg ) ; + _:_; + prop19: 10 - ($grid-gutter-width / 2); + prop20: 10 + -($grid-gutter-width / 2); + prop21: 10 + - ( $grid-gutter-width / 2 ) ; + prop22: - ( $grid-gutter-width / 2 ) ; + prop23: - ( $grid-gutter-width / 2 ) ; + prop24: -$grid-gutter-width; + prop25: + ( $grid-gutter-width / 2 ) ; + prop26: + ( $grid-gutter-width / 2 ) ; + prop27: +$grid-gutter-width; + prop28: --($grid-gutter-width / 2); + prop28: ++($grid-gutter-width / 2); + prop29: rotate( - 2deg ) ; +} + +$last:nth($juggler,length($juggler)); +$x:if($last%2==0,1/2,3/2); +$new:pow($last,$x); +$sequence:1,1 1,2 1,1 2 1 1, 1 1 1 2 2 1; +$new-entry:(); +$new-entry : ( ) ; +$new-entry : ( ) ; +$new-entry +: +( +) +; + +body:before { + content: quote(to-string(fibonacci(100), ' \\A ')); + white-space: pre-wrap; +} + +width: ((100% - (($numPerRow - 1) * $margin)) / $numPerRow); +width +: +( +( +100% +- +( +( +$numPerRow +- +1 +) +* +$margin +) +) +/ +$numPerRow +) +; + +a:nth-child(#{$numPerRow}n) { + margin-right: 0; + margin-bottom: 0; +} + +@function em($pixels, $context: $browser-context) { + @return #{ $pixels / $context }em +} + +.navigation { + @extend %updated-#{$flag}; + @extend .selected-#{$flag}; + @extend %#{$item}; +} + +.icon-#{$icon-name} { + background-image: '/images/#{$icon-name}.svg'; +} + +$extmods:(eot:"?",svg:"#" + str-replace($name," ","_")); + +@mixin keyframes {@-moz-keyframes{@content;}@-webkit-keyframes{@content;}} + +@function gcd($a,$b){ + // From: http://rosettacode.org/wiki/Greatest_common_divisor#JavaScript + @if ($b != 0) { + @return gcd($b,$a % $b); + }@else{ + @return abs($a); + } +} + +$colors: ( +primary: ( +base: #00abc9, +light: #daf1f6, +dark: #12799a +), +secondary: ( +base: #424d55, +light: #ccc, +lightest: #efefef, +dark: #404247 +), +success: ( +base: #bbd33e, +light: #eaf0c6 +) +); + +@function color($color, $tone: "base") { +@return map-get(map-get($colors, $color), $tone); +} + +@media only screen and (max-width: 767px) { + @include widths(2 3 4, \\@small); +} + +$widths-breakpoint-separator: \\@small; + +a { + transition-timing-function: func1( + func2( + func3( + "veryVeryVeryVeryVeryLongValue", + "veryVeryVeryVeryVeryLongValue", + "veryVeryVeryVeryVeryLongValue", + "veryVeryVeryVeryVeryLongValue", + ), + "veryVeryVeryVeryVeryLongValue", + "veryVeryVeryVeryVeryLongValue", + "veryVeryVeryVeryVeryLongValue", + ), + "veryVeryVeryVeryVeryLongValue", + "veryVeryVeryVeryVeryLongValue", + func3( + "veryVeryVeryVeryVeryLongValue", + "veryVeryVeryVeryVeryLongValue", + "veryVeryVeryVeryVeryLongValue", + "veryVeryVeryVeryVeryLongValue" + ) + ); +} + +$empty-map: (); +$empty-nested-map: ( +nested-key: (empty-key: (color: red)), +empty-key: (), +empty-key: (), +empty-key: () +); + +$o-grid-default-config: ( +columns: 12, +gutter: 10px, +min-width: 240px, +max-width: 1330px, +layouts: ( +S: 370px, +M: 610px, +L: 850px, +XL: 1090px +), +fluid: true, +debug: false, +fixed-layout: M, +enhanced-experience: true +); + +$a: (); +$b: unquote(''); +$c: null; +$d: (null); + +$threads-properties: map-merge($threads-properties, ($border-label: ())); +$o-grid-default-config: (layouts: (S: 370px)); + +$map: ( +key: (value), +other-key: (key: other-other-value) +); + +a { + content: "#{".5"}"; + content: my-fn("_"); + content: "#{my-fn("_")}"; + content: my-fn("-"); + content: "#{my-fn("-")}"; + content: my-fn("-a"); + content: "#{my-fn("-a")}"; + content: my-fn("a-"); + content: "#{my-fn("a-")}"; + content: my-fn("foo"); + content: "#{my-fn("foo")}"; + content: 1 "#{my-fn("foo")}" 2; + content: foo "#{my-fn("foo")}" bar; + content: "foo #{$description} bar"; + + content: "#{my-fn("foo","bar")}"; + content: "#{my-fn( "foo" , "bar" )}"; + content: "#{my-fn( "foo" , "bar" )}"; + + content: '#{my-fn("foo")}'; + content: '#{my-fn('foo')}'; + content: "#{my-fn('foo')}"; + content: "#{my-fn("foo")}"; +} + +@mixin theme($css-property, $css-value, $theme-classes: t) { + @each $selector in & { + @each $class in $theme-classes { + @each $theme, $theme-properties in c(themes) { + $value: $css-value; + + @each $theme-name, $theme-value in $theme-properties { + $rgba-value: "rgba(#{red($theme-value)}, #{green($theme-value)}, #{blue($theme-value)}"; + $value: str-replace($value, "rgba(\${#{$theme-name}}", $rgba-value); + $value: str-replace($value, "\${#{$theme-name}}", $theme-value); + } + + @at-root .#{$class}-#{join($theme, $selector)} { + #{$css-property}: unquote($value); + } + } + } + } +} + +.foo, +// Comment +.bar { + // Comment + color: red; // Comment +} + +$my-list: + 'foo', // Comment + 'bar'; // Comment + +$my-map: ( + 'foo': 1, // Comment + 'bar': 2, // Comment + 'buz': calc(1 + 2), // Buz + 'baz': 4, // Baz +); + +[href]:hover &, // Comment +[href]:focus &, // Comment +[href]:active & { + .tooltip { + opacity: 1; + } +} + +@import + // Comment + 'mixins', + 'variables', + // Comment + 'reset', + 'scaffolding', + 'type', + // Comment + 'bar', + 'tabs'; + +@mixin placeholder { + &::placeholder {@content} +} + +.container { + @include placeholder { + color: $color-silver; + } +} + +.something { + grid-template-columns: 1 2fr (3 + 4); +} + +// Ignore escape "\\" in SCSS mixins +@mixin margin-bottom-1\\/3 { + margin-bottom: 0.8rem; +} + +label { + @include margin-bottom-1\\/3; +} + +@function someVeryLongFunctionNameForJustAPow($base, $exponent) { + $result: 1; + @for $_ from 1 through $exponent { + $result: $result * $base; + } + @return $result; +} + +@function pow($base, $exponent){ + @return someVeryLongFunctionNameForJustAPow($base,$exponent); +} + +.foo{ + width: someVeryLongFunctionNameForJustAPow(2, someVeryLongFunctionNameForJustAPow(2, someVeryLongFunctionNameForJustAPow(2, + // This next pow is really powerful + someVeryLongFunctionNameForJustAPow(2, someVeryLongFunctionNameForJustAPow(2, someVeryLongFunctionNameForJustAPow(2, someVeryLongFunctionNameForJustAPow(2, someVeryLongFunctionNameForJustAPow(2, someVeryLongFunctionNameForJustAPow(2, someVeryLongFunctionNameForJustAPow(2, someVeryLongFunctionNameForJustAPow(2, someVeryLongFunctionNameForJustAPow(2, 2)))))))))))) +} + +.bar{ + width: pow(2, pow(2, pow(2, + // This next pow is really powerful + pow(2, pow(2, pow(2, pow(2, pow(2, pow(2, pow(2, pow(2, pow(2, 2)))))))))))) +} + +=====================================output===================================== +@media #{$g-breakpoint-tiny} { +} +.#{$fa-css-prefix}-glass:before { + content: $fa-var-glass; +} +a { + height: calc( #{$foo} + 1 ); +} +div { + background: { + size: auto 60%; + position: bottom 2px left; + } +} +a { + margin: 0 { + left: 10px; + } +} + +$default: #111111 !default; +$default: #111111 !default; +$default: #111111 !default; +$default: "very-long-long-long-long-long-long-long-long-long-long-long-value" !default; +$default: "very-long-long-long-long-long-long-long-long-long-long-long-value" !default; +$default: "very-long-long-long-long-long-long-long-long-long-long-long-value" !default; + +$global: #111111 !global; +$global: #111111 !global; +$global: #111111 !global; +$global: "very-long-long-long-long-long-long-long-long-long-long-long-value" !global; +$global: "very-long-long-long-long-long-long-long-long-long-long-long-value" !global; +$global: "very-long-long-long-long-long-long-long-long-long-long-long-value" !global; + +$map: ( + key: value, + other-key: other-value, +); +$map: ( + key: value, + other-key: other-value, +) !default; +$map: ( + key: value, + other-key: other-value, +) !default; +$map: ( + key: value, + other-key: other-value, +) !default; +$map: ( + key: value, + other-key: other-value, +) !default; +$map: ( + key: value, + other-key: other-value, +); +$map: ( + key: value, + other-key: other-value, +); +$map: ( + key: value, + other-key: other-value, +); +$map: ( + key: value, + other-key: other-value, +); +$map: ( + key: value, + other-key: other-value, +); +$map: ( + key: value, + other-key: other-value, +); +$map: ( + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-key: + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-value, + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-key: + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-value, +); +$map: ( + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-key: + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-value, + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-key: + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-value, +); +$map: ( + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-key: + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-value, + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-key: + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-value, +); +$map: ( + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-key: + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-value, + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-key: + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-value, +); +$map: ( + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-key: + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-value, + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-key: + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-value, +); +$map: ( + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-key: + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-value, + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-key: + very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-verylong-other-value, +); +$map: ( + key: ( + #d82d2d, + #666, + ), + other-key: ( + #52bf4a, + #fff, + ), + other-other-key: ( + #c23435, + #fff, + ), +); +$map: ( + key: ( + #d82d2d, + #666, + ), + other-key: ( + #52bf4a, + #fff, + ), + other-other-key: ( + #c23435, + #fff, + ), +); +$map: ( + key: ( + #d82d2d, + #666, + ), + other-key: ( + #52bf4a, + #fff, + ), + other-other-key: ( + #c23435, + #fff, + ), +); +$map: ( + key: ( + #d82d2d, + #666, + ), + other-key: ( + #52bf4a, + #fff, + ), + other-other-key: ( + #c23435, + #fff, + ), +); +$map: ( + key: ( + #d82d2d, + #666, + ), + other-key: ( + #52bf4a, + #fff, + ), + other-other-key: ( + #c23435, + #fff, + ), +); +$map: map-merge( + $map, + ( + $key: $value, + ) +); +$map: map-merge( + $map, + ( + $key: $value, + ) +); +$map: map-merge( + $map, + ( + $key: $value, + ) +); +$map: map-merge( + $map, + ( + $key: $value, + ) +); +$map: map-merge( + $map, + ( + $key: $value, + ) +); +$map: map-merge( + $map, + ( + $key: $value, + ) +); + +$longVariable: ( + ( mobile $mobile ) ( tablet $tablet ) ( desktop $desktop ) ( wide $wide ) +); + +$list-space: "item-1" "item-2" "item-3"; +$list-space: "item-1" "item-2" "item-3"; +$list-space: "item-1" "item-2" "item-3"; +$list-space: "item-1" "item-2" "item-3"; +$list-space: "item-1" "item-2" "item-3"; +$list-space: "item-1" "item-2" "item-3"; +$list-comma: "item-1", "item-2", "item-3"; +$list-comma: "item-1", "item-2", "item-3"; +$list-comma: "item-1", "item-2", "item-3"; +$list-comma: "item-1", "item-2", "item-3"; +$list-comma: "item-1", "item-2", "item-3"; +$list-comma: "item-1", "item-2", "item-3"; +$list: "item-1.1" "item-1.2" "item-1.3", "item-2.1" "item-2.2" "item-2.3", + "item-3.1" "item-3.2" "item-3.3"; +$list: "item-1.1" "item-1.2" "item-1.3", "item-2.1" "item-2.2" "item-2.3", + "item-3.1" "item-3.2" "item-3.3"; +$list: "item-1.1" "item-1.2" "item-1.3", "item-2.1" "item-2.2" "item-2.3", + "item-3.1" "item-3.2" "item-3.3"; +$list: "item-1.1" "item-1.2" "item-1.3", "item-2.1" "item-2.2" "item-2.3", + "item-3.1" "item-3.2" "item-3.3"; +$list: "item-1.1" "item-1.2" "item-1.3", "item-2.1" "item-2.2" "item-2.3", + "item-3.1" "item-3.2" "item-3.3"; +$list: "item-1.1" "item-1.2" "item-1.3", "item-2.1" "item-2.2" "item-2.3", + "item-3.1" "item-3.2" "item-3.3"; +$list: ( + ( "item-1.1", "item-1.2", "item-1.3" ), + ( "item-2.1", "item-2.2", "item-2.3" ), + ( "item-3.1", "item-3.2", "item-3.3" ) +); +$list: ( + ( "item-1.1", "item-1.2", "item-1.3" ), + ( "item-2.1", "item-2.2", "item-2.3" ), + ( "item-3.1", "item-3.2", "item-3.3" ) +); +$list: ( + ( "item-1.1", "item-1.2", "item-1.3" ), + ( "item-2.1", "item-2.2", "item-2.3" ), + ( "item-3.1", "item-3.2", "item-3.3" ) +); +$list: ( + ( "item-1.1", "item-1.2", "item-1.3" ), + ( "item-2.1", "item-2.2", "item-2.3" ), + ( "item-3.1", "item-3.2", "item-3.3" ) +); +$list: ( + ( "item-1.1", "item-1.2", "item-1.3" ), + ( "item-2.1", "item-2.2", "item-2.3" ), + ( "item-3.1", "item-3.2", "item-3.3" ) +); +$list: ( + ( "item-1.1", "item-1.2", "item-1.3" ), + ( "item-2.1", "item-2.2", "item-2.3" ), + ( "item-3.1", "item-3.2", "item-3.3" ) +); + +$var: ( 0 0 ) ( 0 0 ) ( 0 0 ) ( 0 0 ) ( 0 0 ) ( 0 0 ) ( 0 0 ) ( 0 0 ) ( 0 0 ) + ( 0 0 ) ( 0 0 ) ( 0 0 ) ( 0 0 ) ( 0 0 ); +$space-scale: ( 0, "0" ) ( 0.25, "0-25" ) ( 0.5, "0-5" ) ( 0.75, "0-75" ) + ( 1, "1" ) ( 1.25, "1-25" ) ( 1.5, "1-5" ) ( 1.75, "1-75" ) ( 2, "2" ) + ( 2.25, "2-25" ) ( 2.5, "2-5" ) ( 2.75, "2-75" ) ( 3, "3" ) ( 3.25, "3-25" ) + ( 3.5, "3-5" ) ( 3.75, "3-75" ) ( 4, "4" ); + +.card-column-simple { + @include breakpoint( getBp( md ) ) { + padding: $spacing_content-sm $spacing_content-md; + } + + @include breakpoint( getBp( md ) ) { + &:nth-child( 2n + 3 ) { + clear: both; + } + } + + @include breakpoint( getBp( xl ) ) { + &:nth-child( 2n + 3 ) { + clear: none; + } + &:nth-child( 3n + 4 ) { + clear: both; + } + } +} + +@warn "Warn (#{$message})."; +@warn "Warn (#{$message})."; +@warn "Warn (#{$message})."; +@warn #{$message}; +@warn "Very long long long long long long long long long long long long long line (#{$message})."; +@warn "Very long long long long long long long long long long long long long line (#{$message})."; +@error "Error (#{$message})."; +@error "Error (#{$message})."; +@error "Error (#{$message})."; +@error #{$message}; +@error "Very long long long long long long long long long long long long long line Error (#{$message})."; +@error "Very long long long long long long long long long long long long long line Error (#{$message})."; + +$buttonConfig: "save" 50px, "cancel" 50px, "help" 100px; + +$locale: "en_us"; +html[lang="#{$locale}"] { + font-size: 10px; +} +$alertClass: "error"; +p.message-#{$alertClass} { + color: red; +} +$mediumBreakpoint: 768px; +@media (max-width: #{$mediumBreakpoint}) { + a { + font-size: 18px; + } +} + +p { + @media ( max-width: 768px ) { + font-size: 150%; + + @media ( orientation: landscape ) { + line-height: 75%; + } + } +} + +.popularAnimal { + background: gray; +} +.GoodBoy { + color: green; +} +.dog { + @extend .popularAnimal; + @extend .GoodBoy; + color: white; +} + +%animal { + background: gray; +} +.cat { + @extend %animal; + color: white; +} +.dog { + @extend %animal; + color: black; +} + +%mfw-standing-out { + font-size: 150%; + font-style: italic; + padding: 25px; +} +%mfwSlightlyShadowed { + @include box-shadow( black 2px 2px 10px ); // from Compass +} +%MFWRounded { + @include border-radius( 25px ); // from Compass +} +#join-button { + @extend %mfw-standing-out; + @extend %mfwSlightlyShadowed; + @extend %MFWRounded; + background: green; + color: white; +} + +a { + &:hover { + color: red; + } +} +p { + body.no-touch & { + display: none; + } +} +.foo.bar .baz.bang, +.bip.qux { + $selector: &; +} +@mixin does-parent-exist { + @if & { + &:hover { + color: red; + } + } @else { + a { + color: red; + } + } +} + +p { + @if 1 + 1 == 2 { + border: 1px solid; + } + @if 5 < 3 { + border: 2px dotted; + } + @if null { + border: 3px double; + } +} + +$mosterType: monster; +p { + @if $mosterType == ocean { + color: blue; + } @else if $mosterType == matador { + color: red; + } @else if $mosterType == monster { + color: green; + } @else if $mosterType == nightKing { + color: green; + } @else if $mosterType == VeryWickedWolf { + color: green; + } @else { + color: black; + } +} + +@for $i from 1 through 3 { + .item-#{$i} { + width: 2em * $i; + } +} + +@each $animal in puma, sea-slug, cheerfulDog, BigSalamander, "string", + "another-string", "camelCaseString", "PascalCaseString" +{ + .#{$animal}-icon { + background-image: url( "/images/#{$animal}.png" ); + } +} + +$i: 6; +@while $i > 0 { + .item-#{$i} { + width: 2em * $i; + } + $i: $i - 2; +} + +@mixin cool-border( + $width: 10px, + $coolStyle: "solid", + $AwesomeColor: "black" +) { + border: $width $coolStyle $AwesomeColor; +} + +p { + @include cool-border( 1px, "solid", $fff ); +} +p { + @include cool-border( $width: 1px, $coolStyle: "solid", $AwesomeColor: #fff ); +} +p { + @include coolBorder(); +} + +@mixin coolBorder() { + border: 10px solid #fff; +} +p { + @include coolBorder( 1px, "solid", $fff ); +} + +@mixin CoolBorder() { + border: 10px solid #fff; +} +p { + @include CoolBorder( 1px, "solid", $fff ); +} + +@mixin box-shadow( $shadows... ) { + -moz-box-shadow: $shadows; + -webkit-box-shadow: $shadows; + box-shadow: $shadows; +} +.shadows { + @include box-shadow( 0px 4px 5px #666, 2px 6px 10px #999 ); +} + +@mixin apply-to-ie6-only { + * html { + @content; + } +} +@include apply-to-ie6-only { + #logo { + background-image: url( /logo.gif ); + } +} + +@mixin applyToIe6Only { + * html { + @content; + } +} +@include applyToIe6Only { + #logo { + background-image: url( /logo.gif ); + } +} + +@mixin ApplyToIe6Only { + * html { + @content; + } +} +@include ApplyToIe6Only { + #logo { + background-image: url( /logo.gif ); + } +} + +@mixin config-icon-colors( $prefix, $colors... ) { + @each $i in $colors { + .#{$prefix}#{nth($i, 1)} { + color: nth( $i, 2 ); + } + } +} +@include config-icon-colors( + "icon-", + "save" green, + "cancel" gray, + "delete" red, + "wait" blue +); + +@function my-calculation-function( $some-number, $anotherNumber, $BigNumber ) { + @return $some-number + $anotherNumber + $BigNumber; +} +@function myCalculationFunction( $some-number, $anotherNumber, $BigNumber ) { + @return $some-number + $anotherNumber + $BigNumber; +} +@function AnotherMyCalculationFunction( + $some-number, + $anotherNumber, + $BigNumber: 100px +) { + @return $some-number + $anotherNumber + $BigNumber; +} +@function border( $borders... ) { + @return $borders; +} +.foo { + padding: my-calculation-function( 10px, 5px, 100px ); + margin: myCalculationFunction( + $some-number: 10px, + $anotherNumber: 5px, + $BigNumber: 100px + ); + width: AnotherMyCalculationFunction( 10px, 5px ); + border: border( 25px, 35px ); +} + +$sm-only: "(min-width: 768px) and (max-width: 991px)"; +$lg-and-up: "(min-width: 1200px)"; + +@media screen and #{$sm-only, $lg-and-up} { + color: #000; +} + +.class-#{$var} { + #{$var}: #7b3d66; + #{$attr}-color: blue; + #{$prop}-#{$side}: $value; + background-#{$var}: #7b3d66; + animation-name: #{var}; + line-height: #{strip-unit( $line-height )}em; + height: 1#{$var}; + width: calc( 100% - #{$sidebar-width} ); + max-width: calc( #{$m * 100}vw #{$sign} #{$b} ); + font: #{$font-size}/#{$line-height}; + content: "I have #{8 + 2} books on SASS!"; + border: #{$var} #{$var} #{$var}; + filter: #{$var}#{$var}#{$var}; + prop: #{$var + $var} #{$var + $var} #{$var + $var}; + prop2: #{$var + $var} #{$var + $var} #{$var + $var}; + prop3: #{$var + $var} #{$var + $var} #{$var + $var}; + prop4: -#{$loader-icon-duration}; + prop5: +#{$loader-icon-duration}; + prop6: calc( -#{$loader-icon-duration} + 10 ); + prop7: calc( 10 + -#{$loader-icon-duration} ); +} + +/* Framework version for the generated CSS is #{$version}. */ + +.selector { + foo: bar; + #{$active} { + baz: qux; + } +} + +.el:nth-of-type( #{$i} ) { +} + +@media #{$value} { +} + +$foundation-dir: "foundation"; +@import url( "#{$foundation-dir}/components/grid" ); +@import url( #{$foundation-dir}/components/grid ); +@import url( $foundation-dir/components/grid ); +@import url( $foundation-dir + "/components/grid" ); + +@function get-font-family( $family ) { + @return $family; +} +@import url( "//fonts.googleapis.com/css?family=#{ get-font-family('Roboto') }:100,300,500,700,900&display=swap" ); +@import url( //fonts.googleapis.com/css?family=#{ get-font-family('Roboto') }:100,300,500,700,900&display=swap ); + +@keyframes loader { + 0% { + transform: translate3d( 0, 0, 0 ); + } + + #{50% - $loader-icon-duration} { + transform: translate3d( 0, $bounce-height, 0 ); + } + + 50% { + transform: translate3d( 0, $bounce-height, 0 ) + scale( + $loader-bounce-horizontal-expansion, + $loader-bounce-vertical-compression + ); + } +} + +$icons: wifi "\\600", wifi-hotspot "\\601", weather "\\602"; + +@each $icon in $icons { + .icon-#{nth($icon, 1)}, + %icon-#{nth($icon, 1)} { + content: "#{nth($icon, 2)}"; + } +} + +.foo { + prop: -( $grid-gutter-width / 2 ); + prop1: -( $grid-gutter-width / 2 ); + prop2: -$grid-gutter-width / 2; + prop3: +( $grid-gutter-width / 2 ); + prop4: 10px/8px; /* Plain CSS, no division */ + prop5: $width / 2; /* Uses a variable, does division */ + prop6: round( 1.5 ) / 2; /* Uses a function, does division */ + prop7: ( 500px / 2 ); /* Uses parentheses, does division */ + prop8: 5px + 8px / 2px; //* Uses +, does division */ + prop9: ( italic bold 10px/8px ); /* In a list, parentheses don't count */ + prop10: #010203 + #040506; + prop11: #010203 * 2; + prop12: rgba( 255, 0, 0, 0.75 ) + rgba( 0, 255, 0, 0.75 ); + prop13: progid:DXImageTransform.Microsoft.gradient(enabled='false', startColorstr='#{ie-hex-str($green)}', endColorstr='#{ie-hex-str($translucent-red)}'); + prop14: e + -resize; + prop15: sans- + "serif"; + prop16: 1em + ( 2em * 3 ); + prop17: rotate( -2deg ); + prop18: rotate( -2deg ); + _: _; + prop19: 10 - ( $grid-gutter-width / 2 ); + prop20: 10 + -( $grid-gutter-width / 2 ); + prop21: 10 + -( $grid-gutter-width / 2 ); + prop22: -( $grid-gutter-width / 2 ); + prop23: -( $grid-gutter-width / 2 ); + prop24: -$grid-gutter-width; + prop25: +( $grid-gutter-width / 2 ); + prop26: +( $grid-gutter-width / 2 ); + prop27: +$grid-gutter-width; + prop28: --( $grid-gutter-width / 2 ); + prop28: ++( $grid-gutter-width / 2 ); + prop29: rotate( -2deg ); +} + +$last: nth( $juggler, length( $juggler ) ); +$x: if( $last%2==0, 1/2, 3/2 ); +$new: pow( $last, $x ); +$sequence: 1, 1 1, 2 1, 1 2 1 1, 1 1 1 2 2 1; +$new-entry: (); +$new-entry: (); +$new-entry: (); +$new-entry: (); + +body:before { + content: quote( to-string( fibonacci( 100 ), " \\A " ) ); + white-space: pre-wrap; +} + +width: ( ( 100% - ( ( $numPerRow - 1 ) * $margin ) ) / $numPerRow ); +width: ( ( 100% - ( ( $numPerRow - 1 ) * $margin ) ) / $numPerRow ); + +a:nth-child( #{$numPerRow}n ) { + margin-right: 0; + margin-bottom: 0; +} + +@function em( $pixels, $context: $browser-context ) { + @return #{$pixels / $context}em; +} + +.navigation { + @extend %updated-#{$flag}; + @extend .selected-#{$flag}; + @extend %#{$item}; +} + +.icon-#{$icon-name} { + background-image: "/images/#{$icon-name}.svg"; +} + +$extmods: ( + eot: "?", + svg: "#" + str-replace( $name, " ", "_" ), +); + +@mixin keyframes { + @-moz-keyframes { + @content; + } + @-webkit-keyframes { + @content; + } +} + +@function gcd( $a, $b ) { + // From: http://rosettacode.org/wiki/Greatest_common_divisor#JavaScript + @if ( $b != 0 ) { + @return gcd( $b, $a % $b ); + } @else { + @return abs( $a ); + } +} + +$colors: ( + primary: ( + base: #00abc9, + light: #daf1f6, + dark: #12799a, + ), + secondary: ( + base: #424d55, + light: #ccc, + lightest: #efefef, + dark: #404247, + ), + success: ( + base: #bbd33e, + light: #eaf0c6, + ), +); + +@function color( $color, $tone: "base" ) { + @return map-get( map-get( $colors, $color ), $tone ); +} + +@media only screen and ( max-width: 767px ) { + @include widths( 2 3 4, \\@small ); +} + +$widths-breakpoint-separator: \\@small; + +a { + transition-timing-function: func1( + func2( + func3( + "veryVeryVeryVeryVeryLongValue", + "veryVeryVeryVeryVeryLongValue", + "veryVeryVeryVeryVeryLongValue", + "veryVeryVeryVeryVeryLongValue" + ), + "veryVeryVeryVeryVeryLongValue", + "veryVeryVeryVeryVeryLongValue", + "veryVeryVeryVeryVeryLongValue" + ), + "veryVeryVeryVeryVeryLongValue", + "veryVeryVeryVeryVeryLongValue", + func3( + "veryVeryVeryVeryVeryLongValue", + "veryVeryVeryVeryVeryLongValue", + "veryVeryVeryVeryVeryLongValue", + "veryVeryVeryVeryVeryLongValue" + ) + ); +} + +$empty-map: (); +$empty-nested-map: ( + nested-key: ( + empty-key: ( + color: red, + ), + ), + empty-key: (), + empty-key: (), + empty-key: (), +); + +$o-grid-default-config: ( + columns: 12, + gutter: 10px, + min-width: 240px, + max-width: 1330px, + layouts: ( + S: 370px, + M: 610px, + L: 850px, + XL: 1090px, + ), + fluid: true, + debug: false, + fixed-layout: M, + enhanced-experience: true, +); + +$a: (); +$b: unquote( "" ); +$c: null; +$d: ( null ); + +$threads-properties: map-merge( + $threads-properties, + ( + $border-label: (), + ) +); +$o-grid-default-config: ( + layouts: ( + S: 370px, + ), +); + +$map: ( + key: ( + value, + ), + other-key: ( + key: other-other-value, + ), +); + +a { + content: "#{"0.5"}"; + content: my-fn( "_" ); + content: "#{my-fn("_")}"; + content: my-fn( "-" ); + content: "#{my-fn("-")}"; + content: my-fn( "-a" ); + content: "#{my-fn("-a")}"; + content: my-fn( "a-" ); + content: "#{my-fn("a-")}"; + content: my-fn( "foo" ); + content: "#{my-fn("foo")}"; + content: 1 "#{my-fn("foo")}" 2; + content: foo "#{my-fn("foo")}" bar; + content: "foo #{$description} bar"; + + content: "#{my-fn("foo","bar")}"; + content: "#{my-fn( "foo" , "bar" )}"; + content: "#{my-fn( "foo" , "bar" )}"; + + content: '#{my-fn("foo")}'; + content: "#{my-fn("foo")}"; + content: "#{my-fn('foo')}"; + content: "#{my-fn("foo")}"; +} + +@mixin theme( $css-property, $css-value, $theme-classes: t ) { + @each $selector in & { + @each $class in $theme-classes { + @each $theme, $theme-properties in c( themes ) { + $value: $css-value; + + @each $theme-name, $theme-value in $theme-properties { + $rgba-value: "rgba(#{red($theme-value)}, #{green($theme-value)}, #{blue($theme-value)}"; + $value: str-replace( $value, "rgba(\${#{$theme-name}}", $rgba-value ); + $value: str-replace( $value, "\${#{$theme-name}}", $theme-value ); + } + + @at-root .#{$class}-#{join($theme, $selector)} { + #{$css-property}: unquote( $value ); + } + } + } + } +} + +.foo, +// Comment +.bar { + // Comment + color: red; // Comment +} + +$my-list: "foo", + // Comment + "bar"; // Comment + +$my-map: ( + "foo": 1, + // Comment + "bar": 2, + // Comment + "buz": calc( 1 + 2 ), + // Buz + "baz": 4, + // Baz +); + +[href]:hover &, // Comment +[href]:focus &, // Comment +[href]:active & { + .tooltip { + opacity: 1; + } +} + +@import // Comment + "mixins", + "variables", + // Comment + "reset", + "scaffolding", "type", + // Comment + "bar", + "tabs"; + +@mixin placeholder { + &::placeholder { + @content; + } +} + +.container { + @include placeholder { + color: $color-silver; + } +} + +.something { + grid-template-columns: 1 2fr ( 3 + 4 ); +} + +// Ignore escape "\\" in SCSS mixins +@mixin margin-bottom-1\\/3 { + margin-bottom: 0.8rem; +} + +label { + @include margin-bottom-1\\/3; +} + +@function someVeryLongFunctionNameForJustAPow( $base, $exponent ) { + $result: 1; + @for $_ from 1 through $exponent { + $result: $result * $base; + } + @return $result; +} + +@function pow( $base, $exponent ) { + @return someVeryLongFunctionNameForJustAPow( $base, $exponent ); +} + +.foo { + width: someVeryLongFunctionNameForJustAPow( + 2, + someVeryLongFunctionNameForJustAPow( + 2, + someVeryLongFunctionNameForJustAPow( + 2, + // This next pow is really powerful + someVeryLongFunctionNameForJustAPow( + 2, + someVeryLongFunctionNameForJustAPow( + 2, + someVeryLongFunctionNameForJustAPow( + 2, + someVeryLongFunctionNameForJustAPow( + 2, + someVeryLongFunctionNameForJustAPow( + 2, + someVeryLongFunctionNameForJustAPow( + 2, + someVeryLongFunctionNameForJustAPow( + 2, + someVeryLongFunctionNameForJustAPow( + 2, + someVeryLongFunctionNameForJustAPow( 2, 2 ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ); +} + +.bar { + width: pow( + 2, + pow( + 2, + pow( + 2, + // This next pow is really powerful + pow( + 2, + pow( + 2, + pow( + 2, + pow( 2, pow( 2, pow( 2, pow( 2, pow( 2, pow( 2, 2 ) ) ) ) ) ) + ) + ) + ) + ) + ) + ); +} + +================================================================================ +`; + +exports[`string-concatanation.scss - {"cssParenSpacing":true} format 1`] = ` +====================================options===================================== +cssParenSpacing: true +parsers: ["scss"] +printWidth: 80 + | printWidth +=====================================input====================================== +a { + background-image: url($test-path + $test-path); + background-image: url($test-path + 'static/test.jpg'); + background-image: url('../test/' + $test-path); + background-image: url('../test/' + 'static/test.jpg'); + background-image: url($test-path+$test-path); +} + +=====================================output===================================== +a { + background-image: url( $test-path + $test-path ); + background-image: url( $test-path + "static/test.jpg" ); + background-image: url( "../test/" + $test-path ); + background-image: url( "../test/" + "static/test.jpg" ); + background-image: url( $test-path + $test-path ); +} + +================================================================================ +`; diff --git a/tests/format/scss/scss/with-inner-spacing/jsfmt.spec.js b/tests/format/scss/scss/with-inner-spacing/jsfmt.spec.js new file mode 100644 index 0000000000..ff02ed77ac --- /dev/null +++ b/tests/format/scss/scss/with-inner-spacing/jsfmt.spec.js @@ -0,0 +1,10 @@ +// [prettierx] test script notice: +// This test script runs for test files in parent directory, +// **not** on any files in *this* directory. + +const dirPath = `${__dirname}/..`; + +run_spec(dirPath, ["scss"], { + // [prettierx] test with --css-paren-spacing + cssParenSpacing: true, +}); diff --git a/tests/format/typescript/argument-expansion/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/argument-expansion/__snapshots__/jsfmt.spec.js.snap index f4c5c473e4..d916b2e865 100644 --- a/tests/format/typescript/argument-expansion/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/typescript/argument-expansion/__snapshots__/jsfmt.spec.js.snap @@ -85,3 +85,75 @@ const bar8 = [1, 2, 3].reduce( ================================================================================ `; + +exports[`arrow-with-return-type.ts format 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +longfunctionWithCall1("bla", foo, (thing: string): complex> => { + code(); +}); + +longfunctionWithCall12("bla", foo, (thing: string): complex> => { + code(); +}); + +longfunctionWithCallBack("blabla", foobarbazblablablablabla, (thing: string): complex> => { + code(); +}); + +longfunctionWithCallBack("blabla", foobarbazblablabla, (thing: string): complex> => { + code(); +}); + +longfunctionWithCall1("bla", foo, (thing: string): complex> => { + code(); +}); + +=====================================output===================================== +longfunctionWithCall1("bla", foo, (thing: string): complex> => { + code(); +}); + +longfunctionWithCall12( + "bla", + foo, + (thing: string): complex> => { + code(); + } +); + +longfunctionWithCallBack( + "blabla", + foobarbazblablablablabla, + (thing: string): complex> => { + code(); + } +); + +longfunctionWithCallBack( + "blabla", + foobarbazblablabla, + (thing: string): complex> => { + code(); + } +); + +longfunctionWithCall1( + "bla", + foo, + ( + thing: string + ): complex< + type<\` +\`> + > => { + code(); + } +); + +================================================================================ +`; diff --git a/tests/format/typescript/argument-expansion/arrow-with-return-type.ts b/tests/format/typescript/argument-expansion/arrow-with-return-type.ts new file mode 100644 index 0000000000..6114f5cf9a --- /dev/null +++ b/tests/format/typescript/argument-expansion/arrow-with-return-type.ts @@ -0,0 +1,20 @@ +longfunctionWithCall1("bla", foo, (thing: string): complex> => { + code(); +}); + +longfunctionWithCall12("bla", foo, (thing: string): complex> => { + code(); +}); + +longfunctionWithCallBack("blabla", foobarbazblablablablabla, (thing: string): complex> => { + code(); +}); + +longfunctionWithCallBack("blabla", foobarbazblablabla, (thing: string): complex> => { + code(); +}); + +longfunctionWithCall1("bla", foo, (thing: string): complex> => { + code(); +}); diff --git a/tests/format/typescript/assignment/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/assignment/__snapshots__/jsfmt.spec.js.snap index 84ee6556f1..6fc1604d4f 100644 --- a/tests/format/typescript/assignment/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/typescript/assignment/__snapshots__/jsfmt.spec.js.snap @@ -180,6 +180,125 @@ const firestorePersonallyIdentifiablePaths: Array = ================================================================================ `; +exports[`issue-10846.ts format 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +const foo = call<{ + prop1: string; + prop2: string; + prop3: string; +}>(); + +export const CallRecorderContext = + createContext<{ + deleteRecording: (id: string) => void; + deleteAll: () => void; + } | null>(null); + +export const CallRecorderContext = + createContext<{ + deleteRecording: (id: string) => void; + deleteAll: () => void; + } | null>(null, "useless"); + +const foo = + call(); + +const foo = + call< + | Foooooooooooo + | Foooooooooooo + | Foooooooooooo + | Foooooooooooo + | Foooooooooooo + >(); + +const foo = + call< + Foooooooooooo & + Foooooooooooo & + Foooooooooooo & + Foooooooooooo & + Foooooooooooo + >(); + +=====================================output===================================== +const foo = call<{ + prop1: string; + prop2: string; + prop3: string; +}>(); + +export const CallRecorderContext = createContext<{ + deleteRecording: (id: string) => void; + deleteAll: () => void; +} | null>(null); + +export const CallRecorderContext = createContext<{ + deleteRecording: (id: string) => void; + deleteAll: () => void; +} | null>(null, "useless"); + +const foo = call< + Foooooo, + Foooooo, + Foooooo, + Foooooo, + Foooooo, + Foooooo, + Foooooo +>(); + +const foo = call< + Foooooooooooo | Foooooooooooo | Foooooooooooo | Foooooooooooo | Foooooooooooo +>(); + +const foo = call< + Foooooooooooo & Foooooooooooo & Foooooooooooo & Foooooooooooo & Foooooooooooo +>(); + +================================================================================ +`; + +exports[`issue-10850.ts format 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +const map: Map> = + new Map(); + +const map: Map = + new Map(); + +const map: Map = + new Map(); + +const map: Map> = new Map(); + +=====================================output===================================== +const map: Map< + Function, + Map +> = new Map(); + +const map: Map< + Function, + Condition extends Foo ? FooFooFoo : BarBarBar +> = new Map(); + +const map: Map = + new Map(); + +const map: Map> = new Map(); + +================================================================================ +`; + exports[`lone-arg.ts format 1`] = ` ====================================options===================================== parsers: ["typescript"] diff --git a/tests/format/typescript/assignment/issue-10846.ts b/tests/format/typescript/assignment/issue-10846.ts new file mode 100644 index 0000000000..db4b211182 --- /dev/null +++ b/tests/format/typescript/assignment/issue-10846.ts @@ -0,0 +1,38 @@ +const foo = call<{ + prop1: string; + prop2: string; + prop3: string; +}>(); + +export const CallRecorderContext = + createContext<{ + deleteRecording: (id: string) => void; + deleteAll: () => void; + } | null>(null); + +export const CallRecorderContext = + createContext<{ + deleteRecording: (id: string) => void; + deleteAll: () => void; + } | null>(null, "useless"); + +const foo = + call(); + +const foo = + call< + | Foooooooooooo + | Foooooooooooo + | Foooooooooooo + | Foooooooooooo + | Foooooooooooo + >(); + +const foo = + call< + Foooooooooooo & + Foooooooooooo & + Foooooooooooo & + Foooooooooooo & + Foooooooooooo + >(); diff --git a/tests/format/typescript/assignment/issue-10850.ts b/tests/format/typescript/assignment/issue-10850.ts new file mode 100644 index 0000000000..4064c5b194 --- /dev/null +++ b/tests/format/typescript/assignment/issue-10850.ts @@ -0,0 +1,10 @@ +const map: Map> = + new Map(); + +const map: Map = + new Map(); + +const map: Map = + new Map(); + +const map: Map> = new Map(); diff --git a/tests/format/typescript/conformance/es6/Symbols/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/conformance/es6/Symbols/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..f357c587d1 --- /dev/null +++ b/tests/format/typescript/conformance/es6/Symbols/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,45 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`symbolProperty15.ts - {"spaceInParens":true,"typeAngleBracketSpacing":true,"typeBracketSpacing":true} format 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 +spaceInParens: true +typeAngleBracketSpacing: true +typeBracketSpacing: true + | printWidth +=====================================input====================================== +//@target: ES6 +class C { } +interface I { + [Symbol.iterator]?: { x }; +} + +declare function foo(i: I): I; +declare function foo(a: any): any; + +declare function bar(i: C): C; +declare function bar(a: any): any; + +foo(new C); +var i: I; +bar(i); +=====================================output===================================== +//@target: ES6 +class C {} +interface I { + [Symbol.iterator]?: { x }; +} + +declare function foo( i: I ): I; +declare function foo( a: any ): any; + +declare function bar( i: C ): C; +declare function bar( a: any ): any; + +foo( new C() ); +var i: I; +bar( i ); + +================================================================================ +`; diff --git a/tests/format/typescript/conformance/es6/Symbols/with-inner-spacing/jsfmt.spec.js b/tests/format/typescript/conformance/es6/Symbols/with-inner-spacing/jsfmt.spec.js new file mode 100644 index 0000000000..66e01a3c5a --- /dev/null +++ b/tests/format/typescript/conformance/es6/Symbols/with-inner-spacing/jsfmt.spec.js @@ -0,0 +1,12 @@ +// [prettierx] test script notice: +// This test script runs for test files in parent directory, +// **not** on any files in *this* directory. + +const dirPath = `${__dirname}/..`; + +run_spec(dirPath, ["typescript"], { + // [prettierx] test with --paren-spacing + spaceInParens: true, + typeAngleBracketSpacing: true, + typeBracketSpacing: true, +}); diff --git a/tests/format/typescript/conformance/interfaces/interfaceDeclarations/no-type-curly-spacing/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/conformance/interfaces/interfaceDeclarations/no-type-curly-spacing/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..6a07de850c --- /dev/null +++ b/tests/format/typescript/conformance/interfaces/interfaceDeclarations/no-type-curly-spacing/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,62 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`interfaceWithMultipleBaseTypes2.ts - {"typeCurlySpacing":false} format 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 +typeCurlySpacing: false + | printWidth +=====================================input====================================== +interface Base { + x: { + a?: string; b: string; + } +} + +interface Base2 { + x: { + b: string; c?: number; + } +} + +interface Derived extends Base, Base2 { + x: { b: string } +} + +interface Derived2 extends Base, Base2 { + x: { a: number; b: string } +} + +interface Derived3 extends Base, Base2 { + x: { a: string; b: string } +} + +=====================================output===================================== +interface Base { + x: { + a?: string; + b: string; + }; +} + +interface Base2 { + x: { + b: string; + c?: number; + }; +} + +interface Derived extends Base, Base2 { + x: {b: string}; +} + +interface Derived2 extends Base, Base2 { + x: {a: number; b: string}; +} + +interface Derived3 extends Base, Base2 { + x: {a: string; b: string}; +} + +================================================================================ +`; diff --git a/tests/format/typescript/conformance/interfaces/interfaceDeclarations/no-type-curly-spacing/jsfmt.spec.js b/tests/format/typescript/conformance/interfaces/interfaceDeclarations/no-type-curly-spacing/jsfmt.spec.js new file mode 100644 index 0000000000..4cda66e517 --- /dev/null +++ b/tests/format/typescript/conformance/interfaces/interfaceDeclarations/no-type-curly-spacing/jsfmt.spec.js @@ -0,0 +1,9 @@ +// [prettierx] test script notice: +// This test script runs for test files in parent directory, +// **not** on any files in *this* directory. + +const dirPath = `${__dirname}/..`; + +run_spec(dirPath, ["typescript"], { + typeCurlySpacing: false, +}); diff --git a/tests/format/typescript/conformance/types/symbol/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/conformance/types/symbol/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..943ceac91a --- /dev/null +++ b/tests/format/typescript/conformance/types/symbol/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,19 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`symbol.ts - {"typeAngleBracketSpacing":true,"typeBracketSpacing":true} format 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 +typeAngleBracketSpacing: true +typeBracketSpacing: true + | printWidth +=====================================input====================================== +var x: symbol +var x: symbol | string + +=====================================output===================================== +var x: symbol; +var x: symbol | string; + +================================================================================ +`; diff --git a/tests/format/typescript/conformance/types/symbol/with-inner-spacing/jsfmt.spec.js b/tests/format/typescript/conformance/types/symbol/with-inner-spacing/jsfmt.spec.js new file mode 100644 index 0000000000..9b62d76d61 --- /dev/null +++ b/tests/format/typescript/conformance/types/symbol/with-inner-spacing/jsfmt.spec.js @@ -0,0 +1,11 @@ +// [prettierx] test script notice: +// This test script runs for test files in parent directory, +// **not** on any files in *this* directory. + +const dirPath = `${__dirname}/..`; + +run_spec(dirPath, ["typescript"], { + // [prettierx] test with spacing options (...) + typeAngleBracketSpacing: true, + typeBracketSpacing: true, +}); diff --git a/tests/format/typescript/function-type/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/function-type/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..5dca29ca51 --- /dev/null +++ b/tests/format/typescript/function-type/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,42 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`single-parameter.ts - {"spaceInParens":true} format 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 +spaceInParens: true + | printWidth +=====================================input====================================== +type X = (options:{ a: string; b: AbstractCompositeThingamabobberFactoryProvider}) => {}; +type Y = new (options:{ a: string; b: AbstractCompositeThingamabobberFactoryProvider}) => {}; +=====================================output===================================== +type X = ( options: { + a: string; + b: AbstractCompositeThingamabobberFactoryProvider; +} ) => {}; +type Y = new ( options: { + a: string; + b: AbstractCompositeThingamabobberFactoryProvider; +} ) => {}; + +================================================================================ +`; + +exports[`type-annotation.ts - {"spaceInParens":true} format 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 +spaceInParens: true + | printWidth +=====================================input====================================== +const foo = (): () => void => (): void => null; +const bar = (): (() => void) => (): void => null; +const baz = (): ((() => void)) => (): void => null; + +=====================================output===================================== +const foo = (): ( () => void ) => (): void => null; +const bar = (): ( () => void ) => (): void => null; +const baz = (): ( () => void ) => (): void => null; + +================================================================================ +`; diff --git a/tests/format/typescript/function-type/with-inner-spacing/jsfmt.spec.js b/tests/format/typescript/function-type/with-inner-spacing/jsfmt.spec.js new file mode 100644 index 0000000000..2102fe4dfc --- /dev/null +++ b/tests/format/typescript/function-type/with-inner-spacing/jsfmt.spec.js @@ -0,0 +1,10 @@ +// [prettierx] test script notice: +// This test script runs for test files in parent directory, +// **not** on any files in *this* directory. + +const dirPath = `${__dirname}/..`; + +run_spec(dirPath, ["typescript"], { + // [prettierx] test with --paren-spacing + spaceInParens: true, +}); diff --git a/tests/format/typescript/generic/function-expression/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/generic/function-expression/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..8bff02319a --- /dev/null +++ b/tests/format/typescript/generic/function-expression/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,21 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`function-expression.ts - {"spaceBeforeFunctionParen":false,"generatorStarSpacing":true} format 1`] = ` +====================================options===================================== +generatorStarSpacing: true +parsers: ["typescript"] +printWidth: 80 +spaceBeforeFunctionParen: false + | printWidth +=====================================input====================================== +const foo = function(bar: T) { + return bar +} + +=====================================output===================================== +const foo = function (bar: T) { + return bar; +}; + +================================================================================ +`; diff --git a/tests/format/typescript/generic/function-expression/function-expression.ts b/tests/format/typescript/generic/function-expression/function-expression.ts new file mode 100644 index 0000000000..afa103a834 --- /dev/null +++ b/tests/format/typescript/generic/function-expression/function-expression.ts @@ -0,0 +1,3 @@ +const foo = function(bar: T) { + return bar +} diff --git a/tests/format/typescript/generic/function-expression/jsfmt.spec.js b/tests/format/typescript/generic/function-expression/jsfmt.spec.js new file mode 100644 index 0000000000..fe2540af85 --- /dev/null +++ b/tests/format/typescript/generic/function-expression/jsfmt.spec.js @@ -0,0 +1,4 @@ +run_spec(__dirname, ["typescript"], { + spaceBeforeFunctionParen: false, + generatorStarSpacing: true, +}); diff --git a/tests/format/typescript/override-modifiers/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/override-modifiers/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..92a627425c --- /dev/null +++ b/tests/format/typescript/override-modifiers/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,29 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`override-modifier.ts format 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +class MyClass extends BaseClass { + override show() {} + public override show() {} + override size = 5; + override readonly size = 5; + abstract override foo: string; + static override foo: string; +} + +=====================================output===================================== +class MyClass extends BaseClass { + override show() {} + public override show() {} + override size = 5; + override readonly size = 5; + abstract override foo: string; + static override foo: string; +} + +================================================================================ +`; diff --git a/tests/format/typescript/override-modifiers/jsfmt.spec.js b/tests/format/typescript/override-modifiers/jsfmt.spec.js new file mode 100644 index 0000000000..2ea3bb6eb2 --- /dev/null +++ b/tests/format/typescript/override-modifiers/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname, ["typescript"]); diff --git a/tests/format/misc/typescript-babel-only/ts-4.3-override-modifier.ts b/tests/format/typescript/override-modifiers/override-modifier.ts similarity index 68% rename from tests/format/misc/typescript-babel-only/ts-4.3-override-modifier.ts rename to tests/format/typescript/override-modifiers/override-modifier.ts index aba84e1c5f..c383924a6e 100644 --- a/tests/format/misc/typescript-babel-only/ts-4.3-override-modifier.ts +++ b/tests/format/typescript/override-modifiers/override-modifier.ts @@ -3,4 +3,6 @@ class MyClass extends BaseClass { public override show() {} override size = 5; override readonly size = 5; + abstract override foo: string; + static override foo: string; } diff --git a/tests/format/typescript/standard/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/standard/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..2e9b230d37 --- /dev/null +++ b/tests/format/typescript/standard/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,105 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`correct.ts - {"yieldStarSpacing":true,"generatorStarSpacing":true,"spaceBeforeFunctionParen":true,"singleQuote":true,"jsxSingleQuote":true,"semi":false} format 1`] = ` +====================================options===================================== +generatorStarSpacing: true +jsxSingleQuote: true +parsers: ["typescript"] +printWidth: 80 +semi: false +singleQuote: true +spaceBeforeFunctionParen: true +yieldStarSpacing: true + | printWidth +=====================================input====================================== +function identity (value: T): T { + return value +} + +interface Foo { + getter(value: T): T +} + +class Example implements Foo { + value: T + getter (value: T): T { + return this.value + } + set setter (value: T) { + this.value = value + } +} + +=====================================output===================================== +function identity (value: T): T { + return value +} + +interface Foo { + getter(value: T): T +} + +class Example implements Foo { + value: T + getter (value: T): T { + return this.value + } + set setter (value: T) { + this.value = value + } +} + +================================================================================ +`; + +exports[`incorrect.ts - {"yieldStarSpacing":true,"generatorStarSpacing":true,"spaceBeforeFunctionParen":true,"singleQuote":true,"jsxSingleQuote":true,"semi":false} format 1`] = ` +====================================options===================================== +generatorStarSpacing: true +jsxSingleQuote: true +parsers: ["typescript"] +printWidth: 80 +semi: false +singleQuote: true +spaceBeforeFunctionParen: true +yieldStarSpacing: true + | printWidth +=====================================input====================================== +function identity (value :T) :T { + return value +} + +interface Foo { + getter(value:T):T +} + +class Example implements Foo { + value:T; + getter(value :T) :T { + return this.value + } + set setter(value :T) { + this.value = value + } +} + +=====================================output===================================== +function identity (value: T): T { + return value +} + +interface Foo { + getter(value: T): T +} + +class Example implements Foo { + value: T + getter (value: T): T { + return this.value + } + set setter (value: T) { + this.value = value + } +} + +================================================================================ +`; diff --git a/tests/format/typescript/standard/correct.ts b/tests/format/typescript/standard/correct.ts new file mode 100644 index 0000000000..a75b70d421 --- /dev/null +++ b/tests/format/typescript/standard/correct.ts @@ -0,0 +1,17 @@ +function identity (value: T): T { + return value +} + +interface Foo { + getter(value: T): T +} + +class Example implements Foo { + value: T + getter (value: T): T { + return this.value + } + set setter (value: T) { + this.value = value + } +} diff --git a/tests/format/typescript/standard/incorrect.ts b/tests/format/typescript/standard/incorrect.ts new file mode 100644 index 0000000000..30a251f1ed --- /dev/null +++ b/tests/format/typescript/standard/incorrect.ts @@ -0,0 +1,17 @@ +function identity (value :T) :T { + return value +} + +interface Foo { + getter(value:T):T +} + +class Example implements Foo { + value:T; + getter(value :T) :T { + return this.value + } + set setter(value :T) { + this.value = value + } +} diff --git a/tests/format/typescript/standard/jsfmt.spec.js b/tests/format/typescript/standard/jsfmt.spec.js new file mode 100644 index 0000000000..112fd03dce --- /dev/null +++ b/tests/format/typescript/standard/jsfmt.spec.js @@ -0,0 +1,8 @@ +run_spec(__dirname, ["typescript"], { + yieldStarSpacing: true, + generatorStarSpacing: true, + spaceBeforeFunctionParen: true, + singleQuote: true, + jsxSingleQuote: true, + semi: false, +}); diff --git a/tests/format/typescript/standard/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/standard/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..b0ce465637 --- /dev/null +++ b/tests/format/typescript/standard/with-inner-spacing/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,109 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`correct.ts - {"spaceInParens":true,"yieldStarSpacing":true,"generatorStarSpacing":true,"typeAngleBracketSpacing":true,"spaceBeforeFunctionParen":true,"singleQuote":true,"jsxSingleQuote":true,"semi":false} format 1`] = ` +====================================options===================================== +generatorStarSpacing: true +jsxSingleQuote: true +parsers: ["typescript"] +printWidth: 80 +semi: false +singleQuote: true +spaceBeforeFunctionParen: true +spaceInParens: true +typeAngleBracketSpacing: true +yieldStarSpacing: true + | printWidth +=====================================input====================================== +function identity (value: T): T { + return value +} + +interface Foo { + getter(value: T): T +} + +class Example implements Foo { + value: T + getter (value: T): T { + return this.value + } + set setter (value: T) { + this.value = value + } +} + +=====================================output===================================== +function identity< T > ( value: T ): T { + return value +} + +interface Foo< T > { + getter( value: T ): T +} + +class Example< T > implements Foo< T > { + value: T + getter ( value: T ): T { + return this.value + } + set setter ( value: T ) { + this.value = value + } +} + +================================================================================ +`; + +exports[`incorrect.ts - {"spaceInParens":true,"yieldStarSpacing":true,"generatorStarSpacing":true,"typeAngleBracketSpacing":true,"spaceBeforeFunctionParen":true,"singleQuote":true,"jsxSingleQuote":true,"semi":false} format 1`] = ` +====================================options===================================== +generatorStarSpacing: true +jsxSingleQuote: true +parsers: ["typescript"] +printWidth: 80 +semi: false +singleQuote: true +spaceBeforeFunctionParen: true +spaceInParens: true +typeAngleBracketSpacing: true +yieldStarSpacing: true + | printWidth +=====================================input====================================== +function identity (value :T) :T { + return value +} + +interface Foo { + getter(value:T):T +} + +class Example implements Foo { + value:T; + getter(value :T) :T { + return this.value + } + set setter(value :T) { + this.value = value + } +} + +=====================================output===================================== +function identity< T > ( value: T ): T { + return value +} + +interface Foo< T > { + getter( value: T ): T +} + +class Example< T > implements Foo< T > { + value: T + getter ( value: T ): T { + return this.value + } + set setter ( value: T ) { + this.value = value + } +} + +================================================================================ +`; diff --git a/tests/format/typescript/standard/with-inner-spacing/jsfmt.spec.js b/tests/format/typescript/standard/with-inner-spacing/jsfmt.spec.js new file mode 100644 index 0000000000..e4f263a48f --- /dev/null +++ b/tests/format/typescript/standard/with-inner-spacing/jsfmt.spec.js @@ -0,0 +1,16 @@ +// [prettierx] test script notice: +// This test script runs for test files in parent directory, +// **not** on any files in *this* directory. + +const dirPath = `${__dirname}/..`; + +run_spec(dirPath, ["typescript"], { + spaceInParens: true, + yieldStarSpacing: true, + generatorStarSpacing: true, + typeAngleBracketSpacing: true, + spaceBeforeFunctionParen: true, + singleQuote: true, + jsxSingleQuote: true, + semi: false, +}); diff --git a/tests/format/typescript/type-alias/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/type-alias/__snapshots__/jsfmt.spec.js.snap index 6f10128eab..9da037d106 100644 --- a/tests/format/typescript/type-alias/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/typescript/type-alias/__snapshots__/jsfmt.spec.js.snap @@ -15,6 +15,99 @@ export type RequestNextDealAction = ================================================================================ `; +exports[`issue-100857.ts format 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +type FieldLayoutWith< + T extends string, + S extends unknown = { width: string } +> = { + type: T; + code: string; + size: S; +}; + +type FieldLayoutWith< + T extends string, + S extends unknown, +> = { + type: T; + code: string; + size: S; +}; + +type FieldLayoutWith< + S extends unknown = { width: string } +> = { + type: T; + code: string; + size: S; +}; + +type FieldLayoutWith< + T extends stringggggggggggg, + T extends stringggggggggggg +> = { + type: T; + code: string; + size: S; +}; + +type FieldLayoutWith< + T extends stringggggggggggg, + S = stringggggggggggggggggg +> = { + type: T; + code: string; + size: S; +}; + +=====================================output===================================== +type FieldLayoutWith< + T extends string, + S extends unknown = { width: string } +> = { + type: T; + code: string; + size: S; +}; + +type FieldLayoutWith = { + type: T; + code: string; + size: S; +}; + +type FieldLayoutWith = { + type: T; + code: string; + size: S; +}; + +type FieldLayoutWith< + T extends stringggggggggggg, + T extends stringggggggggggg +> = { + type: T; + code: string; + size: S; +}; + +type FieldLayoutWith< + T extends stringggggggggggg, + S = stringggggggggggggggggg +> = { + type: T; + code: string; + size: S; +}; + +================================================================================ +`; + exports[`pattern-parameter.ts format 1`] = ` ====================================options===================================== parsers: ["typescript"] diff --git a/tests/format/typescript/type-alias/issue-100857.ts b/tests/format/typescript/type-alias/issue-100857.ts new file mode 100644 index 0000000000..7c2a3144be --- /dev/null +++ b/tests/format/typescript/type-alias/issue-100857.ts @@ -0,0 +1,43 @@ +type FieldLayoutWith< + T extends string, + S extends unknown = { width: string } +> = { + type: T; + code: string; + size: S; +}; + +type FieldLayoutWith< + T extends string, + S extends unknown, +> = { + type: T; + code: string; + size: S; +}; + +type FieldLayoutWith< + S extends unknown = { width: string } +> = { + type: T; + code: string; + size: S; +}; + +type FieldLayoutWith< + T extends stringggggggggggg, + T extends stringggggggggggg +> = { + type: T; + code: string; + size: S; +}; + +type FieldLayoutWith< + T extends stringggggggggggg, + S = stringggggggggggggggggg +> = { + type: T; + code: string; + size: S; +}; diff --git a/tests/format/typescript/type-member-get-set/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/type-member-get-set/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 0000000000..f034192f42 --- /dev/null +++ b/tests/format/typescript/type-member-get-set/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,39 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`type-member-get-set.ts format 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +interface Foo { + get foo(): string; + set bar(v); +} + +type Foo = { + get foo(): string; + set bar(v); +} + +interface Foo { + set bar(foo: string); +} + +=====================================output===================================== +interface Foo { + get foo(): string; + set bar(v); +} + +type Foo = { + get foo(): string; + set bar(v); +}; + +interface Foo { + set bar(foo: string); +} + +================================================================================ +`; diff --git a/tests/format/typescript/type-member-get-set/jsfmt.spec.js b/tests/format/typescript/type-member-get-set/jsfmt.spec.js new file mode 100644 index 0000000000..2ea3bb6eb2 --- /dev/null +++ b/tests/format/typescript/type-member-get-set/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname, ["typescript"]); diff --git a/tests/format/misc/typescript-babel-only/ts4.3-type-members-get-set.ts b/tests/format/typescript/type-member-get-set/type-member-get-set.ts similarity index 100% rename from tests/format/misc/typescript-babel-only/ts4.3-type-members-get-set.ts rename to tests/format/typescript/type-member-get-set/type-member-get-set.ts diff --git a/tests/format/typescript/typeparams/consistent/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/typeparams/consistent/__snapshots__/jsfmt.spec.js.snap index 0a7b54e438..f3ebb5358f 100644 --- a/tests/format/typescript/typeparams/consistent/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/typescript/typeparams/consistent/__snapshots__/jsfmt.spec.js.snap @@ -2,7 +2,7 @@ exports[`flow-only.ts format 1`] = ` ====================================options===================================== -parsers: ["typescript", "flow", "babel-flow", "babel"] +parsers: ["typescript", "flow", "babel-flow"] printWidth: 80 | printWidth =====================================input====================================== @@ -21,7 +21,7 @@ const foo7: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo exports[`issue-9501.ts format 1`] = ` ====================================options===================================== -parsers: ["typescript", "flow", "babel-flow", "babel"] +parsers: ["typescript", "flow", "babel-flow"] printWidth: 80 | printWidth =====================================input====================================== @@ -38,7 +38,7 @@ const name: SomeGeneric> = exports[`simple-types.ts format 1`] = ` ====================================options===================================== -parsers: ["typescript", "flow", "babel-flow", "babel"] +parsers: ["typescript", "flow", "babel-flow"] printWidth: 80 | printWidth =====================================input====================================== @@ -84,13 +84,6 @@ const foo12: Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo ================================================================================ `; -exports[`template-literal-types.ts [babel] format 1`] = ` -"Unexpected token (1:84) -> 1 | const foo1: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<\`Hello, \${keyof World}\`> = a; - | ^ - 2 |" -`; - exports[`template-literal-types.ts [babel-flow] format 1`] = ` "Unexpected token (1:84) > 1 | const foo1: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<\`Hello, \${keyof World}\`> = a; @@ -107,7 +100,7 @@ exports[`template-literal-types.ts [flow] format 1`] = ` exports[`template-literal-types.ts format 1`] = ` ====================================options===================================== -parsers: ["typescript", "flow", "babel-flow", "babel"] +parsers: ["typescript", "flow", "babel-flow"] printWidth: 80 | printWidth =====================================input====================================== @@ -122,7 +115,7 @@ const foo1: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo exports[`typescript-only.ts format 1`] = ` ====================================options===================================== -parsers: ["typescript", "flow", "babel-flow", "babel"] +parsers: ["typescript", "flow", "babel-flow"] printWidth: 80 | printWidth =====================================input====================================== diff --git a/tests/format/typescript/typeparams/consistent/jsfmt.spec.js b/tests/format/typescript/typeparams/consistent/jsfmt.spec.js index 9990099dc8..e590e7f2ad 100644 --- a/tests/format/typescript/typeparams/consistent/jsfmt.spec.js +++ b/tests/format/typescript/typeparams/consistent/jsfmt.spec.js @@ -1,7 +1,6 @@ -run_spec(__dirname, ["typescript", "flow", "babel-flow", "babel"], { +run_spec(__dirname, ["typescript", "flow", "babel-flow"], { errors: { flow: ["template-literal-types.ts"], "babel-flow": ["template-literal-types.ts"], - babel: ["template-literal-types.ts"], }, }); diff --git a/tests/format/yaml/comment/__snapshots__/jsfmt.spec.js.snap b/tests/format/yaml/comment/__snapshots__/jsfmt.spec.js.snap index 40c5720ed1..db44b11630 100644 --- a/tests/format/yaml/comment/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/yaml/comment/__snapshots__/jsfmt.spec.js.snap @@ -6,9 +6,9 @@ parsers: ["yaml"] printWidth: 80 | printWidth =====================================input====================================== -a: +a: # a.trailingComment 123 - # impicitMappginValue + # implicitMappingValue ? b # explicitMappingKey @@ -37,9 +37,9 @@ empty_content: # hello world =====================================output===================================== -a: +a: # a.trailingComment 123 - # impicitMappginValue + # implicitMappingValue ? b # explicitMappingKey diff --git a/tests/format/yaml/comment/collection.yml b/tests/format/yaml/comment/collection.yml index c93a08322b..f3df4914f7 100644 --- a/tests/format/yaml/comment/collection.yml +++ b/tests/format/yaml/comment/collection.yml @@ -1,6 +1,6 @@ -a: +a: # a.trailingComment 123 - # impicitMappginValue + # implicitMappingValue ? b # explicitMappingKey diff --git a/tests/format/yaml/flow-mapping/__snapshots__/jsfmt.spec.js.snap b/tests/format/yaml/flow-mapping/__snapshots__/jsfmt.spec.js.snap index 60c4518e63..e1a93b79f2 100644 --- a/tests/format/yaml/flow-mapping/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/yaml/flow-mapping/__snapshots__/jsfmt.spec.js.snap @@ -1,10 +1,11 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`alias-key.yml - {"bracketSpacing":false} format 1`] = ` +exports[`alias-key.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== {&123 foo, *123 : 456} @@ -44,11 +45,12 @@ printWidth: 80 ================================================================================ `; -exports[`array-key.yml - {"bracketSpacing":false} format 1`] = ` +exports[`array-key.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== {? [longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong],? [longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong],? [longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong]} @@ -136,11 +138,12 @@ printWidth: 80 ================================================================================ `; -exports[`array-key-array-value.yml - {"bracketSpacing":false} format 1`] = ` +exports[`array-key-array-value.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== {[longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong]: [longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong],[longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong]: [longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong],[longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong]: [longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong]} @@ -273,11 +276,12 @@ printWidth: 80 ================================================================================ `; -exports[`array-plain.yml - {"bracketSpacing":false} format 1`] = ` +exports[`array-plain.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== {[longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong],[longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong],[longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong]} @@ -365,11 +369,12 @@ printWidth: 80 ================================================================================ `; -exports[`array-value.yml - {"bracketSpacing":false} format 1`] = ` +exports[`array-value.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== {a: [longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong],b: [longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong],c: [longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong]} @@ -466,11 +471,12 @@ printWidth: 80 ================================================================================ `; -exports[`comment-between.yml - {"bracketSpacing":false} format 1`] = ` +exports[`comment-between.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== { @@ -534,11 +540,12 @@ printWidth: 80 ================================================================================ `; -exports[`comment-trailing.yml - {"bracketSpacing":false} format 1`] = ` +exports[`comment-trailing.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== {123, # comment @@ -587,11 +594,12 @@ printWidth: 80 ================================================================================ `; -exports[`empty.yml - {"bracketSpacing":false} format 1`] = ` +exports[`empty.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== {} @@ -631,11 +639,12 @@ printWidth: 80 ================================================================================ `; -exports[`empty-item-colon.yml - {"bracketSpacing":false} format 1`] = ` +exports[`empty-item-colon.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== { : } @@ -675,11 +684,12 @@ printWidth: 80 ================================================================================ `; -exports[`empty-line.yml - {"bracketSpacing":false} format 1`] = ` +exports[`empty-line.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== { aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, @@ -737,11 +747,12 @@ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb } ================================================================================ `; -exports[`empty-line-collapse.yml - {"bracketSpacing":false} format 1`] = ` +exports[`empty-line-collapse.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== { aaa, @@ -787,11 +798,12 @@ bbb } ================================================================================ `; -exports[`long-key.yml - {"bracketSpacing":false} format 1`] = ` +exports[`long-key.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== {? longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong1,? longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong2,? longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong3} @@ -843,11 +855,12 @@ printWidth: 80 ================================================================================ `; -exports[`long-key-long-value.yml - {"bracketSpacing":false} format 1`] = ` +exports[`long-key-long-value.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== {longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong1: longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong,longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong2: longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong,longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong3: longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong} @@ -899,11 +912,12 @@ printWidth: 80 ================================================================================ `; -exports[`long-plain.yml - {"bracketSpacing":false} format 1`] = ` +exports[`long-plain.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== {longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong1,longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong2,longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong3} @@ -955,11 +969,12 @@ printWidth: 80 ================================================================================ `; -exports[`long-value.yml - {"bracketSpacing":false} format 1`] = ` +exports[`long-value.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== {1: longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong,2: longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong,3: longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong} @@ -1011,11 +1026,12 @@ printWidth: 80 ================================================================================ `; -exports[`middle-comment.yml - {"bracketSpacing":false} format 1`] = ` +exports[`middle-comment.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== !!map #comment @@ -1061,11 +1077,12 @@ printWidth: 80 ================================================================================ `; -exports[`middle-comments.yml - {"bracketSpacing":false} format 1`] = ` +exports[`middle-comments.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== !!map # comment 1 @@ -1120,11 +1137,12 @@ printWidth: 80 ================================================================================ `; -exports[`next-empty-line.yml - {"bracketSpacing":false} format 1`] = ` +exports[`next-empty-line.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== { @@ -1191,11 +1209,12 @@ c: 123 ================================================================================ `; -exports[`props.yml - {"bracketSpacing":false} format 1`] = ` +exports[`props.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== !!map &anchor {a: 1} @@ -1235,11 +1254,12 @@ printWidth: 80 ================================================================================ `; -exports[`props-in-map.yml - {"bracketSpacing":false} format 1`] = ` +exports[`props-in-map.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== a: !!map &anchor {a: 1} @@ -1279,11 +1299,12 @@ a: !!map &anchor { a: 1 } ================================================================================ `; -exports[`short-key.yml - {"bracketSpacing":false} format 1`] = ` +exports[`short-key.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== {? 1,? 2,? 3} @@ -1323,11 +1344,12 @@ printWidth: 80 ================================================================================ `; -exports[`short-key-short-value.yml - {"bracketSpacing":false} format 1`] = ` +exports[`short-key-short-value.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== {1: a,2: b,3: c} @@ -1367,11 +1389,12 @@ printWidth: 80 ================================================================================ `; -exports[`short-plain.yml - {"bracketSpacing":false} format 1`] = ` +exports[`short-plain.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== {1,2,3} @@ -1411,11 +1434,12 @@ printWidth: 80 ================================================================================ `; -exports[`short-value.yml - {"bracketSpacing":false} format 1`] = ` +exports[`short-value.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== {1: 1,2: 2,3: 3} @@ -1455,11 +1479,12 @@ printWidth: 80 ================================================================================ `; -exports[`very-long-value.yml - {"bracketSpacing":false} format 1`] = ` +exports[`very-long-value.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== { diff --git a/tests/format/yaml/flow-mapping/jsfmt.spec.js b/tests/format/yaml/flow-mapping/jsfmt.spec.js index 755b6ecb28..707c8c8e76 100644 --- a/tests/format/yaml/flow-mapping/jsfmt.spec.js +++ b/tests/format/yaml/flow-mapping/jsfmt.spec.js @@ -1,3 +1,9 @@ run_spec(__dirname, ["yaml"]); run_spec(__dirname, ["yaml"], { tabWidth: 4 }); -run_spec(__dirname, ["yaml"], { bracketSpacing: false }); +// [prettierx]: broken-out bracket spacing option(s) +run_spec(__dirname, ["yaml"], { + // [prettierx] bogus option to keep snapshot more consistent with Prettier 2.3.0 + bogus: null, + // [prettierx] replaced bracketSpacing option + yamlBracketSpacing: false, +}); diff --git a/tests/format/yaml/flow-sequence/__snapshots__/jsfmt.spec.js.snap b/tests/format/yaml/flow-sequence/__snapshots__/jsfmt.spec.js.snap index 8dac907078..ce8bec788b 100644 --- a/tests/format/yaml/flow-sequence/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/yaml/flow-sequence/__snapshots__/jsfmt.spec.js.snap @@ -1,10 +1,11 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`alias-key.yml - {"bracketSpacing":false} format 1`] = ` +exports[`alias-key.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== [&123 foo, *123 : 456] @@ -44,11 +45,12 @@ printWidth: 80 ================================================================================ `; -exports[`array-key.yml - {"bracketSpacing":false} format 1`] = ` +exports[`array-key.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== [? [longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong],? [longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong],? [longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong]] @@ -136,11 +138,12 @@ printWidth: 80 ================================================================================ `; -exports[`array-key-array-value.yml - {"bracketSpacing":false} format 1`] = ` +exports[`array-key-array-value.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== [[longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong]: [longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong],[longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong]: [longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong],[longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong]: [longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong]] @@ -273,11 +276,12 @@ printWidth: 80 ================================================================================ `; -exports[`array-plain.yml - {"bracketSpacing":false} format 1`] = ` +exports[`array-plain.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== [[longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong],[longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong],[longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong]] @@ -365,11 +369,12 @@ printWidth: 80 ================================================================================ `; -exports[`array-value.yml - {"bracketSpacing":false} format 1`] = ` +exports[`array-value.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== [: [longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong],: [longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong],: [longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong, longlonglonglonglonglonglonglonglonglonglong]] @@ -457,11 +462,12 @@ printWidth: 80 ================================================================================ `; -exports[`comment-between.yml - {"bracketSpacing":false} format 1`] = ` +exports[`comment-between.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== [ @@ -525,11 +531,12 @@ printWidth: 80 ================================================================================ `; -exports[`comment-trailing.yml - {"bracketSpacing":false} format 1`] = ` +exports[`comment-trailing.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== [123, # comment @@ -578,11 +585,12 @@ printWidth: 80 ================================================================================ `; -exports[`empty.yml - {"bracketSpacing":false} format 1`] = ` +exports[`empty.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== [] @@ -622,11 +630,12 @@ printWidth: 80 ================================================================================ `; -exports[`empty-item-colon.yml - {"bracketSpacing":false} format 1`] = ` +exports[`empty-item-colon.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== [ : ] @@ -666,11 +675,12 @@ printWidth: 80 ================================================================================ `; -exports[`empty-line.yml - {"bracketSpacing":false} format 1`] = ` +exports[`empty-line.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== [ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, @@ -728,11 +738,12 @@ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ] ================================================================================ `; -exports[`empty-line-collapse.yml - {"bracketSpacing":false} format 1`] = ` +exports[`empty-line-collapse.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== [ aaa, @@ -778,11 +789,12 @@ bbb ] ================================================================================ `; -exports[`long-key.yml - {"bracketSpacing":false} format 1`] = ` +exports[`long-key.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== [? longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong,? longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong,? longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong] @@ -834,11 +846,12 @@ printWidth: 80 ================================================================================ `; -exports[`long-key-long-value.yml - {"bracketSpacing":false} format 1`] = ` +exports[`long-key-long-value.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== [longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong: longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong,longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong: longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong,longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong: longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong] @@ -890,11 +903,12 @@ printWidth: 80 ================================================================================ `; -exports[`long-plain.yml - {"bracketSpacing":false} format 1`] = ` +exports[`long-plain.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== [longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong,longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong,longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong] @@ -946,11 +960,12 @@ printWidth: 80 ================================================================================ `; -exports[`long-value.yml - {"bracketSpacing":false} format 1`] = ` +exports[`long-value.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== [: longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong,: longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong,: longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong] @@ -1002,11 +1017,12 @@ printWidth: 80 ================================================================================ `; -exports[`middle-comment.yml - {"bracketSpacing":false} format 1`] = ` +exports[`middle-comment.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== !!set # comment @@ -1052,11 +1068,12 @@ printWidth: 80 ================================================================================ `; -exports[`middle-comments.yml - {"bracketSpacing":false} format 1`] = ` +exports[`middle-comments.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== !!set # comment 1 @@ -1111,11 +1128,12 @@ printWidth: 80 ================================================================================ `; -exports[`next-empty-line.yml - {"bracketSpacing":false} format 1`] = ` +exports[`next-empty-line.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== [ @@ -1182,11 +1200,12 @@ c: 123 ================================================================================ `; -exports[`props.yml - {"bracketSpacing":false} format 1`] = ` +exports[`props.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== !!set &anchor [1] @@ -1226,11 +1245,12 @@ printWidth: 80 ================================================================================ `; -exports[`props-in-map.yml - {"bracketSpacing":false} format 1`] = ` +exports[`props-in-map.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== a: !!set &anchor [1] @@ -1270,11 +1290,12 @@ a: !!set &anchor [1] ================================================================================ `; -exports[`short-key.yml - {"bracketSpacing":false} format 1`] = ` +exports[`short-key.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== [? 1,? 2,? 3] @@ -1314,11 +1335,12 @@ printWidth: 80 ================================================================================ `; -exports[`short-key-short-value.yml - {"bracketSpacing":false} format 1`] = ` +exports[`short-key-short-value.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== [1: a,2: b,3: c] @@ -1358,11 +1380,12 @@ printWidth: 80 ================================================================================ `; -exports[`short-plain.yml - {"bracketSpacing":false} format 1`] = ` +exports[`short-plain.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== [1,2,3] @@ -1402,11 +1425,12 @@ printWidth: 80 ================================================================================ `; -exports[`short-value.yml - {"bracketSpacing":false} format 1`] = ` +exports[`short-value.yml - {"bogus":null,"yamlBracketSpacing":false} format 1`] = ` ====================================options===================================== -bracketSpacing: false +bogus: null parsers: ["yaml"] printWidth: 80 +yamlBracketSpacing: false | printWidth =====================================input====================================== [: 1,: 2,: 3] diff --git a/tests/format/yaml/flow-sequence/jsfmt.spec.js b/tests/format/yaml/flow-sequence/jsfmt.spec.js index 755b6ecb28..707c8c8e76 100644 --- a/tests/format/yaml/flow-sequence/jsfmt.spec.js +++ b/tests/format/yaml/flow-sequence/jsfmt.spec.js @@ -1,3 +1,9 @@ run_spec(__dirname, ["yaml"]); run_spec(__dirname, ["yaml"], { tabWidth: 4 }); -run_spec(__dirname, ["yaml"], { bracketSpacing: false }); +// [prettierx]: broken-out bracket spacing option(s) +run_spec(__dirname, ["yaml"], { + // [prettierx] bogus option to keep snapshot more consistent with Prettier 2.3.0 + bogus: null, + // [prettierx] replaced bracketSpacing option + yamlBracketSpacing: false, +}); diff --git a/tests/format/yaml/mapping/__snapshots__/jsfmt.spec.js.snap b/tests/format/yaml/mapping/__snapshots__/jsfmt.spec.js.snap index 37b1da0b2e..ffb14a8ab9 100644 --- a/tests/format/yaml/mapping/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/yaml/mapping/__snapshots__/jsfmt.spec.js.snap @@ -366,11 +366,25 @@ tabWidth: 4 : longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong ? longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong : value +? solongitshouldbreakbutitcannot_longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong +: # Comment + foo: bar +? multiline + scalar + key +: value =====================================output===================================== key1: value key2: longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong: value +solongitshouldbreakbutitcannot_longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong: + # Comment + foo: bar +? multiline + scalar + key +: value ================================================================================ `; @@ -387,11 +401,25 @@ printWidth: 80 : longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong ? longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong : value +? solongitshouldbreakbutitcannot_longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong +: # Comment + foo: bar +? multiline + scalar + key +: value =====================================output===================================== key1: value key2: longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong: value +solongitshouldbreakbutitcannot_longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong: + # Comment + foo: bar +? multiline + scalar + key +: value ================================================================================ `; diff --git a/tests/format/yaml/mapping/explicit-key.yml b/tests/format/yaml/mapping/explicit-key.yml index 3223ef8ebc..1f81c1d42b 100644 --- a/tests/format/yaml/mapping/explicit-key.yml +++ b/tests/format/yaml/mapping/explicit-key.yml @@ -4,3 +4,10 @@ : longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong ? longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong : value +? solongitshouldbreakbutitcannot_longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong +: # Comment + foo: bar +? multiline + scalar + key +: value diff --git a/tests/integration/__tests__/__snapshots__/early-exit.js.snap b/tests/integration/__tests__/__snapshots__/early-exit.js.snap index 4faab0a77f..780c362064 100644 --- a/tests/integration/__tests__/__snapshots__/early-exit.js.snap +++ b/tests/integration/__tests__/__snapshots__/early-exit.js.snap @@ -1,14 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`node version error 1`] = ` -Object { - "stderr": "prettier requires at least version 10.13.0 of Node, please upgrade -", - "stdout": "", - "write": Array [], -} -`; - exports[`show detailed usage with --help l (alias) (stderr) 1`] = `""`; exports[`show detailed usage with --help l (alias) (stdout) 1`] = ` @@ -53,7 +44,7 @@ exports[`show detailed usage with plugin options (manual resolution) (write) 1`] exports[`show usage with --help (stderr) 1`] = `""`; exports[`show usage with --help (stdout) 1`] = ` -"Usage: prettier [options] [file/dir/glob ...] +"Usage: prettierx [options] [file/dir/glob ...] By default, output is written to stdout. Stdin is read if it is piped to Prettier and no files are given. @@ -67,23 +58,56 @@ Output options: Format options: + --align-object-properties + Align colons in multiline object literals. + Defaults to false. + --array-bracket-spacing Put spaces between array brackets (similar to the corresponding eslint option). Status: experimental, with limited testing. + Defaults to false. --arrow-parens Include parentheses around a sole arrow function parameter. Defaults to always. - --no-bracket-spacing Do not print spaces between brackets. + --break-before-else Always add a line break before else. + Defaults to false. + --break-long-method-chains + Break method chains with more than 3 method calls, like Prettier 1.x. + Defaults to false. + --computed-property-spacing + Put spaces between computed property brackets (similar to the corresponding eslint option). Status: experimental, with limited testing. + Defaults to false. + --css-paren-spacing Print spaces between parens in CSS, WordPress style. Status: experimental, with limited testing. + Defaults to false. --embedded-language-formatting Control how Prettier formats quoted code embedded in the file. Defaults to auto. --end-of-line Which end of line characters to apply. Defaults to lf. + --no-export-curly-spacing + Disable spaces between export curly braces. + --generator-star-spacing Put spaces around the star (\`*\`) in generator functions (before and after - similar to the corresponding eslint option). (Default is after only.) + Defaults to false. + --no-graphql-curly-spacing + Do not put spaces between curly braces for GraphQL. + --html-void-tags Format void HTML elements as void tags. + Defaults to false. --html-whitespace-sensitivity How to handle whitespaces in HTML. Defaults to css. + --no-import-curly-spacing + Disable spaces between import curly braces. + --import-formatting + Formatting of import statements, may be \`oneline\` to avoid conflict with VSCode \\"Organize Imports\\" feature. + Defaults to auto. + --no-indent-chains Disable indents at the start of chained calls. --jsx-bracket-same-line Put > on the last line instead of at a new line. Defaults to false. --jsx-single-quote Use single quotes in JSX. Defaults to false. + --no-object-curly-spacing + Disable spaces between object curly braces. + --offset-ternary-expressions + Indent and align ternary expression branches more consistently with \\"Standard JS\\" (similar to the corresponding eslint option). + Defaults to false. --parser Which parser to use. --print-width The line length where Prettier will try wrap. @@ -97,16 +121,35 @@ Format options: --no-semi Do not print semicolons, except at the beginning of lines which may need them. --single-quote Use single quotes instead of double quotes. Defaults to false. + --space-before-function-paren + Put a space before function parenthesis in all declarations (similar to the corresponding eslint option). (Default is to put a space before function parenthesis for untyped anonymous functions only.) + Defaults to false. + --space-in-parens Print spaces in between parens, WordPress style (similar to the corresponding eslint option). Not recommended in combination with the default \`arrowParens: \\"always\\"\` option. Status: experimental, with limited testing. + Defaults to false. + --space-unary-ops Put spaces after unary operator symbols, except in the middle of \`!!\` (similar to the corresponding eslint option). Status: experimental, with limited testing. + Defaults to false. --tab-width Number of spaces per indentation level. Defaults to 2. + --template-curly-spacing Put spaces between template curly brackets (similar to the corresponding eslint option). Status: experimental, with limited testing. + Defaults to false. --trailing-comma Print trailing commas wherever possible when multi-line. Defaults to es5. + --type-angle-bracket-spacing + Put spaces between type angle brackets. Status: experimental, with limited testing. + Defaults to false. + --type-bracket-spacing Print spaces between type brackets. Status: experimental, with limited testing. + Defaults to false. + --no-type-curly-spacing Disable spaces between type curly braces. --use-tabs Indent with tabs instead of spaces. Defaults to false. --vue-indent-script-and-style Indent script and style tags in Vue files. Defaults to false. + --no-yaml-bracket-spacing + Do not put spaces between brackets / curly braces for YAML. + --yield-star-spacing Put spaces around the star (\`*\`) in \`yield*\` expressions (before and after - similar to the corresponding eslint option). (Default is after only.) + Defaults to false. Config options: @@ -218,7 +261,7 @@ exports[`show warning with --help not-found (typo) (write) 1`] = `Array []`; exports[`throw error and show usage with something unexpected (stderr) 1`] = `""`; exports[`throw error and show usage with something unexpected (stdout) 1`] = ` -"Usage: prettier [options] [file/dir/glob ...] +"Usage: prettierx [options] [file/dir/glob ...] By default, output is written to stdout. Stdin is read if it is piped to Prettier and no files are given. @@ -232,23 +275,56 @@ Output options: Format options: + --align-object-properties + Align colons in multiline object literals. + Defaults to false. + --array-bracket-spacing Put spaces between array brackets (similar to the corresponding eslint option). Status: experimental, with limited testing. + Defaults to false. --arrow-parens Include parentheses around a sole arrow function parameter. Defaults to always. - --no-bracket-spacing Do not print spaces between brackets. + --break-before-else Always add a line break before else. + Defaults to false. + --break-long-method-chains + Break method chains with more than 3 method calls, like Prettier 1.x. + Defaults to false. + --computed-property-spacing + Put spaces between computed property brackets (similar to the corresponding eslint option). Status: experimental, with limited testing. + Defaults to false. + --css-paren-spacing Print spaces between parens in CSS, WordPress style. Status: experimental, with limited testing. + Defaults to false. --embedded-language-formatting Control how Prettier formats quoted code embedded in the file. Defaults to auto. --end-of-line Which end of line characters to apply. Defaults to lf. + --no-export-curly-spacing + Disable spaces between export curly braces. + --generator-star-spacing Put spaces around the star (\`*\`) in generator functions (before and after - similar to the corresponding eslint option). (Default is after only.) + Defaults to false. + --no-graphql-curly-spacing + Do not put spaces between curly braces for GraphQL. + --html-void-tags Format void HTML elements as void tags. + Defaults to false. --html-whitespace-sensitivity How to handle whitespaces in HTML. Defaults to css. + --no-import-curly-spacing + Disable spaces between import curly braces. + --import-formatting + Formatting of import statements, may be \`oneline\` to avoid conflict with VSCode \\"Organize Imports\\" feature. + Defaults to auto. + --no-indent-chains Disable indents at the start of chained calls. --jsx-bracket-same-line Put > on the last line instead of at a new line. Defaults to false. --jsx-single-quote Use single quotes in JSX. Defaults to false. + --no-object-curly-spacing + Disable spaces between object curly braces. + --offset-ternary-expressions + Indent and align ternary expression branches more consistently with \\"Standard JS\\" (similar to the corresponding eslint option). + Defaults to false. --parser Which parser to use. --print-width The line length where Prettier will try wrap. @@ -262,16 +338,35 @@ Format options: --no-semi Do not print semicolons, except at the beginning of lines which may need them. --single-quote Use single quotes instead of double quotes. Defaults to false. + --space-before-function-paren + Put a space before function parenthesis in all declarations (similar to the corresponding eslint option). (Default is to put a space before function parenthesis for untyped anonymous functions only.) + Defaults to false. + --space-in-parens Print spaces in between parens, WordPress style (similar to the corresponding eslint option). Not recommended in combination with the default \`arrowParens: \\"always\\"\` option. Status: experimental, with limited testing. + Defaults to false. + --space-unary-ops Put spaces after unary operator symbols, except in the middle of \`!!\` (similar to the corresponding eslint option). Status: experimental, with limited testing. + Defaults to false. --tab-width Number of spaces per indentation level. Defaults to 2. + --template-curly-spacing Put spaces between template curly brackets (similar to the corresponding eslint option). Status: experimental, with limited testing. + Defaults to false. --trailing-comma Print trailing commas wherever possible when multi-line. Defaults to es5. + --type-angle-bracket-spacing + Put spaces between type angle brackets. Status: experimental, with limited testing. + Defaults to false. + --type-bracket-spacing Print spaces between type brackets. Status: experimental, with limited testing. + Defaults to false. + --no-type-curly-spacing Disable spaces between type curly braces. --use-tabs Indent with tabs instead of spaces. Defaults to false. --vue-indent-script-and-style Indent script and style tags in Vue files. Defaults to false. + --no-yaml-bracket-spacing + Do not put spaces between brackets / curly braces for YAML. + --yield-star-spacing Put spaces around the star (\`*\`) in \`yield*\` expressions (before and after - similar to the corresponding eslint option). (Default is after only.) + Defaults to false. Config options: diff --git a/tests/integration/__tests__/__snapshots__/help-options.js.snap b/tests/integration/__tests__/__snapshots__/help-options.js.snap index 0d8680b47c..f3cf49b838 100644 --- a/tests/integration/__tests__/__snapshots__/help-options.js.snap +++ b/tests/integration/__tests__/__snapshots__/help-options.js.snap @@ -1,5 +1,31 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`show detailed usage with --help align-object-properties (stderr) 1`] = `""`; + +exports[`show detailed usage with --help align-object-properties (stdout) 1`] = ` +"--align-object-properties + + Align colons in multiline object literals. + +Default: false +" +`; + +exports[`show detailed usage with --help align-object-properties (write) 1`] = `Array []`; + +exports[`show detailed usage with --help array-bracket-spacing (stderr) 1`] = `""`; + +exports[`show detailed usage with --help array-bracket-spacing (stdout) 1`] = ` +"--array-bracket-spacing + + Put spaces between array brackets (similar to the corresponding eslint option). Status: experimental, with limited testing. + +Default: false +" +`; + +exports[`show detailed usage with --help array-bracket-spacing (write) 1`] = `Array []`; + exports[`show detailed usage with --help arrow-parens (stderr) 1`] = `""`; exports[`show detailed usage with --help arrow-parens (stdout) 1`] = ` @@ -18,18 +44,31 @@ Default: always exports[`show detailed usage with --help arrow-parens (write) 1`] = `Array []`; -exports[`show detailed usage with --help bracket-spacing (stderr) 1`] = `""`; +exports[`show detailed usage with --help break-before-else (stderr) 1`] = `""`; -exports[`show detailed usage with --help bracket-spacing (stdout) 1`] = ` -"--bracket-spacing +exports[`show detailed usage with --help break-before-else (stdout) 1`] = ` +"--break-before-else - Print spaces between brackets. + Always add a line break before else. -Default: true +Default: false " `; -exports[`show detailed usage with --help bracket-spacing (write) 1`] = `Array []`; +exports[`show detailed usage with --help break-before-else (write) 1`] = `Array []`; + +exports[`show detailed usage with --help break-long-method-chains (stderr) 1`] = `""`; + +exports[`show detailed usage with --help break-long-method-chains (stdout) 1`] = ` +"--break-long-method-chains + + Break method chains with more than 3 method calls, like Prettier 1.x. + +Default: false +" +`; + +exports[`show detailed usage with --help break-long-method-chains (write) 1`] = `Array []`; exports[`show detailed usage with --help check (stderr) 1`] = `""`; @@ -56,6 +95,19 @@ Default: true exports[`show detailed usage with --help color (write) 1`] = `Array []`; +exports[`show detailed usage with --help computed-property-spacing (stderr) 1`] = `""`; + +exports[`show detailed usage with --help computed-property-spacing (stdout) 1`] = ` +"--computed-property-spacing + + Put spaces between computed property brackets (similar to the corresponding eslint option). Status: experimental, with limited testing. + +Default: false +" +`; + +exports[`show detailed usage with --help computed-property-spacing (write) 1`] = `Array []`; + exports[`show detailed usage with --help config (stderr) 1`] = `""`; exports[`show detailed usage with --help config (stdout) 1`] = ` @@ -87,6 +139,19 @@ Default: cli-override exports[`show detailed usage with --help config-precedence (write) 1`] = `Array []`; +exports[`show detailed usage with --help css-paren-spacing (stderr) 1`] = `""`; + +exports[`show detailed usage with --help css-paren-spacing (stdout) 1`] = ` +"--css-paren-spacing + + Print spaces between parens in CSS, WordPress style. Status: experimental, with limited testing. + +Default: false +" +`; + +exports[`show detailed usage with --help css-paren-spacing (write) 1`] = `Array []`; + exports[`show detailed usage with --help cursor-offset (stderr) 1`] = `""`; exports[`show detailed usage with --help cursor-offset (stdout) 1`] = ` @@ -153,6 +218,19 @@ Default: lf exports[`show detailed usage with --help end-of-line (write) 1`] = `Array []`; +exports[`show detailed usage with --help export-curly-spacing (stderr) 1`] = `""`; + +exports[`show detailed usage with --help export-curly-spacing (stdout) 1`] = ` +"--export-curly-spacing + + Put spaces between export curly braces. + +Default: true +" +`; + +exports[`show detailed usage with --help export-curly-spacing (write) 1`] = `Array []`; + exports[`show detailed usage with --help file-info (stderr) 1`] = `""`; exports[`show detailed usage with --help file-info (stdout) 1`] = ` @@ -177,6 +255,32 @@ exports[`show detailed usage with --help find-config-path (stdout) 1`] = ` exports[`show detailed usage with --help find-config-path (write) 1`] = `Array []`; +exports[`show detailed usage with --help generator-star-spacing (stderr) 1`] = `""`; + +exports[`show detailed usage with --help generator-star-spacing (stdout) 1`] = ` +"--generator-star-spacing + + Put spaces around the star (\`*\`) in generator functions (before and after - similar to the corresponding eslint option). (Default is after only.) + +Default: false +" +`; + +exports[`show detailed usage with --help generator-star-spacing (write) 1`] = `Array []`; + +exports[`show detailed usage with --help graphql-curly-spacing (stderr) 1`] = `""`; + +exports[`show detailed usage with --help graphql-curly-spacing (stdout) 1`] = ` +"--graphql-curly-spacing + + Put spaces between curly braces for GraphQL. + +Default: true +" +`; + +exports[`show detailed usage with --help graphql-curly-spacing (write) 1`] = `Array []`; + exports[`show detailed usage with --help help (stderr) 1`] = `""`; exports[`show detailed usage with --help help (stdout) 1`] = ` @@ -189,6 +293,19 @@ exports[`show detailed usage with --help help (stdout) 1`] = ` exports[`show detailed usage with --help help (write) 1`] = `Array []`; +exports[`show detailed usage with --help html-void-tags (stderr) 1`] = `""`; + +exports[`show detailed usage with --help html-void-tags (stdout) 1`] = ` +"--html-void-tags + + Format void HTML elements as void tags. + +Default: false +" +`; + +exports[`show detailed usage with --help html-void-tags (write) 1`] = `Array []`; + exports[`show detailed usage with --help html-whitespace-sensitivity (stderr) 1`] = `""`; exports[`show detailed usage with --help html-whitespace-sensitivity (stdout) 1`] = ` @@ -232,6 +349,50 @@ exports[`show detailed usage with --help ignore-unknown (stdout) 1`] = ` exports[`show detailed usage with --help ignore-unknown (write) 1`] = `Array []`; +exports[`show detailed usage with --help import-curly-spacing (stderr) 1`] = `""`; + +exports[`show detailed usage with --help import-curly-spacing (stdout) 1`] = ` +"--import-curly-spacing + + Put spaces between import curly braces. + +Default: true +" +`; + +exports[`show detailed usage with --help import-curly-spacing (write) 1`] = `Array []`; + +exports[`show detailed usage with --help import-formatting (stderr) 1`] = `""`; + +exports[`show detailed usage with --help import-formatting (stdout) 1`] = ` +"--import-formatting + + Formatting of import statements, may be \`oneline\` to avoid conflict with VSCode \\"Organize Imports\\" feature. + +Valid options: + + auto automatic formatting, like Prettier + oneline keep import statements on one line + +Default: auto +" +`; + +exports[`show detailed usage with --help import-formatting (write) 1`] = `Array []`; + +exports[`show detailed usage with --help indent-chains (stderr) 1`] = `""`; + +exports[`show detailed usage with --help indent-chains (stdout) 1`] = ` +"--indent-chains + + Put indents at the start of chained calls. + +Default: true +" +`; + +exports[`show detailed usage with --help indent-chains (write) 1`] = `Array []`; + exports[`show detailed usage with --help insert-pragma (stderr) 1`] = `""`; exports[`show detailed usage with --help insert-pragma (stdout) 1`] = ` @@ -303,17 +464,6 @@ Default: log exports[`show detailed usage with --help loglevel (write) 1`] = `Array []`; -exports[`show detailed usage with --help no-bracket-spacing (stderr) 1`] = `""`; - -exports[`show detailed usage with --help no-bracket-spacing (stdout) 1`] = ` -"--no-bracket-spacing - - Do not print spaces between brackets. -" -`; - -exports[`show detailed usage with --help no-bracket-spacing (write) 1`] = `Array []`; - exports[`show detailed usage with --help no-color (stderr) 1`] = `""`; exports[`show detailed usage with --help no-color (stdout) 1`] = ` @@ -358,6 +508,61 @@ exports[`show detailed usage with --help no-error-on-unmatched-pattern (stdout) exports[`show detailed usage with --help no-error-on-unmatched-pattern (write) 1`] = `Array []`; +exports[`show detailed usage with --help no-export-curly-spacing (stderr) 1`] = `""`; + +exports[`show detailed usage with --help no-export-curly-spacing (stdout) 1`] = ` +"--no-export-curly-spacing + + Disable spaces between export curly braces. +" +`; + +exports[`show detailed usage with --help no-export-curly-spacing (write) 1`] = `Array []`; + +exports[`show detailed usage with --help no-graphql-curly-spacing (stderr) 1`] = `""`; + +exports[`show detailed usage with --help no-graphql-curly-spacing (stdout) 1`] = ` +"--no-graphql-curly-spacing + + Do not put spaces between curly braces for GraphQL. +" +`; + +exports[`show detailed usage with --help no-graphql-curly-spacing (write) 1`] = `Array []`; + +exports[`show detailed usage with --help no-import-curly-spacing (stderr) 1`] = `""`; + +exports[`show detailed usage with --help no-import-curly-spacing (stdout) 1`] = ` +"--no-import-curly-spacing + + Disable spaces between import curly braces. +" +`; + +exports[`show detailed usage with --help no-import-curly-spacing (write) 1`] = `Array []`; + +exports[`show detailed usage with --help no-indent-chains (stderr) 1`] = `""`; + +exports[`show detailed usage with --help no-indent-chains (stdout) 1`] = ` +"--no-indent-chains + + Disable indents at the start of chained calls. +" +`; + +exports[`show detailed usage with --help no-indent-chains (write) 1`] = `Array []`; + +exports[`show detailed usage with --help no-object-curly-spacing (stderr) 1`] = `""`; + +exports[`show detailed usage with --help no-object-curly-spacing (stdout) 1`] = ` +"--no-object-curly-spacing + + Disable spaces between object curly braces. +" +`; + +exports[`show detailed usage with --help no-object-curly-spacing (write) 1`] = `Array []`; + exports[`show detailed usage with --help no-semi (stderr) 1`] = `""`; exports[`show detailed usage with --help no-semi (stdout) 1`] = ` @@ -369,6 +574,54 @@ exports[`show detailed usage with --help no-semi (stdout) 1`] = ` exports[`show detailed usage with --help no-semi (write) 1`] = `Array []`; +exports[`show detailed usage with --help no-type-curly-spacing (stderr) 1`] = `""`; + +exports[`show detailed usage with --help no-type-curly-spacing (stdout) 1`] = ` +"--no-type-curly-spacing + + Disable spaces between type curly braces. +" +`; + +exports[`show detailed usage with --help no-type-curly-spacing (write) 1`] = `Array []`; + +exports[`show detailed usage with --help no-yaml-bracket-spacing (stderr) 1`] = `""`; + +exports[`show detailed usage with --help no-yaml-bracket-spacing (stdout) 1`] = ` +"--no-yaml-bracket-spacing + + Do not put spaces between brackets / curly braces for YAML. +" +`; + +exports[`show detailed usage with --help no-yaml-bracket-spacing (write) 1`] = `Array []`; + +exports[`show detailed usage with --help object-curly-spacing (stderr) 1`] = `""`; + +exports[`show detailed usage with --help object-curly-spacing (stdout) 1`] = ` +"--object-curly-spacing + + Put spaces between object curly braces (similar to the corresponding eslint option). + +Default: true +" +`; + +exports[`show detailed usage with --help object-curly-spacing (write) 1`] = `Array []`; + +exports[`show detailed usage with --help offset-ternary-expressions (stderr) 1`] = `""`; + +exports[`show detailed usage with --help offset-ternary-expressions (stdout) 1`] = ` +"--offset-ternary-expressions + + Indent and align ternary expression branches more consistently with \\"Standard JS\\" (similar to the corresponding eslint option). + +Default: false +" +`; + +exports[`show detailed usage with --help offset-ternary-expressions (write) 1`] = `Array []`; + exports[`show detailed usage with --help parser (stderr) 1`] = `""`; exports[`show detailed usage with --help parser (stdout) 1`] = ` @@ -554,6 +807,45 @@ Default: false exports[`show detailed usage with --help single-quote (write) 1`] = `Array []`; +exports[`show detailed usage with --help space-before-function-paren (stderr) 1`] = `""`; + +exports[`show detailed usage with --help space-before-function-paren (stdout) 1`] = ` +"--space-before-function-paren + + Put a space before function parenthesis in all declarations (similar to the corresponding eslint option). (Default is to put a space before function parenthesis for untyped anonymous functions only.) + +Default: false +" +`; + +exports[`show detailed usage with --help space-before-function-paren (write) 1`] = `Array []`; + +exports[`show detailed usage with --help space-in-parens (stderr) 1`] = `""`; + +exports[`show detailed usage with --help space-in-parens (stdout) 1`] = ` +"--space-in-parens + + Print spaces in between parens, WordPress style (similar to the corresponding eslint option). Not recommended in combination with the default \`arrowParens: \\"always\\"\` option. Status: experimental, with limited testing. + +Default: false +" +`; + +exports[`show detailed usage with --help space-in-parens (write) 1`] = `Array []`; + +exports[`show detailed usage with --help space-unary-ops (stderr) 1`] = `""`; + +exports[`show detailed usage with --help space-unary-ops (stdout) 1`] = ` +"--space-unary-ops + + Put spaces after unary operator symbols, except in the middle of \`!!\` (similar to the corresponding eslint option). Status: experimental, with limited testing. + +Default: false +" +`; + +exports[`show detailed usage with --help space-unary-ops (write) 1`] = `Array []`; + exports[`show detailed usage with --help stdin-filepath (stderr) 1`] = `""`; exports[`show detailed usage with --help stdin-filepath (stdout) 1`] = ` @@ -589,6 +881,19 @@ Default: 2 exports[`show detailed usage with --help tab-width (write) 1`] = `Array []`; +exports[`show detailed usage with --help template-curly-spacing (stderr) 1`] = `""`; + +exports[`show detailed usage with --help template-curly-spacing (stdout) 1`] = ` +"--template-curly-spacing + + Put spaces between template curly brackets (similar to the corresponding eslint option). Status: experimental, with limited testing. + +Default: false +" +`; + +exports[`show detailed usage with --help template-curly-spacing (write) 1`] = `Array []`; + exports[`show detailed usage with --help trailing-comma (stderr) 1`] = `""`; exports[`show detailed usage with --help trailing-comma (stdout) 1`] = ` @@ -608,6 +913,45 @@ Default: es5 exports[`show detailed usage with --help trailing-comma (write) 1`] = `Array []`; +exports[`show detailed usage with --help type-angle-bracket-spacing (stderr) 1`] = `""`; + +exports[`show detailed usage with --help type-angle-bracket-spacing (stdout) 1`] = ` +"--type-angle-bracket-spacing + + Put spaces between type angle brackets. Status: experimental, with limited testing. + +Default: false +" +`; + +exports[`show detailed usage with --help type-angle-bracket-spacing (write) 1`] = `Array []`; + +exports[`show detailed usage with --help type-bracket-spacing (stderr) 1`] = `""`; + +exports[`show detailed usage with --help type-bracket-spacing (stdout) 1`] = ` +"--type-bracket-spacing + + Print spaces between type brackets. Status: experimental, with limited testing. + +Default: false +" +`; + +exports[`show detailed usage with --help type-bracket-spacing (write) 1`] = `Array []`; + +exports[`show detailed usage with --help type-curly-spacing (stderr) 1`] = `""`; + +exports[`show detailed usage with --help type-curly-spacing (stdout) 1`] = ` +"--type-curly-spacing + + Put spaces between type curly braces. + +Default: true +" +`; + +exports[`show detailed usage with --help type-curly-spacing (write) 1`] = `Array []`; + exports[`show detailed usage with --help use-tabs (stderr) 1`] = `""`; exports[`show detailed usage with --help use-tabs (stdout) 1`] = ` @@ -666,3 +1010,29 @@ exports[`show detailed usage with --help write (stdout) 1`] = ` `; exports[`show detailed usage with --help write (write) 1`] = `Array []`; + +exports[`show detailed usage with --help yaml-bracket-spacing (stderr) 1`] = `""`; + +exports[`show detailed usage with --help yaml-bracket-spacing (stdout) 1`] = ` +"--yaml-bracket-spacing + + Put spaces between brackets / curly braces for YAML. + +Default: true +" +`; + +exports[`show detailed usage with --help yaml-bracket-spacing (write) 1`] = `Array []`; + +exports[`show detailed usage with --help yield-star-spacing (stderr) 1`] = `""`; + +exports[`show detailed usage with --help yield-star-spacing (stdout) 1`] = ` +"--yield-star-spacing + + Put spaces around the star (\`*\`) in \`yield*\` expressions (before and after - similar to the corresponding eslint option). (Default is after only.) + +Default: false +" +`; + +exports[`show detailed usage with --help yield-star-spacing (write) 1`] = `Array []`; diff --git a/tests/integration/__tests__/__snapshots__/plugin-options-string.js.snap b/tests/integration/__tests__/__snapshots__/plugin-options-string.js.snap index 2ed7ae8b69..fddf87024a 100644 --- a/tests/integration/__tests__/__snapshots__/plugin-options-string.js.snap +++ b/tests/integration/__tests__/__snapshots__/plugin-options-string.js.snap @@ -18,20 +18,24 @@ exports[`show external options with \`--help\` 1`] = ` - First value + Second value -@@ -20,18 +20,20 @@ - Control how Prettier formats quoted code embedded in the file. - Defaults to auto. +@@ -36,10 +36,12 @@ --end-of-line Which end of line characters to apply. Defaults to lf. + --no-export-curly-spacing + Disable spaces between export curly braces. + --foo-string foo description + Defaults to bar. - --html-whitespace-sensitivity - How to handle whitespaces in HTML. - Defaults to css. - --jsx-bracket-same-line Put > on the last line instead of at a new line. + --generator-star-spacing Put spaces around the star (\`*\`) in generator functions (before and after - similar to the corresponding eslint option). (Default is after only.) Defaults to false. - --jsx-single-quote Use single quotes in JSX. + --no-graphql-curly-spacing + Do not put spaces between curly braces for GraphQL. + --html-void-tags Format void HTML elements as void tags. +@@ -60,11 +62,11 @@ + --no-object-curly-spacing + Disable spaces between object curly braces. + --offset-ternary-expressions + Indent and align ternary expression branches more consistently with \\"Standard JS\\" (similar to the corresponding eslint option). Defaults to false. - --parser + --parser diff --git a/tests/integration/__tests__/__snapshots__/plugin-options.js.snap b/tests/integration/__tests__/__snapshots__/plugin-options.js.snap index 276c950e74..3b61f6b6da 100644 --- a/tests/integration/__tests__/__snapshots__/plugin-options.js.snap +++ b/tests/integration/__tests__/__snapshots__/plugin-options.js.snap @@ -60,20 +60,24 @@ exports[`show external options with \`--help\` 1`] = ` - First value + Second value -@@ -20,18 +20,20 @@ - Control how Prettier formats quoted code embedded in the file. - Defaults to auto. +@@ -36,10 +36,12 @@ --end-of-line Which end of line characters to apply. Defaults to lf. + --no-export-curly-spacing + Disable spaces between export curly braces. + --foo-option foo description + Defaults to bar. - --html-whitespace-sensitivity - How to handle whitespaces in HTML. - Defaults to css. - --jsx-bracket-same-line Put > on the last line instead of at a new line. + --generator-star-spacing Put spaces around the star (\`*\`) in generator functions (before and after - similar to the corresponding eslint option). (Default is after only.) Defaults to false. - --jsx-single-quote Use single quotes in JSX. + --no-graphql-curly-spacing + Do not put spaces between curly braces for GraphQL. + --html-void-tags Format void HTML elements as void tags. +@@ -60,11 +62,11 @@ + --no-object-curly-spacing + Disable spaces between object curly braces. + --offset-ternary-expressions + Indent and align ternary expression branches more consistently with \\"Standard JS\\" (similar to the corresponding eslint option). Defaults to false. - --parser + --parser diff --git a/tests/integration/__tests__/__snapshots__/schema.js.snap b/tests/integration/__tests__/__snapshots__/schema.js.snap index 9ff9127181..6cb69bdffc 100644 --- a/tests/integration/__tests__/__snapshots__/schema.js.snap +++ b/tests/integration/__tests__/__snapshots__/schema.js.snap @@ -6,6 +6,16 @@ Object { "definitions": Object { "optionsDefinition": Object { "properties": Object { + "alignObjectProperties": Object { + "default": false, + "description": "Align colons in multiline object literals.", + "type": "boolean", + }, + "arrayBracketSpacing": Object { + "default": false, + "description": "Put spaces between array brackets (similar to the corresponding eslint option). Status: experimental, with limited testing.", + "type": "boolean", + }, "arrowParens": Object { "default": "always", "description": "Include parentheses around a sole arrow function parameter.", @@ -24,9 +34,24 @@ Object { }, ], }, - "bracketSpacing": Object { - "default": true, - "description": "Print spaces between brackets.", + "breakBeforeElse": Object { + "default": false, + "description": "Always add a line break before else.", + "type": "boolean", + }, + "breakLongMethodChains": Object { + "default": false, + "description": "Break method chains with more than 3 method calls, like Prettier 1.x.", + "type": "boolean", + }, + "computedPropertySpacing": Object { + "default": false, + "description": "Put spaces between computed property brackets (similar to the corresponding eslint option). Status: experimental, with limited testing.", + "type": "boolean", + }, + "cssParenSpacing": Object { + "default": false, + "description": "Print spaces between parens in CSS, WordPress style. Status: experimental, with limited testing.", "type": "boolean", }, "cursorOffset": Object { @@ -84,11 +109,31 @@ This option cannot be used with --range-start and --range-end.", }, ], }, + "exportCurlySpacing": Object { + "default": true, + "description": "Put spaces between export curly braces.", + "type": "boolean", + }, "filepath": Object { "default": undefined, "description": "Specify the input filepath. This will be used to do parser inference.", "type": "string", }, + "generatorStarSpacing": Object { + "default": false, + "description": "Put spaces around the star (\`*\`) in generator functions (before and after - similar to the corresponding eslint option). (Default is after only.)", + "type": "boolean", + }, + "graphqlCurlySpacing": Object { + "default": true, + "description": "Put spaces between curly braces for GraphQL.", + "type": "boolean", + }, + "htmlVoidTags": Object { + "default": false, + "description": "Format void HTML elements as void tags.", + "type": "boolean", + }, "htmlWhitespaceSensitivity": Object { "default": "css", "description": "How to handle whitespaces in HTML.", @@ -113,6 +158,34 @@ This option cannot be used with --range-start and --range-end.", }, ], }, + "importCurlySpacing": Object { + "default": true, + "description": "Put spaces between import curly braces.", + "type": "boolean", + }, + "importFormatting": Object { + "default": "auto", + "description": "Formatting of import statements, may be \`oneline\` to avoid conflict with VSCode \\"Organize Imports\\" feature.", + "oneOf": Array [ + Object { + "description": "automatic formatting, like Prettier", + "enum": Array [ + "auto", + ], + }, + Object { + "description": "keep import statements on one line", + "enum": Array [ + "oneline", + ], + }, + ], + }, + "indentChains": Object { + "default": true, + "description": "Put indents at the start of chained calls.", + "type": "boolean", + }, "insertPragma": Object { "default": false, "description": "Insert @format pragma into file's first docblock comment.", @@ -128,6 +201,16 @@ This option cannot be used with --range-start and --range-end.", "description": "Use single quotes in JSX.", "type": "boolean", }, + "objectCurlySpacing": Object { + "default": true, + "description": "Put spaces between object curly braces (similar to the corresponding eslint option).", + "type": "boolean", + }, + "offsetTernaryExpressions": Object { + "default": false, + "description": "Indent and align ternary expression branches more consistently with \\"Standard JS\\" (similar to the corresponding eslint option).", + "type": "boolean", + }, "parser": Object { "default": undefined, "description": "Which parser to use.", @@ -367,11 +450,31 @@ in order for it to be formatted.", "description": "Use single quotes instead of double quotes.", "type": "boolean", }, + "spaceBeforeFunctionParen": Object { + "default": false, + "description": "Put a space before function parenthesis in all declarations (similar to the corresponding eslint option). (Default is to put a space before function parenthesis for untyped anonymous functions only.)", + "type": "boolean", + }, + "spaceInParens": Object { + "default": false, + "description": "Print spaces in between parens, WordPress style (similar to the corresponding eslint option). Not recommended in combination with the default \`arrowParens: \\"always\\"\` option. Status: experimental, with limited testing.", + "type": "boolean", + }, + "spaceUnaryOps": Object { + "default": false, + "description": "Put spaces after unary operator symbols, except in the middle of \`!!\` (similar to the corresponding eslint option). Status: experimental, with limited testing.", + "type": "boolean", + }, "tabWidth": Object { "default": 2, "description": "Number of spaces per indentation level.", "type": "integer", }, + "templateCurlySpacing": Object { + "default": false, + "description": "Put spaces between template curly brackets (similar to the corresponding eslint option). Status: experimental, with limited testing.", + "type": "boolean", + }, "trailingComma": Object { "default": "es5", "description": "Print trailing commas wherever possible when multi-line.", @@ -396,6 +499,21 @@ in order for it to be formatted.", }, ], }, + "typeAngleBracketSpacing": Object { + "default": false, + "description": "Put spaces between type angle brackets. Status: experimental, with limited testing.", + "type": "boolean", + }, + "typeBracketSpacing": Object { + "default": false, + "description": "Print spaces between type brackets. Status: experimental, with limited testing.", + "type": "boolean", + }, + "typeCurlySpacing": Object { + "default": true, + "description": "Put spaces between type curly braces.", + "type": "boolean", + }, "useTabs": Object { "default": false, "description": "Indent with tabs instead of spaces.", @@ -406,6 +524,16 @@ in order for it to be formatted.", "description": "Indent script and style tags in Vue files.", "type": "boolean", }, + "yamlBracketSpacing": Object { + "default": true, + "description": "Put spaces between brackets / curly braces for YAML.", + "type": "boolean", + }, + "yieldStarSpacing": Object { + "default": false, + "description": "Put spaces around the star (\`*\`) in \`yield*\` expressions (before and after - similar to the corresponding eslint option). (Default is after only.)", + "type": "boolean", + }, }, "type": "object", }, diff --git a/tests/integration/__tests__/__snapshots__/support-info.js.snap b/tests/integration/__tests__/__snapshots__/support-info.js.snap index 6d63cd85a9..b811510acf 100644 --- a/tests/integration/__tests__/__snapshots__/support-info.js.snap +++ b/tests/integration/__tests__/__snapshots__/support-info.js.snap @@ -10,8 +10,8 @@ Object { "css", ], "Flow": Array [ - "flow", "babel-flow", + "flow", ], "GraphQL": Array [ "graphql", @@ -71,12 +71,12 @@ Object { "scss", ], "TSX": Array [ - "typescript", "babel-ts", + "typescript", ], "TypeScript": Array [ - "typescript", "babel-ts", + "typescript", ], "Vue": Array [ "vue", @@ -86,6 +86,14 @@ Object { ], }, "options": Object { + "alignObjectProperties": Object { + "default": false, + "type": "boolean", + }, + "arrayBracketSpacing": Object { + "default": false, + "type": "boolean", + }, "arrowParens": Object { "choices": Array [ "always", @@ -94,8 +102,20 @@ Object { "default": "always", "type": "choice", }, - "bracketSpacing": Object { - "default": true, + "breakBeforeElse": Object { + "default": false, + "type": "boolean", + }, + "breakLongMethodChains": Object { + "default": false, + "type": "boolean", + }, + "computedPropertySpacing": Object { + "default": false, + "type": "boolean", + }, + "cssParenSpacing": Object { + "default": false, "type": "boolean", }, "cursorOffset": Object { @@ -125,10 +145,26 @@ Object { "default": "lf", "type": "choice", }, + "exportCurlySpacing": Object { + "default": true, + "type": "boolean", + }, "filepath": Object { "default": undefined, "type": "path", }, + "generatorStarSpacing": Object { + "default": false, + "type": "boolean", + }, + "graphqlCurlySpacing": Object { + "default": true, + "type": "boolean", + }, + "htmlVoidTags": Object { + "default": false, + "type": "boolean", + }, "htmlWhitespaceSensitivity": Object { "choices": Array [ "css", @@ -138,6 +174,22 @@ Object { "default": "css", "type": "choice", }, + "importCurlySpacing": Object { + "default": true, + "type": "boolean", + }, + "importFormatting": Object { + "choices": Array [ + "auto", + "oneline", + ], + "default": "auto", + "type": "choice", + }, + "indentChains": Object { + "default": true, + "type": "boolean", + }, "insertPragma": Object { "default": false, "type": "boolean", @@ -150,6 +202,14 @@ Object { "default": false, "type": "boolean", }, + "objectCurlySpacing": Object { + "default": true, + "type": "boolean", + }, + "offsetTernaryExpressions": Object { + "default": false, + "type": "boolean", + }, "parser": Object { "choices": Array [ "flow", @@ -243,6 +303,18 @@ Object { "default": false, "type": "boolean", }, + "spaceBeforeFunctionParen": Object { + "default": false, + "type": "boolean", + }, + "spaceInParens": Object { + "default": false, + "type": "boolean", + }, + "spaceUnaryOps": Object { + "default": false, + "type": "boolean", + }, "tabWidth": Object { "default": 2, "range": Object { @@ -252,6 +324,10 @@ Object { }, "type": "int", }, + "templateCurlySpacing": Object { + "default": false, + "type": "boolean", + }, "trailingComma": Object { "choices": Array [ "es5", @@ -261,6 +337,18 @@ Object { "default": "es5", "type": "choice", }, + "typeAngleBracketSpacing": Object { + "default": false, + "type": "boolean", + }, + "typeBracketSpacing": Object { + "default": false, + "type": "boolean", + }, + "typeCurlySpacing": Object { + "default": true, + "type": "boolean", + }, "useTabs": Object { "default": false, "type": "boolean", @@ -269,6 +357,14 @@ Object { "default": false, "type": "boolean", }, + "yamlBracketSpacing": Object { + "default": true, + "type": "boolean", + }, + "yieldStarSpacing": Object { + "default": false, + "type": "boolean", + }, }, } `; @@ -359,7 +455,7 @@ exports[`CLI --support-info (stdout) 1`] = ` ], \\"linguistLanguageId\\": 183, \\"name\\": \\"Flow\\", - \\"parsers\\": [\\"flow\\", \\"babel-flow\\"], + \\"parsers\\": [\\"babel-flow\\", \\"flow\\"], \\"since\\": \\"0.0.0\\", \\"tmScope\\": \\"source.js\\", \\"type\\": \\"programming\\", @@ -397,7 +493,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"interpreters\\": [\\"deno\\", \\"ts-node\\"], \\"linguistLanguageId\\": 378, \\"name\\": \\"TypeScript\\", - \\"parsers\\": [\\"typescript\\", \\"babel-ts\\"], + \\"parsers\\": [\\"babel-ts\\", \\"typescript\\"], \\"since\\": \\"1.4.0\\", \\"tmScope\\": \\"source.ts\\", \\"type\\": \\"programming\\", @@ -411,7 +507,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"group\\": \\"TypeScript\\", \\"linguistLanguageId\\": 94901924, \\"name\\": \\"TSX\\", - \\"parsers\\": [\\"typescript\\", \\"babel-ts\\"], + \\"parsers\\": [\\"babel-ts\\", \\"typescript\\"], \\"since\\": \\"1.4.0\\", \\"tmScope\\": \\"source.tsx\\", \\"type\\": \\"programming\\", @@ -455,6 +551,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"filenames\\": [ \\".arcconfig\\", \\".htmlhintrc\\", + \\".imgbotconfig\\", \\".tern-config\\", \\".tern-project\\", \\".watchmanconfig\\", @@ -497,6 +594,7 @@ exports[`CLI --support-info (stdout) 1`] = ` \\".jscsrc\\", \\".jshintrc\\", \\".jslintrc\\", + \\"api-extractor.json\\", \\"devcontainer.json\\", \\"jsconfig.json\\", \\"language-configuration.json\\", @@ -707,7 +805,7 @@ exports[`CLI --support-info (stdout) 1`] = ` }, { \\"aceMode\\": \\"html\\", - \\"color\\": \\"#2c3e50\\", + \\"color\\": \\"#41b883\\", \\"extensions\\": [\\".vue\\"], \\"linguistLanguageId\\": 391, \\"name\\": \\"Vue\\", @@ -752,6 +850,22 @@ exports[`CLI --support-info (stdout) 1`] = ` } ], \\"options\\": [ + { + \\"category\\": \\"JavaScript\\", + \\"default\\": false, + \\"description\\": \\"Align colons in multiline object literals.\\", + \\"name\\": \\"alignObjectProperties\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, + { + \\"category\\": \\"JavaScript\\", + \\"default\\": false, + \\"description\\": \\"Put spaces between array brackets (similar to the corresponding eslint option). Status: experimental, with limited testing.\\", + \\"name\\": \\"arrayBracketSpacing\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, { \\"category\\": \\"JavaScript\\", \\"choices\\": [ @@ -772,13 +886,35 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"type\\": \\"choice\\" }, { - \\"category\\": \\"Common\\", - \\"default\\": true, - \\"description\\": \\"Print spaces between brackets.\\", - \\"name\\": \\"bracketSpacing\\", - \\"oppositeDescription\\": \\"Do not print spaces between brackets.\\", + \\"category\\": \\"JavaScript\\", + \\"default\\": false, + \\"description\\": \\"Always add a line break before else.\\", + \\"name\\": \\"breakBeforeElse\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, + { + \\"category\\": \\"JavaScript\\", + \\"default\\": false, + \\"description\\": \\"Break method chains with more than 3 method calls, like Prettier 1.x.\\", + \\"name\\": \\"breakLongMethodChains\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, + { + \\"category\\": \\"JavaScript\\", + \\"default\\": false, + \\"description\\": \\"Put spaces between computed property brackets (similar to the corresponding eslint option). Status: experimental, with limited testing.\\", + \\"name\\": \\"computedPropertySpacing\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, + { + \\"category\\": \\"Other\\", + \\"default\\": false, + \\"description\\": \\"Print spaces between parens in CSS, WordPress style. Status: experimental, with limited testing.\\", + \\"name\\": \\"cssParenSpacing\\", \\"pluginDefaults\\": {}, - \\"since\\": \\"0.0.0\\", \\"type\\": \\"boolean\\" }, { @@ -837,6 +973,15 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"since\\": \\"1.15.0\\", \\"type\\": \\"choice\\" }, + { + \\"category\\": \\"JavaScript\\", + \\"default\\": true, + \\"description\\": \\"Put spaces between export curly braces.\\", + \\"name\\": \\"exportCurlySpacing\\", + \\"oppositeDescription\\": \\"Disable spaces between export curly braces.\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, { \\"category\\": \\"Special\\", \\"description\\": \\"Specify the input filepath. This will be used to do parser inference.\\", @@ -845,6 +990,31 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"since\\": \\"1.4.0\\", \\"type\\": \\"path\\" }, + { + \\"category\\": \\"JavaScript\\", + \\"default\\": false, + \\"description\\": \\"Put spaces around the star (\`*\`) in generator functions (before and after - similar to the corresponding eslint option). (Default is after only.)\\", + \\"name\\": \\"generatorStarSpacing\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, + { + \\"category\\": \\"Other\\", + \\"default\\": true, + \\"description\\": \\"Put spaces between curly braces for GraphQL.\\", + \\"name\\": \\"graphqlCurlySpacing\\", + \\"oppositeDescription\\": \\"Do not put spaces between curly braces for GraphQL.\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, + { + \\"category\\": \\"HTML\\", + \\"default\\": false, + \\"description\\": \\"Format void HTML elements as void tags.\\", + \\"name\\": \\"htmlVoidTags\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, { \\"category\\": \\"HTML\\", \\"choices\\": [ @@ -868,6 +1038,42 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"since\\": \\"1.15.0\\", \\"type\\": \\"choice\\" }, + { + \\"category\\": \\"JavaScript\\", + \\"default\\": true, + \\"description\\": \\"Put spaces between import curly braces.\\", + \\"name\\": \\"importCurlySpacing\\", + \\"oppositeDescription\\": \\"Disable spaces between import curly braces.\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, + { + \\"category\\": \\"JavaScript\\", + \\"choices\\": [ + { + \\"description\\": \\"automatic formatting, like Prettier\\", + \\"value\\": \\"auto\\" + }, + { + \\"description\\": \\"keep import statements on one line\\", + \\"value\\": \\"oneline\\" + } + ], + \\"default\\": \\"auto\\", + \\"description\\": \\"Formatting of import statements, may be \`oneline\` to avoid conflict with VSCode \\\\\\"Organize Imports\\\\\\" feature.\\", + \\"name\\": \\"importFormatting\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"choice\\" + }, + { + \\"category\\": \\"JavaScript\\", + \\"default\\": true, + \\"description\\": \\"Put indents at the start of chained calls.\\", + \\"name\\": \\"indentChains\\", + \\"oppositeDescription\\": \\"Disable indents at the start of chained calls.\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, { \\"category\\": \\"Special\\", \\"default\\": false, @@ -895,6 +1101,23 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"since\\": \\"1.15.0\\", \\"type\\": \\"boolean\\" }, + { + \\"category\\": \\"JavaScript\\", + \\"default\\": true, + \\"description\\": \\"Put spaces between object curly braces (similar to the corresponding eslint option).\\", + \\"name\\": \\"objectCurlySpacing\\", + \\"oppositeDescription\\": \\"Disable spaces between object curly braces.\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, + { + \\"category\\": \\"JavaScript\\", + \\"default\\": false, + \\"description\\": \\"Indent and align ternary expression branches more consistently with \\\\\\"Standard JS\\\\\\" (similar to the corresponding eslint option).\\", + \\"name\\": \\"offsetTernaryExpressions\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, { \\"category\\": \\"Global\\", \\"choices\\": [ @@ -1070,6 +1293,30 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"since\\": \\"0.0.0\\", \\"type\\": \\"boolean\\" }, + { + \\"category\\": \\"JavaScript\\", + \\"default\\": false, + \\"description\\": \\"Put a space before function parenthesis in all declarations (similar to the corresponding eslint option). (Default is to put a space before function parenthesis for untyped anonymous functions only.)\\", + \\"name\\": \\"spaceBeforeFunctionParen\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, + { + \\"category\\": \\"JavaScript\\", + \\"default\\": false, + \\"description\\": \\"Print spaces in between parens, WordPress style (similar to the corresponding eslint option). Not recommended in combination with the default \`arrowParens: \\\\\\"always\\\\\\"\` option. Status: experimental, with limited testing.\\", + \\"name\\": \\"spaceInParens\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, + { + \\"category\\": \\"JavaScript\\", + \\"default\\": false, + \\"description\\": \\"Put spaces after unary operator symbols, except in the middle of \`!!\` (similar to the corresponding eslint option). Status: experimental, with limited testing.\\", + \\"name\\": \\"spaceUnaryOps\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, { \\"category\\": \\"Global\\", \\"default\\": 2, @@ -1079,6 +1326,14 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"range\\": { \\"end\\": null, \\"start\\": 0, \\"step\\": 1 }, \\"type\\": \\"int\\" }, + { + \\"category\\": \\"JavaScript\\", + \\"default\\": false, + \\"description\\": \\"Put spaces between template curly brackets (similar to the corresponding eslint option). Status: experimental, with limited testing.\\", + \\"name\\": \\"templateCurlySpacing\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, { \\"category\\": \\"JavaScript\\", \\"choices\\": [ @@ -1099,6 +1354,31 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"since\\": \\"0.0.0\\", \\"type\\": \\"choice\\" }, + { + \\"category\\": \\"JavaScript\\", + \\"default\\": false, + \\"description\\": \\"Put spaces between type angle brackets. Status: experimental, with limited testing.\\", + \\"name\\": \\"typeAngleBracketSpacing\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, + { + \\"category\\": \\"JavaScript\\", + \\"default\\": false, + \\"description\\": \\"Print spaces between type brackets. Status: experimental, with limited testing.\\", + \\"name\\": \\"typeBracketSpacing\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, + { + \\"category\\": \\"JavaScript\\", + \\"default\\": true, + \\"description\\": \\"Put spaces between type curly braces.\\", + \\"name\\": \\"typeCurlySpacing\\", + \\"oppositeDescription\\": \\"Disable spaces between type curly braces.\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, { \\"category\\": \\"Global\\", \\"default\\": false, @@ -1116,6 +1396,23 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"pluginDefaults\\": {}, \\"since\\": \\"1.19.0\\", \\"type\\": \\"boolean\\" + }, + { + \\"category\\": \\"Other\\", + \\"default\\": true, + \\"description\\": \\"Put spaces between brackets / curly braces for YAML.\\", + \\"name\\": \\"yamlBracketSpacing\\", + \\"oppositeDescription\\": \\"Do not put spaces between brackets / curly braces for YAML.\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" + }, + { + \\"category\\": \\"JavaScript\\", + \\"default\\": false, + \\"description\\": \\"Put spaces around the star (\`*\`) in \`yield*\` expressions (before and after - similar to the corresponding eslint option). (Default is after only.)\\", + \\"name\\": \\"yieldStarSpacing\\", + \\"pluginDefaults\\": {}, + \\"type\\": \\"boolean\\" } ] } diff --git a/tests/integration/__tests__/bundle.js b/tests/integration/__tests__/bundle.js index 3980925c0e..2138bb81fb 100644 --- a/tests/integration/__tests__/bundle.js +++ b/tests/integration/__tests__/bundle.js @@ -17,8 +17,10 @@ describe("standalone", () => { .sync(["parser-*.js"], { cwd: distDirectory, absolute: true }) .map((file) => require(file)); - const esmStandalone = require(path.join(distDirectory, "esm/standalone.mjs")) - .default; + const esmStandalone = require(path.join( + distDirectory, + "esm/standalone.mjs" + )).default; const esmPlugins = globby .sync(["esm/parser-*.mjs"], { cwd: distDirectory, absolute: true }) .map((file) => require(file).default); diff --git a/tests/integration/__tests__/doc-builders.js b/tests/integration/__tests__/doc-builders.js index 47f25516f5..8e1303a19b 100644 --- a/tests/integration/__tests__/doc-builders.js +++ b/tests/integration/__tests__/doc-builders.js @@ -53,6 +53,7 @@ describe("doc builders", () => { "group", group(concat(["1"])), { + addedLine: false, type: "group", id: undefined, contents: { type: "concat", parts: ["1"] }, @@ -64,6 +65,7 @@ describe("doc builders", () => { "group (array)", group(["1"]), { + addedLine: false, type: "group", id: undefined, contents: ["1"], diff --git a/tests/integration/__tests__/early-exit.js b/tests/integration/__tests__/early-exit.js index c9d068becd..c5375f1ed7 100644 --- a/tests/integration/__tests__/early-exit.js +++ b/tests/integration/__tests__/early-exit.js @@ -2,6 +2,7 @@ const prettier = require("prettier-local"); const runPrettier = require("../runPrettier"); +const { isProduction } = require("../env"); describe("show version with --version", () => { runPrettier("cli/with-shebang", ["--version"]).test({ @@ -99,12 +100,14 @@ test("node version error", async () => { writable: false, }); const result = runPrettier("cli", ["--help"]); - expect(await result.status).toEqual(1); - const snapshot = {}; - for (const name of ["stderr", "stdout", "write"]) { - snapshot[name] = await result[name]; - } - expect(snapshot).toMatchSnapshot(); + expect(await result.status).toBe(1); + expect(await result.stderr).toBe( + `prettierx requires at least version ${ + isProduction ? "10.13.0" : "12.17.0" + } of Node, please upgrade\n` + ); + expect(await result.stdout).toBe(""); + expect(await result.write).toEqual([]); } finally { Object.defineProperty(process, "version", { value: originalProcessVersion, diff --git a/tests/integration/__tests__/format.js b/tests/integration/__tests__/format.js index 6a83e86e6c..dba985a88d 100644 --- a/tests/integration/__tests__/format.js +++ b/tests/integration/__tests__/format.js @@ -56,7 +56,8 @@ test("should work with foo plugin instance", () => { prettier.format(input, { parser: "foo-parser", plugins: [fooPlugin] }) ) ).toMatchInlineSnapshot( - '"\\"{\\\\\\"tabWidth\\\\\\":8,\\\\\\"bracketSpacing\\\\\\":false}\\""' + // [prettierx]: broken-out bracket spacing options + '"\\"{\\\\\\"tabWidth\\\\\\":8,\\\\\\"objectCurlySpacing\\\\\\":false}\\""' ); }); diff --git a/tests/integration/__tests__/infer-parser.js b/tests/integration/__tests__/infer-parser.js index 5e27a6b09f..88ea300659 100644 --- a/tests/integration/__tests__/infer-parser.js +++ b/tests/integration/__tests__/infer-parser.js @@ -163,11 +163,9 @@ describe("--write and --list-different with unknown path and no parser", () => { }); describe("multiple files", () => { - runPrettier("cli/infer-parser/", [ - "--list-different", - "--write", - "*", - ]).test({ status: 0 }); + runPrettier("cli/infer-parser/", ["--list-different", "--write", "*"]).test( + { status: 0 } + ); }); }); diff --git a/tests/integration/__tests__/line-suffix-boundary.js b/tests/integration/__tests__/line-suffix-boundary.js index a420c561f8..8622a9bce9 100644 --- a/tests/integration/__tests__/line-suffix-boundary.js +++ b/tests/integration/__tests__/line-suffix-boundary.js @@ -3,14 +3,8 @@ /** @type {import('prettier')} */ const prettier = require("prettier-local"); -const { - group, - indent, - line, - lineSuffix, - lineSuffixBoundary, - softline, -} = prettier.doc.builders; +const { group, indent, line, lineSuffix, lineSuffixBoundary, softline } = + prettier.doc.builders; const printDoc = require("../printDoc"); diff --git a/tests/integration/__tests__/plugin-default-options.js b/tests/integration/__tests__/plugin-default-options.js index b0a3f24b9f..bfc44e6dbb 100644 --- a/tests/integration/__tests__/plugin-default-options.js +++ b/tests/integration/__tests__/plugin-default-options.js @@ -15,7 +15,8 @@ describe("plugin default options should work", () => { ).test({ stdout: JSON.stringify({ tabWidth: 8, - bracketSpacing: false, + // [prettierx]: broken-out bracket spacing options + objectCurlySpacing: false, }), stderr: "", status: 0, @@ -31,7 +32,8 @@ describe("overriding plugin default options should work", () => { ).test({ stdout: JSON.stringify({ tabWidth: 4, - bracketSpacing: false, + // [prettierx]: broken-out bracket spacing options + objectCurlySpacing: false, }), stderr: "", status: 0, diff --git a/tests/integration/__tests__/support-info.js b/tests/integration/__tests__/support-info.js index 9b211902f1..3886c1f33d 100644 --- a/tests/integration/__tests__/support-info.js +++ b/tests/integration/__tests__/support-info.js @@ -13,13 +13,14 @@ describe("CLI --support-info", () => { function getCoreInfo() { const supportInfo = prettier.getSupportInfo(); - const languages = supportInfo.languages.reduce( - (obj, language) => ({ [language.name]: language.parsers, ...obj }), - {} + const languages = Object.fromEntries( + supportInfo.languages.map(({ name, parsers }) => [name, parsers]) ); - const options = supportInfo.options.reduce( - (obj, option) => ({ - [option.name]: { + + const options = Object.fromEntries( + supportInfo.options.map((option) => [ + option.name, + { type: option.type, default: option.default, ...(option.type === "int" @@ -28,9 +29,8 @@ function getCoreInfo() { ? { choices: option.choices.map((choice) => choice.value) } : null), }, - ...obj, - }), - {} + ]) ); + return { languages, options }; } diff --git a/tests/integration/env.js b/tests/integration/env.js index 6d3eb472c2..a6ae39fd90 100644 --- a/tests/integration/env.js +++ b/tests/integration/env.js @@ -2,16 +2,18 @@ const path = require("path"); const isProduction = process.env.NODE_ENV === "production"; -const { PRETTIER_DIR } = process.env; -const { bin } = require(path.join(PRETTIER_DIR, "package.json")); +// [prettierx] +const { PRETTIERX_DIR } = process.env; +const { bin } = require(path.join(PRETTIERX_DIR, "package.json")); const prettierCli = path.join( - PRETTIER_DIR, - typeof bin === "object" ? bin.prettier : bin + PRETTIERX_DIR, + typeof bin === "object" ? bin.prettierx : bin ); +// [prettierx] const thirdParty = isProduction - ? path.join(PRETTIER_DIR, "./third-party") - : path.join(PRETTIER_DIR, "./src/common/third-party"); + ? path.join(PRETTIERX_DIR, "./third-party") + : path.join(PRETTIERX_DIR, "./src/common/third-party"); const projectRoot = path.join(__dirname, "../.."); diff --git a/tests/integration/plugins/defaultOptions/plugin.js b/tests/integration/plugins/defaultOptions/plugin.js index 1c72441cc2..a3d32e9b9f 100644 --- a/tests/integration/plugins/defaultOptions/plugin.js +++ b/tests/integration/plugins/defaultOptions/plugin.js @@ -10,7 +10,8 @@ module.exports = { ], defaultOptions: { tabWidth: 8, - bracketSpacing: false + // [prettierx]: broken-out bracket spacing options + objectCurlySpacing: false }, parsers: { "foo-parser": { @@ -23,7 +24,8 @@ module.exports = { print: (path, options) => JSON.stringify({ tabWidth: options.tabWidth, - bracketSpacing: options.bracketSpacing + // [prettierx]: broken-out bracket spacing options + objectCurlySpacing: options.objectCurlySpacing }) } } diff --git a/tests/integration/runPrettier.js b/tests/integration/runPrettier.js index d8edb2773e..6c510df52a 100644 --- a/tests/integration/runPrettier.js +++ b/tests/integration/runPrettier.js @@ -3,7 +3,6 @@ const fs = require("fs"); const path = require("path"); const stripAnsi = require("strip-ansi"); -const { SynchronousPromise } = require("synchronous-promise"); const { prettierCli, thirdParty } = require("./env"); async function run(dir, args, options) { @@ -43,18 +42,28 @@ async function run(dir, args, options) { const write = []; - jest.spyOn(fs, "writeFileSync").mockImplementation((filename, content) => { - write.push({ filename, content }); - }); - - const origStatSync = fs.statSync; - - jest.spyOn(fs, "statSync").mockImplementation((filename) => { - if (path.basename(filename) === "virtualDirectory") { - return origStatSync(path.join(__dirname, __filename)); - } - return origStatSync(filename); - }); + jest + .spyOn(fs.promises, "writeFile") + .mockImplementation(async (filename, content) => { + write.push({ filename, content }); + }); + + /* + A fake non-existing directory to test plugin search won't crash. + + See: + - `isDirectory` function in `src/common/load-plugins.js` + - Test file `./__tests__/plugin-virtual-directory.js` + - Pull request #5819 + */ + const originalStatSync = fs.statSync; + jest + .spyOn(fs, "statSync") + .mockImplementation((filename) => + originalStatSync( + path.basename(filename) === "virtualDirectory" ? __filename : filename + ) + ); const originalCwd = process.cwd(); const originalArgv = process.argv; @@ -74,7 +83,7 @@ async function run(dir, args, options) { // "get-stream" module to mock. jest .spyOn(require(thirdParty), "getStdin") - .mockImplementation(() => SynchronousPromise.resolve(options.input || "")); + .mockImplementation(async () => options.input || ""); jest .spyOn(require(thirdParty), "isCI") .mockImplementation(() => Boolean(options.ci)); diff --git a/website/README.md b/website/README.md index 1be538cade..a410312cb5 100644 --- a/website/README.md +++ b/website/README.md @@ -57,7 +57,6 @@ previous: doc0 # previous doc on sidebar for navigation next: doc2 # next doc on the sidebar for navigation # don’t include next if this is the last doc; don’t include previous if first doc --- - ``` The docs from `docs/` are published to `https://prettier.io/docs/en/next/` and are considered to be the docs of the next (not yet released) version of Prettier. When a release happens, the docs from `docs/` are copied to the `website/versioned_docs/version-stable` directory, whose content is published to `https://prettier.io/docs/en`. @@ -71,7 +70,6 @@ title: Blog Post Title author: Author Name authorURL: http://github.com/author # (or some other link) --- - ``` In the blog post, you should include a line ``. This determines under which point text will be ignored when generating the preview of your blog post. Blog posts should have the file name format: `yyyy-mm-dd-your-file-name.md`. diff --git a/website/blog/2017-04-13-1.0.0.md b/website/blog/2017-04-13-1.0.0.md deleted file mode 100644 index e5579fb3c4..0000000000 --- a/website/blog/2017-04-13-1.0.0.md +++ /dev/null @@ -1,1062 +0,0 @@ ---- -author: Christopher Chedeau (@vjeux) -authorURL: https://twitter.com/vjeux -title: Releasing Prettier 1.0 ---- - -_This post was written by [vjeux](https://twitter.com/vjeux) and edited by -[jlongster](https://twitter.com/jlongster), and originally published [here](http://jlongster.com/prettier-1.0)_ - -We officially [announced](http://jlongster.com/A-Prettier-Formatter) -[prettier](https://github.com/prettier/prettier) over two months ago as a way to -solve the problem of wasting time formatting your code. It started as an -experiment but it clearly resonated with a lot of people, amassing ~7000 GitHub -stars and over 100,000 monthly `npm downloads` in just two months. - - - -In case you don't know, prettier is a JavaScript formatter that works by -compiling your code to an AST, and then pretty-printing the AST. Like browsers -wrap text, prettier will also wrap code according to a given line length. The -result is good-looking code that is completely consistent no matter who wrote -it. This solves the problem of programmers spending a lot of time manually -moving around code in their editor and arguing about styles (see -[gif](http://jlongster.com/s/refactor.gif)). - -It wasn't entirely clear from the beginning if we could make it always generate -valid and good-looking code, but the good news is that this is no longer an open -question. Many projects (React, Jest, immutable-js, Haul, and many more) and -companies (Oculus, Cloudflare) adopted prettier to format their JavaScript -codebase and realized the wins of automated formatting (see -[this tweet](https://twitter.com/jlongster/status/852532847252566017) for -more!). Some of them ran prettier on their entire codebase (tens of thousands of -lines of code). - -During the past three weeks we went through all the open issues and tried to -make as many decisions regarding how code is being formatted as possible and -fixed most of the bugs we knew about. It's not perfect and we'll keep iterating -on it but it's a good time to **release a 1.0**! - -This does not mean we won't change the format anymore, but changes will be -minimal. For example, we are looking at adjusting -[ternaries](https://github.com/prettier/prettier/pull/1171) but there will be -very few changes of that nature from here on out, and when there are we will -make a new major version. - -What it means is that **prettier is safe to use for production**. We've fixed a -ton of bugs and made sure the output is stable and semantically correct. -Prettier is ready to be used from a few files in your side project to converting -your entire codebase. It's up to you to figure out where you are in the journey -of letting go of a particular way to formatting your code. - -Let's take a look what 1.0 brings to -[prettier](https://github.com/prettier/prettier)! - -_Thank you to all of the following contributors who have contributed to this -release, and thank you to [Ian Storm Taylor](https://github.com/ianstormtaylor) -for the logo!_ - -_Adam Stankiewicz, Alex Rattray, Alex Stachowiak, Amjad Masad, Andrey -Okonetchnikov, António Nuno Monteiro, Artem Sapegin, Benjamin Tan, Bill Mill, -Brandon Mills, Brian Holt, Brian Ng, Charles Pick, ChristianHersevoort, -Christopher Chedeau, Christopher Moeller, Damien Lebrun, Dan Harper, Dara Hak, -David Ascher, David Hong, Davy Duperron, Eric Clemmons, Erick Romero, Esben -Petersen, Filipe Fortes, Gregor Adams, Hampus,hlsson, Hawken Rives, Henry Zhu, -Ilya Panasenko, James Henry, James Long, Jamie Webb, Jan Kassens, Jed Watson, -Jeffrey Horn, Jeremy Morrell, Joe Fiorini, Jon LaBelle, Joseph Savona, Karl -Horky, Karl O'Keeffe, Kent C. Dodds, Kevin Gibbons, Kim Joar Bekkelund, Lucas -Bento, Lucas Duailibe, MarekMatejkaKCL, Mateusz Zatorski, Michael Ficarra, Michał -Pierzchała, Mikael Brevik, Nathan Friedly, Patrick Camacho, Paul,arduner, Rafael -Hengles, Raghuvir Kasturi, Rasmus Eneman, Riley Tomasek, Rogelio Guzman, Royce -Townsend, Sean Grove, Shigeaki Okazaki, Simen,ekkhus, Simon Lydell, Sorin -Muntean, Spencer Dixon, Thai Pangsakulyanont, Tom McKearney, Travis Jefferson, -Umidbek Karimov, Vincent Voyer, Vu Tran, Walter Breakell, Yatharth Khatri, azu, -daleroy, kalmanb, skratchdot_ - -## Options - -Prettier is an opinionated code formatter. At the beginning of the project, we -thought that it meant having no configuration like gofmt or refmt. But, as we -moved forward, we realized that this was going to hurt the adoption of prettier -and people that would have benefited from it wouldn't use it because it wasn't -printing code the way they want. - -Instead, our recent interpretation of being an opinionated code formatter is to -provide options regarding basic aspects of the syntax that are of the nature of -"if it doesn't do X, no matter how good it is, I'm never going to use it". For -example, I (@vjeux) am never going to use -[standard](https://github.com/feross/standard) because it doesn't use -semi-colons. This is absolutely not a rational way to think about it, but that's -the way many people behave and why we have "style wars". - -We are still not going to introduce options for every type of syntax, but only -for more impactful things. We've identified two major options that fall in that -category: _tabs vs spaces_ and _semi vs no-semi_. So we're adding them in -prettier! - -### --no-semi ([#1129](https://github.com/prettier/prettier/pull/1129)) - -Thanks to [rattrayalex](https://github.com/rattrayalex) who did a lot of work to -make this happen! - - -```js -// Before -console.log(); -[1, 2, 3].map(x => x + 1); - -// After -console.log() -;[1, 2, 3].map(x => x + 1) - -``` - -### --use-tabs ([#1026](https://github.com/prettier/prettier/pull/1026)) - -Thanks to [rhengles](https://github.com/rhengles) for implementing this and -explaining the reasons behind it! - - -```js -// Before -if (1) { -··console.log(); // Two spaces -} - -// After -if (1) { -» console.log(); // One Tab! -} - -``` - -## Formatting - -The rest of this post document all of the smaller changes that we round up for -1.0. We won't usually post a changelog as a post, but we thought that it shows -how stable prettier is getting and gives a good sense for the kinds of issues we -are fixing these days. - -### Add newline for bracket-less arrow functions that return calls ([#927](https://github.com/prettier/prettier/pull/927)) - -Probably the most reported issue from the current version of prettier: we were -not adding a newline after arrow functions inside of calls. Now, we do. On a -side note, it's pretty exciting that the issues are now about small things like -this and no longer "this looks completely broken" kind of issues. - - -```js -// Before -const testResults = results.testResults.map(testResult => - formatResult(testResult, formatter, reporter)); - -// After -const testResults = results.testResults.map(testResult => - formatResult(testResult, formatter, reporter) -); - -``` - -### Add softline to assignment and parens around return for binary expressions ([#871](https://github.com/prettier/prettier/pull/871) & [#870](https://github.com/prettier/prettier/pull/870)) - -Big chains of logical expressions look weird when the first line is on the same -line as the variable declaration or return. Instead, it's better to move it on -the next line and add parenthesis in return to make it valid. - - -```js -// Before -const computedDescriptionLines = (showConfirm && - descriptionLinesConfirming) || - (focused && !loading && descriptionLinesFocused) || - descriptionLines; - -// After -const computedDescriptionLines = - (showConfirm && descriptionLinesConfirming) || - (focused && !loading && descriptionLinesFocused) || - descriptionLines; - - -// Before -return !filePath.includes(coverageDirectory) && - !filePath.endsWith(`.${SNAPSHOT_EXTENSION}`); - -// After -return ( - !filePath.includes(coverageDirectory) && - !filePath.endsWith(`.${SNAPSHOT_EXTENSION}`) -); - -``` - -### Group first arg for inline functions ([#947](https://github.com/prettier/prettier/pull/947)) - -The first big custom pattern we've added in prettier is printing functions as -last arguments inline. A less common one is to do the same thing for the first -argument. It's very uncommon for libraries written nowadays to use that style -but some core JavaScript functions like `setTimeout` are doing it so it makes -sense to support it in prettier. - - -```js -// Before -setTimeout( - function() { - thing(); - }, - 500 -); - -// After -setTimeout(function() { - thing(); -}, 500); - -``` - -### Improve jsx output for style components ([#1144](https://github.com/prettier/prettier/pull/1144)) - -Template literals are very tricky to format because whitespaces are significant. -With prettier, we don't want to change the semantic of your program by -reformatting it so we're leaving them as is. The current way we handle them is -not optimal and we have ideas on how to fix them in a general way but in the -meantime, we can do some targeted fixes like this one for JSX. - - -```jsx -// Before - - -// After - - -``` - -### Add support for same line dot-notation in decorators ([#1029](https://github.com/prettier/prettier/pull/1029)) - -MobX 3 now uses member expressions that should be written inline, the previous -heuristic was too restrictive. It is now fixed. - - -```js -class X { - // Before - @action.bound - setPrice(price) { - this.price = price; - } - - // After - @action.bound setPrice(price) { - this.price = price; - } -} - -``` - -### Hug on single object destructuring function ([#1022](https://github.com/prettier/prettier/pull/1022)) - -React stateless functional components are all the rage right now and it makes -sense to hug the destructuring of the first argument to take less space. - - -```jsx -// Before -export default function StatelessFunctionalComponent( - { - searchFilters, - title, - items - } -) { - return
; -} - -// After -export default function StatelessFunctionalComponent({ - searchFilters, - title, - items, -}) { - return
-} - -``` - -### Add support for currying ([#1066](https://github.com/prettier/prettier/pull/1066)) - -Redux is heavily promoting writing functions in a curried form where each -argument is a nested function. Instead of indenting them, we're now putting them -inline. - - -```js -// Before -const mw = store => - next => - action => { - return next(action) - }; - -// After -const mw = store => next => action => { - return next(action) -}; - -``` - -### Respect escaping for JSX strings ([#1056](https://github.com/prettier/prettier/pull/1056)) - -For strings we've tried a bunch of different solutions regarding to escaping: -escape nothing, escape everything, escape a whitelisted set... But we couldn't -find a heuristic that would make all the use cases reasonable. So we decided to -leave the strings escaped the way they were inputted. We're now doing this for -JSX strings. - - -```jsx -// Before - - -// After - - -``` - -## Parenthesis - -A blessing and curse of printing from the AST is that we have to reprint all the -parenthesis of the program. Our stance used to be to print only the minimum -number of parenthesis that were needed for the program to be valid and execute -the same way. Now, we're willing to add parenthesis that are not strictly needed -but help people understand the code. - -### Add parenthesis for binary operators ([#1153](https://github.com/prettier/prettier/pull/1153)) - - -```js -// Before -var sizeIndex = index - 1 >>> level & MASK; - -// After -var sizeIndex = ((index - 1) >>> level) & MASK; - -``` - -### Add parenthesis for no-confusing-arrow rule ([#1182](https://github.com/prettier/prettier/pull/1182)) - - -```js -// Before -var x = a => 1 ? 2 : 3; - -// After -var x = a => (1 ? 2 : 3); - -``` - -### Remove parens from chained assignments ([#967](https://github.com/prettier/prettier/pull/967)) - - -```js -// Before -this.size = (this._origin = (this._capacity = 0)); - -// After -this.size = this._origin = this._capacity = 0; - -``` - -## Flow - -In the early days of prettier we've heavily focused on getting the core -JavaScript language well supported. Now that it is in a good shape, we have more -time to print Flow constructs in a polished way. - -### Add ability for flow generics to break ([#1041](https://github.com/prettier/prettier/pull/1041)) - - -```ts -// Before -type _ReactElement, C: $React.Component> = $React.Element; - -// After -type _ReactElement< - DefaultProps, - Props, - Config: $Diff, - C: $React.Component -> = $React.Element; - -``` - -### Improve printing of flow intersections ([#1018](https://github.com/prettier/prettier/pull/1018) & [#1155](https://github.com/prettier/prettier/pull/1155)) - - -```ts -// Before -type Props = - & { - focusedChildren?: React.Children, - onClick: () => void, - overlayChildren?: React.Children, - } - & FooterProps; - -// After -type Props = { - focusedChildren?: React.Children, - onClick: () => void, - overlayChildren?: React.Children, -} & FooterProps; - -``` - -### Add support for breaks in TupleTypeAnnotation ([#1003](https://github.com/prettier/prettier/pull/1003)) - - -```ts -// Before -export type FileMetaData = [/* id */ string, /* mtime */ number, /* visited */ - | 0 - | 1, /* dependencies */ Array]; - -// After -export type FileMetaData = [ - /* id */ string, - /* mtime */ number, - /* visited */ 0|1, - /* dependencies */ Array, -]; - -``` - -### No parenthesis for Flow shorthand with one arg ([#972](https://github.com/prettier/prettier/pull/972)) - - -```ts -// Before -type T = { method: (a) => void }; - -// After -type T = { method: a => void }; - -``` - -### Ability for interface to break ([#1060](https://github.com/prettier/prettier/pull/1060)) - - -```ts -// Before -export interface Environment1 extends GenericEnvironment { - m(): void -} - -// After -export interface Environment1 - extends GenericEnvironment { - m(): void -} - -``` - -### Fix printing of Flow type number literals ([#1132](https://github.com/prettier/prettier/pull/1132)) - - -```ts -// Before -type Hex = {n: 1}; - -// After -type Hex = {n: 0x01}; - -``` - -## Places to break - -There are a few cases where prettier still outputs code that's > 80 columns -where there's a possible way to write it without. The solution is to carefully -find places where it's possible to break and make sure that it doesn't -negatively impact common cases. - -### Allow to break after = for strings and member expressions ([#1142](https://github.com/prettier/prettier/pull/1142) & [#1188](https://github.com/prettier/prettier/pull/1188)) - - -```js -// Before -elements[0].innerHTML = '
'; -var testExampleOrOrderOfGetterAndSetterReordered = obj.exampleOfOrderOfGetterAndSetterReordered; - -// After -elements[0].innerHTML = - '
'; -var testExampleOrOrderOfGetterAndSetterReordered = - obj.exampleOfOrderOfGetterAndSetterReordered; - -``` - -### Add ability to break for top member expression ([#1036](https://github.com/prettier/prettier/pull/1036)) - - -```js -// Before -expect( - findDOMNode(component.instance()).getElementsByClassName(styles.inner)[0].style.paddingRight -).toBe("1000px"); - -// After -expect( - findDOMNode(component.instance()).getElementsByClassName(styles.inner)[0] - .style.paddingRight -).toBe("1000px"); - -``` - -## Miscellaneous - -### Inline class expressions for bracket-less arrow functions ([#1023](https://github.com/prettier/prettier/pull/1023)) - -Super small thing, we're now inlining classes returned from arrow functions. - - -```js -// Before -jest.mock( - '../SearchSource', - () => - class { - findMatchingTests(pattern) { - return {paths: []}; - } - }, -); - -// After -jest.mock( - '../SearchSource', - () => class { - findMatchingTests(pattern) { - return {paths: []}; - } - }, -); - -``` - -### Do not respect newlines for object destructuring pattern ([#981](https://github.com/prettier/prettier/pull/981)) - -For objects, we have special handling where if there is a \\n anywhere inside in -the original source, we keep it expanded. It was only intended for objects but -because the same code is shared with destructuring, it accidentally applied -there too. This has been fixed. - - -```js -// Before -const Component2 = ({ - props -}) => Test; - -// After -const Component1 = ({ props }) => Test; - -``` - -## Language Support - -In order for you to be able to use prettier, it must be able to print the code -you are writing. We are aiming to be able to print everything that our -underlying parsers (babylon and flow) are able to parse. - -### Add support for ForOfStatement with await flag ([#1073](https://github.com/prettier/prettier/pull/1073)) - - -```js -async function f() { - for await (const line of readLines(\\"/path/to/file\\")) { - (line: void); // error: string ~> void - } -} - -``` - -### Add support for flow type spread ([#1064](https://github.com/prettier/prettier/pull/1064)) - - -```ts -type TypeB = { ...TypeA }; - -``` - -## Correctness - -The absolute first requirement of prettier is to print valid code that has the -same behavior as the original source. You shouldn't be afraid of running -prettier on your entire codebase. In order to ensure this, we are doing a lot of -things: - -- Have an automated way to ensure that prettier is outputting valid code. -- Use it against large codebases such as Facebook, all of CDNjs and the many - people in the community using it. -- Run extensive fuzzing using [eslump](https://github.com/lydell/eslump). -- Making every report of such issue as high-pri and fixed right away. - -If you are unlucky enough to see one, please report it so that we can fix it and -you can use `// prettier-ignore` to get you unblocked. - -### Properly handle \\r\\n in JSXText ([#1170](https://github.com/prettier/prettier/pull/1170)) - - -```jsx -// Before -
- {" "} - Text{" "} -
; - -// After -
- Text -
; - -``` - -### Fix parenthesis when call inside of new ([#1169](https://github.com/prettier/prettier/pull/1169)) - - -```js -// Before -new factory()(); - -// After -new (factory())(); - -``` - -### Add parens around arrow function return type ([#1152](https://github.com/prettier/prettier/pull/1152)) - - -```ts -// Before -const f = (): string => string => {}; - -// After -const f = (): (string => string) => {}; - -``` - -### Fix printing of exact object flow type annotations ([#1114](https://github.com/prettier/prettier/pull/1114)) - - -```ts -// Before -type Props = {}; - -// After -type Props = {||}; - -``` - -### Print return dangling comment ([#1178](https://github.com/prettier/prettier/pull/1178)) - - -```js -// Before -function f() { - return; -} - -// After -function f() { - return /* a */; -} - -``` - -### Print comment after object key ([#1131](https://github.com/prettier/prettier/pull/1131)) - - -```js -// Before -let a = { - "a": () => 1 -}; - -// After -let a = { - "a" /* comment */: () => 1 -}; - -``` - -### Fix leading comment inside returned SequenceExpression ([#1133](https://github.com/prettier/prettier/pull/1133)) - - -```js -// Before -function sequenceExpressionInside() { - return; - // Reason for a - a, b; -} - -// After -function sequenceExpressionInside() { - return ( // Reason for a - a, b - ); -} - -``` - -### Fix single optional arrow param printing ([#1002](https://github.com/prettier/prettier/pull/1002)) - - -```ts -// Before -a = b? => c; - -// After -a = (b?) => c; - -``` - -### Fix default exports ([#998](https://github.com/prettier/prettier/pull/998)) - - -```js -// Before -export { foo, bar } from "./baz"; - -// After -export foo, {bar} from './baz'; - -``` - -### Print line/mixed comments on new lines inside JSXEmptyExpression ([#985](https://github.com/prettier/prettier/pull/985)) - - -```jsx -// Before -
- { - // single line comment} -
; - -// After -
- { - // single line comment - } -
; - -``` - -## Comments - -prettier works by printing the AST, this makes handling comments tricky as they -can be placed anywhere between tokens. The way prettier works is to attach a -comment to an ast node, either before or after it. We have a generic heuristic -to find the location that works most of the time but there's a large amount of -edge cases that we need to handle manually. - -prettier is never going to be able to properly print comments in all the crazy -places where you can put them, but we expect to be able to do a reasonable job -at them in most cases. If you see anything weird related to comments, please -create issues and we can figure something out. - -### Add breakParent support for willBreak ([#674](https://github.com/prettier/prettier/pull/674)) - - -```js -// Before -runtimeAgent.getProperties(objectId, false, false, false, ( // ownProperties // accessorPropertiesOnly // generatePreview - error, - properties, - internalProperties -) => { - return 1; -}); - -// After -runtimeAgent.getProperties( - objectId, - false, // ownProperties - false, // accessorPropertiesOnly - false, // generatePreview - (error, properties, internalProperties) => { - return 1 - }, -); - -``` - -### Fix additional empty line switch case comment ([#936](https://github.com/prettier/prettier/pull/936)) - - -```js -// Before -switch (foo) { - case "bar": - doThing() - - - // no default -} - -// After -switch (foo) { - case "bar": - doThing() - - // no default -} - -``` - -### Fix import declaration comments ([#1030](https://github.com/prettier/prettier/pull/1030)) - - -```js -// Before -import { - FN1, - FN2, - // FN3, - FN4 -} from // FN4, -// FN5 -"./module"; - -// After -import { - FN1, - FN2, - // FN3, - FN4, - // FN4, - // FN5 -} from './module'; - -``` - -### Fix last argument comment for function ([#1176](https://github.com/prettier/prettier/pull/1176) & [#905](https://github.com/prettier/prettier/pull/905)) - - -```ts -// Before -function f( - a: number -)// some comment here -: number { - return a + 1; -} - -// After -function f( - a: number - // some comment here -): number { - return a + 1; -} - -``` - -### Unrestrict flow union comments check ([#1040](https://github.com/prettier/prettier/pull/1040)) - - -```ts -// Before -type UploadState = - // The upload hasnt begun yet - | A - | // The upload timed out - B - | // Failed somewhere on the line - C; - -// After -type UploadState = - // The upload hasnt begun yet - | A - // The upload timed out - | B - // Failed somewhere on the line - | C; - -``` - -### Fix comments inside of ObjectPattern ([#1045](https://github.com/prettier/prettier/pull/1045)) - - -```ts -// Before -export default ( - { - foo, - bar - // comment - // comment 2 - }: { - foo?: Object, - bar?: Object - } -) => {}; - -// After -export default ( - { - foo, - bar - }: { - // comment - foo?: Object, - // comment 2 - bar?: Object, - }, -) => {} - -``` - -### Fix comment sorting location ([#1038](https://github.com/prettier/prettier/pull/1038)) - - -```js -// Before -let { - // comment - a = b -} = c; - -// After -let { - a = b // comment -} = c; - -``` - -### Fix comment location for binary expressions ([#1043](https://github.com/prettier/prettier/pull/1043)) - - -```js -// Before -a = Math.random() * (yRange * (1 - minVerticalFraction)) + - minVerticalFraction * yRange// Comment - - - offset; - -// After -a = - // Comment - Math.random() * (yRange * (1 - minVerticalFraction)) + - minVerticalFraction * yRange - - offset; - -``` - -### Fix class method comments ([#1074](https://github.com/prettier/prettier/pull/1074)) - - -```js -// Before -class x { - focus() // do nothing - { - // do nothing - } -} - -// After -class x { - focus() { - // do nothing - // do nothing - } -} - -``` - -### Support "// prettier-ignore" in comment blocks ([#1125](https://github.com/prettier/prettier/pull/1125)) - - -```js -// Before -module.exports = { - // Some comment - // prettier-ignore - m: matrix(1, 0, 0, 0, 1, 0, 0, 0, 1) -}; - -// After -module.exports = { - // Some comment - // prettier-ignore - m: matrix( - 1, 0, 0, - 0, 1, 0, - 0, 0, 1 - ) -}; - -``` - -### Stabilize VariableDeclarator comments ([#1130](https://github.com/prettier/prettier/pull/1130)) - - -```js -// Before -let obj = [ // Comment - 'val' -]; - -// After -let obj = [ - // Comment - 'val' -]; - -``` - -### Fix comment detection before comma ([#1127](https://github.com/prettier/prettier/pull/1127)) - - -```js -// Before -const foo = { - a: 'a' /* comment for this line */, - - /* Section B */ - b: 'b', -}; - -// After -const foo = { - a: 'a' /* comment for this line */, - /* Section B */ - b: 'b', -}; - -``` - -### Fix last comment of an if test ([#1042](https://github.com/prettier/prettier/pull/1042)) - - -```js -// Before -if (isIdentifierStart(code) || code === 92) { - /* '\' */ -} - -// After -if (isIdentifierStart(code) || code === 92 /* '\' */) {} - -``` diff --git a/website/blog/2017-04-20-1.2.0.md b/website/blog/2017-04-20-1.2.0.md deleted file mode 100644 index d20f82b3b6..0000000000 --- a/website/blog/2017-04-20-1.2.0.md +++ /dev/null @@ -1,174 +0,0 @@ ---- -author: Christopher Chedeau (@vjeux) -authorURL: https://twitter.com/vjeux -title: Prettier 1.2 ---- - -1.0 is not the end of prettier, we're going to continue to work on the long tail of formatting issues in order to make it an awesome JavaScript code formatter. You should expect minor version releases like this one to change small things and edge cases but nothing major or controversial. - - - -### Format - -#### Do not print the sub-tree when using prettier-ignore ([#1286](https://github.com/prettier/prettier/pull/1286)) - -#### Bail when traversing === groups ([#1294](https://github.com/prettier/prettier/pull/1294)) - -A regression was introduced in 1.0 where deeply nested functions like this would trigger an exponential behavior and no longer complete in a reasonable time. We introduced a mitigation such that it's not instant but at least completes in a reasonable amount of time. - - -```js -someObject.someFunction().then(function () { - return someObject.someFunction().then(function () { - return someObject.someFunction().then(function () { - return someObject.someFunction().then(function () { - return someObject.someFunction().then(function () { - }); - }); - }); - }); -}); -``` - -#### Break if () if conditional inside breaks ([#1344](https://github.com/prettier/prettier/pull/1344)) - -prettier was sometimes breaking inside of an if condition as it didn't fit 80 columns but would print all the conditions in a single line. This was very weird looking. Now if the if break, prettier will also break the conditions. - - -```js -// Before -if ( - this.hasPlugin("dynamicImports") && this.lookahead().type === tt.parenLeft -) { - -// After -if ( - this.hasPlugin("dynamicImports") && - this.lookahead().type === tt.parenLeft -) { -``` - -#### Avoid breaking arguments for last arg expansion ([#1305](https://github.com/prettier/prettier/pull/1305)) - -A long-standing issue around last argument expansion and complex arguments has been fixed, it no longer looks crazy bad. - - -```js -// Before -manageChildren: jest.fn(function manageChildren(parentTag, moveFromIndices = [ -], moveToIndices = [], addChildReactTags = [], addAtIndices = [ -], removeAtIndices = []) { - -// After -manageChildren: jest.fn(function manageChildren( - parentTag, - moveFromIndices = [], - moveToIndices = [], - addChildReactTags = [], - addAtIndices = [], - removeAtIndices = [] -) { -``` - -#### Add parentheses for assignment as body of arrow ([#1326](https://github.com/prettier/prettier/pull/1326)) - -We're fine tuning when to add parenthesis in order to improve understanding of the code. This time, we're adding it to assignment inside of arrow functions. Please open up issues if you think that there should be parenthesis and prettier doesn't put them. - - -```js -// Before -() => foo = bar + 2; - -// After -() => (foo = bar + 2); -``` - -#### Improve regex printing ([#1341](https://github.com/prettier/prettier/pull/1341)) - -Flow and Babylon were inconsistent in how they printed escapes and flags. Now the escapes are untouched compared to the original ones and the flags are sorted. - - -```js -// Before -/[\/]\/\u0aBc/mgi; - -// After -/[/]\/\u0aBc/gim; -``` - -#### Fix arrow function parenthesis with comments in flow ([#1339](https://github.com/prettier/prettier/pull/1339)) - -With the Flow parser, prettier didn't add parenthesis for single argument functions with a comment. - - -```js -// Before -call(/*object*/ row => {}); - -// After -call((/*object*/ row) => {}); -``` - -#### Don't inline paren at right of arguments ([#1345](https://github.com/prettier/prettier/pull/1345)) - -We incorrectly put a comment at the right of arguments inside of the argument list. - - -```js -// Before -f(/* ... */) {} - -// After -f() /* ... */ {} -``` - -#### Fix template literal comments ([#1296](https://github.com/prettier/prettier/pull/1296)) - -Comments inside of template literals would crash in some conditions and be inserted in the wrong `${}`, no more :) - - -```js -// Before -stdin: TypeError: Cannot read property 'comments' of undefined - -// After -` -(?:${escapeChar}[\\S\\s]|(?:(?!${// Using `XRegExp.union` safely rewrites backreferences in `left` and `right`. -// Intentionally not passing `basicFlags` to `XRegExp.union` since any syntax -// transformation resulting from those flags was already applied to `left` and -// `right` when they were passed through the XRegExp constructor above. -XRegExp.union([left, right], '', {conjunction: 'or'}).source})[^${escapeChar}])+)+ -` -``` - -#### Fix isPreviousLineEmpty on Windows ([#1263](https://github.com/prettier/prettier/pull/1263)) - -Empty lines were not properly preserved for switch case on windows. - - -```js -// Before -switch (a) { - case x: - - case y: - call(); -} - -// After -switch (a) { - case x: - case y: - call(); -} -``` - -### CLI - -#### Skip globbing filenames with node-glob when the filename is not a glob ([#1307](https://github.com/prettier/prettier/pull/1307)) - -If you run `prettier file.js` and `file.js` doesn't exist, it's going to throw an exception instead of silently doing nothing. - -#### Write out change CLI changes synchronously ([#1292](https://github.com/prettier/prettier/pull/1292)) - -There was a race condition when you did ctrl-c to stop the process where it could delete files. Now we write files synchronously so it doesn't anymore. diff --git a/website/blog/2017-05-03-1.3.0.md b/website/blog/2017-05-03-1.3.0.md deleted file mode 100644 index 6026f8e489..0000000000 --- a/website/blog/2017-05-03-1.3.0.md +++ /dev/null @@ -1,507 +0,0 @@ ---- -author: Christopher Chedeau (@vjeux) -authorURL: https://twitter.com/vjeux -title: Prettier 1.3 ---- - -This post provides an update to Facebook's adoption or Prettier, outlines our progress on TypeScript, and details some of the improvements and fixes included in the 1.3.0 release of Prettier. - - - -### Facebook Adoption Update - -The reason why I ([@vjeux](https://github.com/vjeux)) embarked on this journey working on prettier has always been to get the entire Facebook codebase converted over. I would like to give an update on how it is going and what is the process to get there. - -The first projects to adopt prettier were Jest, React and immutable-js. Those are small codebases in the order of hundreds of files that have their own infrastructure. There are a handful of people working on them full time. - -Then, Oculus and Nuclide converted their codebase over. The scale is bigger with a few thousands of files and tens of full time contributors but looks pretty similar to the first projects. The conversions went in one big codemod and that's it. - -Now, the entire Facebook codebase is way bigger than this and it's not feasible to just convert everything in one go and to convince everyone that their entire codebase is going to be reformatted under their feet. So we need to find a more incremental approach. - -#### Scaling adoption - -Running prettier on a piece of code is a pretty expensive operation, it makes your pull request look bad because of a lot of unrelated changes and it causes merge conflicts for all the outstanding pull requests. So **once a file has been formatted, you should do everything to make sure it remains formatted**. - -- When pretty-printing a file, add `@format` to the first block comment like `@flow`. -- Have a lint rule with autofix that checks if the file is correctly pretty printed when `@format` is present. - - When running Nuclide, it's going to show as an inline warning and have a fix button. - - When sending a pull request, it's going to show the lint failing with a [Yn] prompt that you can just press enter. -- Update the default code templates to add `@format` to the header. -- When you run code formatting via cmd-shift-c inside of Nuclide, automatically insert the `@format` header. -- Disable all the stylistic rules like max-len when `@format` is in the header. -- Have script to run prettier through an entire folder with everything configured as a one line operation. -- Have a good guide to help people that want to convert their codebase over with instructions and best practices. -- When pushing a new release of prettier, also run it through all the files with `@format` in order to avoid getting warnings afterwards. -- Add tracking for the number of files with `@format` over time. - -We finally got all those things wired up 1.5 weeks ago and the reception has been insane. Many people from various teams converted their codebase to prettier on their own. As of today, 15% of Facebook codebase has been converted over! - -
- -When I started working on prettier, I had a hunch that people were hungry for tools to solve formatting. But I had no idea that once the tooling was in place, people would rush to convert their codebase over! This is great confirmation that this project is useful to people and not just a gimmicky tool. - -### TypeScript Support Progress - -[@despairblue](https://github.com/despairblue), [@azz](https://github.com/azz) and [@JamesHenry](https://github.com/JamesHenry) have been hard at work around getting TypeScript supported by prettier as it's the top requested feature. 2000 out of 11000 files in the TypeScript test suite are not yet properly printed. You can follow progress on https://github.com/prettier/prettier/issues/1480 and do not hesitate to help out! - -### Flow - -#### Add trailing commas on flow generics ([#1381](https://github.com/prettier/prettier/pull/1381)) - -The `--trailing-comma=all` option is supposed to add trailing commas everywhere possible, but as an oversight we forgot to do it for flow generics. - - -```ts -// Before -type Errors = Immutable.Map< - Ahohohhohohohohohohohohohohooh, - Fbt | Immutable.Map ->; - -// After -type Errors = Immutable.Map< - Ahohohhohohohohohohohohohohooh, - Fbt | Immutable.Map, ->; -``` - -#### Inline nullable in flow generics ([#1426](https://github.com/prettier/prettier/pull/1426)) - -The phase after printing things correctly is to tweak the output to make it closer to the way people write code in practice. Inlining optional flow types is a small thing that makes a difference. - - -```ts -// Before -type Cursor = Promise< - ?{ - newCursor?: number, - formatted: string, - } ->; - -// After -type Cursor = Promise; -``` - -#### Allow flow declarations to break on StringLiteralTypeAnnotations ([#1437](https://github.com/prettier/prettier/pull/1437)) - -We can always find more places to add breaks when things don't fit 80 columns. This time it's around declaring a type as a constant string. - - -```js -// Before -export type AdamPlacementValidationSingleErrorKey = 'SOME_FANCY_TARGETS.GLOBAL_TARGET'; - -// After -export type AdamPlacementValidationSingleErrorKey = - 'SOME_FANCY_TARGETS.GLOBAL_TARGET'; -``` - -#### Add space around `=` for flow generics default arguments ([#1476](https://github.com/prettier/prettier/pull/1476)) - -Another example of small thing where we can improve the display of flow code. For function default arguments we put a space around `=` but didn't around flow generics. - - -```ts -// Before -class PolyDefault {} - -// After -class PolyDefault {} -``` - -#### Don't break for unparenthesised single argument flow function ([#1452](https://github.com/prettier/prettier/pull/1452)) - -I'm trying to figure out something to write here, but ... it just looks weird! - - -```ts -// Before -const selectorByPath: - Path - => SomethingSelector< - SomethingUEditorContextType, - SomethingUEditorContextType, - SomethingBulkValue -> = memoizeWithArgs(/* ... */) - -// After -const selectorByPath: Path => SomethingSelector< - SomethingUEditorContextType, - SomethingUEditorContextType, - SomethingBulkValue -> = memoizeWithArgs(/* ... */); -``` - -#### Fix optional flow parenthesis ([#1357](https://github.com/prettier/prettier/pull/1357)) - -We were a bit too lenient around parenthesis for optional flow types. In one case in the entire Facebook codebase, it generated code with different semantics. As part of this fix, we hardened the list of types that can be written without parenthesis. - - -```ts -// Before -type X = ?(number, number) => number => void; - -// After -type X = (?(number, number) => number) => void; -``` - -#### Skip trailing commas with FlowShorthandWithOneArg ([#1364](https://github.com/prettier/prettier/pull/1364)) - -It is a parse error to add a trailing comma without parenthesis for arguments of arrow function types. We found one case in Facebook codebase when this happened, it's a very rare occurrence. - - -```ts -// Before -type IdeConnectionFactory = - child_process$ChildProcess, - => FlowIDEConnection = defaultIDEConnectionFactory; - -// After -type IdeConnectionFactory = - child_process$ChildProcess - => FlowIDEConnection = defaultIDEConnectionFactory; -``` - -#### Reorder flow object props ([#1451](https://github.com/prettier/prettier/pull/1451)) - -This one is an example where the way the AST is structured is not our favor. Instead of having a list of elements inside of a type, the AST is structured in a way where normal keys and array keys each have their own group. In order to restore the initial order, we're now reading from the original source :( - - -```ts -// Before -type Foo = { - [key: string]: void, - alpha: "hello", - beta: 10 -}; - -// After -type Foo = { - alpha: 'hello', - [key: string]: void, - beta: 10 -} -``` - -### Template Literal - -#### Proper indentation for template literals ([#1385](https://github.com/prettier/prettier/pull/1385)) - -A long standing issue with template literals and prettier is around the indentation of code inside of `${}`. It used to be the indentation of the backtick but turned out to give poor results. Instead people tend to use the indent of the `${`. We changed this behavior and it magically made GraphQL queries look pretty! - - -```js -// Before -Relay.createContainer({ - nodes: ({ solution_type, time_frame }) => Relay.QL` - fragment { - __typename - ${OptimalSolutionsSection.getFragment("node", { - solution_type, - time_frame - })} - } - ` -}) -``` - - -```js -// After -Relay.createContainer({ - nodes: ({ solution_type, time_frame }) => Relay.QL` - fragment { - __typename - ${OptimalSolutionsSection.getFragment("node", { - solution_type, - time_frame - })} - } - ` -}) -``` - -#### Do not indent calls with a single template literal argument ([#873](https://github.com/prettier/prettier/pull/873)) - -Template literals are very hard to deal with for a pretty printer because the spaces inside are meaningful so you can't re-indent them. We didn't know what to do for a call with a single template literal so we didn't do anything, but we kept receiving reports of people saying that prettier indented it the wrong way, so we are now inlining them. Fingers crossed it is going to cover most use cases. - -```js -// Before -insertRule( - `*, *:before, *:after { - box-sizing: inherit; - }` -); - -// After -insertRule(`*, *:before, *:after { - box-sizing: inherit; -}`); -``` - -#### Fix windows line ending on template literals ([#1439](https://github.com/prettier/prettier/pull/1439)) - -We manipulate line endings in a lot of places in prettier and took great care of handling both `\n` and `\r\n` except for template literals where we forgot. Now this is fixed! - - -```js -// Before -const aLongString = ` - -Line 1 - -Line 2 - -Line 3 - -`; - -// After -const aLongString = ` -Line 1 -Line 2 -Line 3 -`; -``` - -#### Inline template literals as arrow body ([#1485](https://github.com/prettier/prettier/pull/1485)) - -We already inline template literals that are tagged (eg `` graphql`query` ``) but didn't for plain template literals. For the anecdote, it turns out the code was supposed to support it but it was using `TemplateElement` instead of `TemplateLiteral` :( - - -```js -// Before -const inlineStore = preloadedState => - ` - -` - -// After -const inlineStore = preloadedState => ` - -` -``` - -### Ternaries - -#### Add parenthesis for unusual nested ternaries ([#1386](https://github.com/prettier/prettier/pull/1386)) - -While working on printing nested ternaries, everyone focused on the ones with the shape of an if then else `cond1 ? elem1_if : cond2 ? elem2_if : elem_else` which is the most common. But, if you move some `?` and `:` around you can have another pattern. It looks almost the same but has a different meaning. In order to reduce confusion, we're adding parenthesis around the uncommon form. - - -```js -// Before -cond1 ? cond2 ? elem2_if : elem2_else : elem1_else - -// After -cond1 ? (cond2 ? elem2_if : elem2_else) : elem1_else -``` - -#### Only add parenthesis on ternaries inside of arrow functions if doesn't break ([#1450](https://github.com/prettier/prettier/pull/1450)) - -There's an eslint rule [`no-confusing-arrows`](http://eslint.org/docs/rules/no-confusing-arrow) which suggests adding parenthesis for ternaries in arrow functions without brackets. The following two pieces of code are confusing: - - -```js -var x = a => 1 ? 2 : 3; -var x = a <= 1 ? 2 : 3; -``` - -It makes sense when code is in one line, but when it is split into multiple lines, the parenthesis are unnecessary given the indentation, so we now only put them when they serve their disambiguation purpose. - - -```js -// Before -var x = a => (1 ? 2 : 3); -var x = a => - (1 - ? 2 - : 3); - -// After -var x = a => (1 ? 2 : 3); -var x = a => - 1 - ? 2 - : 3; -``` - -### General JavaScript Improvements - -#### Inline function declaration with single arg as object ([#1173](https://github.com/prettier/prettier/pull/1173)) - -This one was often requested for React Stateless Functional Components (SFC). If you make use of a lot of them, it's likely going to be a big change for you. - - -```js -// Before -const X = ( - props: { - a: boolean, - }, -) =>
; - -// After -const X = (props: { - a: boolean, -}) =>
; -``` - -#### Break inline object first in function arguments ([#1453](https://github.com/prettier/prettier/pull/1453)) - -One thing we discovered early on is that people usually break the arguments of the function before breaking the return type. Unfortunately, the code responsible to inline single destructuring argument broke that assumption and it introduced bad looking code like this example. The good news is that it enables us to turn on inlining for single arguments that are typed with an object. - - -```js -// Before -class X { - async onDidInsertSuggestion({editor, triggerPosition, suggestion}): Promise< - void - > { - } -} - -// After -class X { - async onDidInsertSuggestion({ - editor, - triggerPosition, - suggestion - }): Promise { - } -} -``` - -#### Don't break on empty arrays and objects ([#1440](https://github.com/prettier/prettier/pull/1440)) - -This one has been a long standing issue and is an easy fix, but was an invaluable tool: whenever someone reported that `[]` or `{}` would break, we were able to fix the example by fixing something else. So it was a great way to surface edge cases. Fortunately, this vein has now ran out and all the recent examples just look bad with no other reason than the fact that they are breaking. So it's time to finally do it! - - -```js -// Before -const a = someVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeLong.Expression || [ -]; - -// After -const a = someVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeLong.Expression || []; -``` - -#### Do not break on `[0]` ([#1441](https://github.com/prettier/prettier/pull/1441)) - -We have a lot of issues where code breaks in array access when it doesn't look good. We don't yet have a good generic solution for it, but we can add a specific fix a common situation: `[0]`. - - -```js -// Before -queryThenMutateDOM(() => { - title = SomeThing.call(root, "someLongStringThatPushesThisTextReall")[ - 0 - ]; -}); - -// After -queryThenMutateDOM(() => { - title = SomeThing.call( - root, - "someLongStringThatPushesThisTextReall", - )[0]; -}); -``` - -#### Indent do while condition ([#1373](https://github.com/prettier/prettier/pull/1373)) - -We were not using the correct indentation logic for do-while condition but someone noticed, now we do! - - -```js -// Before -do {} -while (someVeryLongStringA && someVeryLongStringB && someVeryLongStringC && someVeryLongStringD); - -// After -do {} -while ( - someVeryLongStringA && - someVeryLongStringB && - someVeryLongStringC && - someVeryLongStringD -); -``` - -#### Preserve inline comment as last argument ([#1390](https://github.com/prettier/prettier/pull/1390)) - -We forgot to add one case in the comment detection code when they appear last for JSX attributes and function arguments which made them go after the closing. In the case of JSX, it generated code that had a different meaning. Fortunately, since we don't usually commit commented out code it didn't affect production code, but it is not a good experience while coding. - - -```js -// Before -const x = ( -
-// attr3={3} - {children} -
-); - -// After -const x = ( -
- {children} -
-); -``` - -#### Break class expression returned by arrow call ([#1464](https://github.com/prettier/prettier/pull/1464)) - -In 1.0, we made class be inline inside of arrow functions. It turns out that it doesn't work great when the class is non trivial, so we are reverting this change. We're trying really hard to avoid making trashy decisions like this where the style changes back and forth, but we allow ourselves to do it sometimes to fix mistakes! - -```js -// Before -export default (ViewComponent: Function, ContainerComponent: Function) => - class extends React.Component { - static propTypes = {}; - }; - -// After -export default (ViewComponent: Function, ContainerComponent: Function) => - class extends React.Component { - static propTypes = {}; - }; -``` - -#### Fix empty line in block with EmptyStatement ([#1375](https://github.com/prettier/prettier/pull/1375)) - -This one was found by fuzzing. You're unlikely going to hit this in real code but it's good to know it is fixed! - - -```js -// Input -if (a) { - b; - - - ; -} - -// Before -if (a) { - b; - -} - -// After -if (a) { - b; -} -``` diff --git a/website/blog/2017-06-03-1.4.0.md b/website/blog/2017-06-03-1.4.0.md deleted file mode 100644 index ab5ee4606b..0000000000 --- a/website/blog/2017-06-03-1.4.0.md +++ /dev/null @@ -1,655 +0,0 @@ ---- -author: Christopher Chedeau (@vjeux) -authorURL: https://twitter.com/vjeux -title: "Prettier 1.4: TypeScript and CSS support" ---- - -This release introduces support for TypeScript, CSS, Less, and SCSS languages to Prettier! - - - -[![prettier-revolution-conf](/blog/assets/prettier-revolution-conf.png)](https://revolutionconf.com/talk/a-prettier-printer) - -## TypeScript Support - -This is the most requested feature for prettier. With 1.4.0, you can now use prettier to format your `.ts` and `.tsx` files! - -The way prettier works is by using those project to generate an AST representation of the code and print it. Both babylon (the parser that powers babel) and flow are producing an AST approximately following the [estree](https://github.com/estree/estree) format for the JavaScript parts and then have special nodes for Flow-specific ones. - -TypeScript, the same way as Flow, introduces special nodes for the syntax it introduces. Unfortunately, it doesn't follow the estree format for the rest of the JavaScript language. This puts us in a rough spot with prettier as we would have to essentially completely fork it in order to print TypeScript. - -This incompatibility with the AST is not a new problem and another project struggled with it: ESLint. Because the AST is different, none of the ESLint rules are working. Fortunately for us, [@JamesHenry](https://github.com/JamesHenry) and [@soda0289](https://github.com/soda0289) wrote a project called [typescript-eslint-parser](https://github.com/eslint/typescript-eslint-parser) which takes a TypeScript AST and convert it to an estree one, just what we need for prettier! - -After that project got setup inside of prettier, [@azz](https://github.com/azz), [@despairblue](https://github.com/despairblue) and [@Pajn](https://github.com/Pajn) implemented all the TypeScript-specific nodes and ensured that the 13k tests of the TypeScript test suite are correctly passing. This was a huge undertaking and it is finally ready to be used :) - -We tested prettier on the biggest TypeScript projects we could find on GitHub to ensure that it prints correct code. We haven't spent a lot of time trying to optimize the way code is formatted yet, so if you see something strange, please raise an issue! - -## CSS, Less and SCSS Support - -While TypeScript is the most requested feature from open source, CSS is the biggest one from Facebook engineers. Once you are used to pretty print your code in one language, you want to do it everywhere! - -It turns out that CSS is a much smaller language than JavaScript and supporting it only took a few days. We are using [postcss](https://github.com/postcss/postcss) by [@ai](https://github.com/ai) as the underlying parser which is able to parse CSS, Less and SCSS. We also depend on [postcss-values-parser](https://github.com/shellscape/postcss-values-parser), [postcss-selector-parser](https://github.com/postcss/postcss-selector-parser) by [@ben](https://github.com/ben)-eb [postcss-media-query-parser](https://github.com/dryoma/postcss-media-query-parser) by [@dryoma](https://github.com/dryoma). - -Unfortunately, postcss right now doesn't parse Sass nor Stylus. We'd be happy to support them if someone is willing to do the work of printing them. - -Note that prettier is currently just formatting the code, it does not respect any options yet such as `singleQuote` nor is doing any color or number normalization like we do for JavaScript. - -## Editor Integration - -The first phase of the project was to make prettier output correct and good looking code. Now that it's in a good shape, we can spend time on making the integrations better. We just introduced support for two great features: maintain cursor position and being able to format a range instead of the entire file. - -Note that we just landed the support inside of prettier itself, none of the editor integrations are using it yet. Also, we haven't really tried them out in practice so we're likely going to have to fix rough edges with them! - -#### Add `cursorOffset` option for cursor translation ([#1637](https://github.com/prettier/prettier/pull/1637)) by [@josephfrazier](https://github.com/josephfrazier) - -Right now, we let editors figure out where the cursor should be, which they do an okay job at. But since we are printing the code, we can give the correct position! - -#### Add `--range-start/end` options to format only parts of the input ([#1609](https://github.com/prettier/prettier/pull/1609)) by [@josephfrazier](https://github.com/josephfrazier) - -This one is a very often requested feature. Right now prettier only formats the entire file. Now it is possible to format a range. - -The way it works is by going up through the AST in order to find the closest statement. This way you don't need to select exactly the right range that is valid. You can just drag in the rough place where the code you want to reformat it, and it's going to! - -#### Adding filepath option in order to enable filetype inference ([#1835](https://github.com/prettier/prettier/pull/1835)) by [@mitermayer](https://github.com/mitermayer) - -Since we are now formatting CSS and TypeScript, it is not convenient to have to specify the parser for every file. You can now pass the filepath of the file you are working on and prettier will read the extension and figure out the right parser to use. - -## Highlights - -#### Wrap text content inside of JSX ([#1120](https://github.com/prettier/prettier/pull/1120), [#1671](https://github.com/prettier/prettier/pull/1671), [#1827](https://github.com/prettier/prettier/pull/1827), [#1829](https://github.com/prettier/prettier/pull/1829)) by [@karl](https://github.com/karl) - -The biggest remaining issue that people have with prettier when printing JSX is when it is used when printing text. The behavior of prettier used to add an ugly `{" "}` before and if a line was too long, just leave it alone. Now we treat each word as a token and are able to make it flow correctly. - -This is an awesome piece of work by [@karl](https://github.com/karl) as not only did he implement the feature, but also introduced a new primitive inside of prettier in order to print a sequence of elements and break as soon as one hits the edge. - - -```jsx -// Before -
- Please state your - {" "} - name - {" "} - and - {" "} - occupation - {" "} - for the board of directors. -
- -// After -
- Please state your name and occupation for the board of - directors. -
-``` - -#### Remove parenthesis for JSX inside of arrow functions ([#1733](https://github.com/prettier/prettier/pull/1733)) by [@xixixao](https://github.com/xixixao) - -People writing functional components are going to be happy about this one. We no longer put parens for arrow functions that return JSX. - - -```jsx -// Before -const render1 = ({ styles }) => ( -
- Keep the wrapping parens. Put each key on its own line. -
-); - -// After -const render1 = ({ styles }) => -
- Keep the wrapping parens. Put each key on its own line. -
; -``` - -#### Improve template literal printing ([#1664](https://github.com/prettier/prettier/pull/1664), [#1714](https://github.com/prettier/prettier/pull/1714)) by [@josephfrazier](https://github.com/josephfrazier) - -Template literal printing has always caused prettier a lot of difficulties. With 1.3.0 we massively improved the situation and with this release, I believe that we handle all the common situations in a good way. - -In order to workaround issues, we added an utility that removes empty lines from the output, but it yielded some really weird results sometimes, this is now gone. Another tweak we've done is instead of indenting when `${` starts, we indent where the line that contains `${` starts. - -Let us know if you still have issues with how template literals output after this release! - - -```js -// Before -const Bar = styled.div` - color: ${props => (props.highlight.length > 0 ? palette([ - 'text', - 'dark', - 'tertiary' - ])(props) : palette([ - 'text', - 'dark', - 'primary' - ])(props))} !important; -` - -// After -const Bar = styled.div` - color: ${props => - props.highlight.length > 0 - ? palette(["text", "dark", "tertiary"])(props) - : palette(["text", "dark", "primary"])(props)} !important; -` -``` - -#### Use the same breaking rules for assignment and object values ([#1721](https://github.com/prettier/prettier/pull/1721)) - -We have a lot of fine-tuned logic for how to break things after assignment (eg `a = ...`). We are now using the same one for object values. This should help for multi-line boolean logic, or big conditionals. This is also a good example of how we can create a consistent printer. - - -```js -// Before -const o = { - somethingThatsAReallyLongPropName: this.props.cardType === - AwesomizerCardEnum.SEEFIRST, -}; - -// After -const o = { - somethingThatsAReallyLongPropName: - this.props.cardType === AwesomizerCardEnum.SEEFIRST, -}; -``` - -#### Indent conditions inside of !() ([#1731](https://github.com/prettier/prettier/pull/1731)) - -There's been a steady stream of people complaining about the way it was rendered and was put on the list of things that are probably hard to do, will check later. It turned out to be super easy, so here you go! - - -```js -// Before -const anyTestFailures = !(aggregatedResults.numFailedTests === 0 && - aggregatedResults.numRuntimeErrorTestSuites === 0); - -// After -const anyTestFailures = !( - aggregatedResults.numFailedTests === 0 && - aggregatedResults.numRuntimeErrorTestSuites === 0 -); -``` - -## Formatting Fixes - -#### Put loop bodies on the same line when possible ([#1498](https://github.com/prettier/prettier/pull/1498)) - -We were already doing this for if statements, we should be consistent and also do it for loops. - - -```js -// Before -for (a in b) - var c = {}; - -// After -for (a in b) var c = {}; -``` - -#### Fix empty line with flow union ([#1511](https://github.com/prettier/prettier/pull/1511)) by [@existentialism](https://github.com/existentialism) - -We shouldn't indent things twice ;) - - -```ts -// Before -type Foo = Promise< - - | { ok: true, bar: string, baz: SomeOtherLongType } - | { ok: false, bar: SomeOtherLongType } ->; - -// After -type Foo = Promise< - { ok: true, bar: string, baz: SomeOtherLongType } | - { ok: false, bar: SomeOtherLongType } ->; -``` - -#### Do not put parens for single argument with end of line comment ([#1518](https://github.com/prettier/prettier/pull/1518)) - -The detection code for whether an arrow function should be written without parenthesis just checked if there was a comment, but instead we only want comments that are inline like `(/* comment */ num)`, not end of line comments. - - -```jsx -// Before -KEYPAD_NUMBERS.map((num) => ( // Buttons 0-9 -
-)); - -KEYPAD_NUMBERS.map(num => ( // Buttons 0-9 -
-)); -``` - -#### Do not indent nested ternaries ([#1822](https://github.com/prettier/prettier/pull/1822)) - -This avoids making it seems like it is indented by 4 characters instead of two. The downside is that if the condition is multi-line it's not going to be properly aligned, but I feel it's a better trade-offs. If you are doing nested ternaries, you usually have small conditions. - - -```js -// Before -aaaaaaaaaaaaaaa - ? bbbbbbbbbbbbbbbbbb - : ccccccccccccccc - ? ddddddddddddddd - : eeeeeeeeeeeeeee ? fffffffffffffff : gggggggggggggggg; - -// After -aaaaaaaaaaaaaaa - ? bbbbbbbbbbbbbbbbbb - : ccccccccccccccc - ? ddddddddddddddd - : eeeeeeeeeeeeeee ? fffffffffffffff : gggggggggggggggg; -``` - -#### Inline chained conditionals inside of jsx attribute ([#1519](https://github.com/prettier/prettier/pull/1519)) - -We don't need to use the indentation to disambiguate another block as nothing can come after. - - -```jsx -// Before -
; - -// After -
; -``` - -#### Unescape unnecessarily escaped characters in strings ([#1575](https://github.com/prettier/prettier/pull/1575)) by [@josephfrazier](https://github.com/josephfrazier) - -We are already trying to cleanup strings in various ways, this is another small addition that's going to remove `\` that are not needed. - - -```js -// Before -a = 'hol\a'; - -// After -a = 'hola'; -``` - -#### Fix boolean for empty objects ([#1590](https://github.com/prettier/prettier/pull/1590)) by [@dmitrika](https://github.com/dmitrika) - -We want to inline objects inside of a boolean expression as it looks weird to have `{` on its own line. But it turns out that it leads to weird behaviors for empty objects. So we keep them on their own line if they are empty. - - -```js -const x = firstItemWithAVeryLongNameThatKeepsGoing || -secondItemWithALongNameAsWell || {}; - -// After -const x = - firstItemWithAVeryLongNameThatKeepsGoing || - secondItemWithALongNameAsWell || - {}; -``` - -#### Remove Parens from SequenceExpressions in ForStatements ([#1597](https://github.com/prettier/prettier/pull/1597)) by [@k15a](https://github.com/k15a) - -It is common to assign multiple values inside of a for loop, now we don't add parenthesis anymore. - - -```js -// Before -for ((i = 0), (len = arr.length); i < len; i++) { - -// After -for (i = 0, len = arr.length; i < len; i++) { -``` - -#### Do not inline arrow when argument has a leading comment ([#1660](https://github.com/prettier/prettier/pull/1660)) - -If you put block comments inside of arrow functions, we no longer mess everything up! - - -```js -// Before -export const bem = block => /** - * @param {String} [element] - the BEM Element within that block; if undefined, selects the block itself. - */ -element => /** - * @param {?String} [modifier] - the BEM Modifier for the Block or Element; if undefined, selects the Block or Element unmodified. - */ -modifier => - -// After -export const bem = block => - /** - * @param {String} [element] - the BEM Element within that block; if undefined, selects the block itself. - */ - element => - /** - * @param {?String} [modifier] - the BEM Modifier for the Block or Element; if undefined, selects the Block or Element unmodified. - */ - modifier => -``` - -#### Fix last comments of imports ([#1677](https://github.com/prettier/prettier/pull/1677)) - -Another place where we have to do special logic for comments! - - -```js -// Before -import { - ExecutionResult, - DocumentNode, - /* tslint:disable */ - SelectionSetNode, -} /* tslint:enable */ from 'graphql'; - -// After -import { - DocumentNode, - /* tslint:disable */ - SelectionSetNode, - /* tslint:enable */ -} from 'graphql'; -``` - -#### Handle comments in member chain ([#1686](https://github.com/prettier/prettier/pull/1686), [#1691](https://github.com/prettier/prettier/pull/1691)) - -We handled some placements before and kept adding places where they could appear, now we switch to a more general approach. Hopefully those issues shouldn't crop up in the future anymore. - - -```js -// Before -const configModel = this.baseConfigurationService.getCache().consolidated // global/default values (do NOT modify) - .merge(this.cachedWorkspaceConfig); - -// After -const configModel = this.baseConfigurationService - .getCache() - .consolidated // global/default values (do NOT modify) - .merge(this.cachedWorkspaceConfig); -``` - -#### Use expandLast for nested arrow functions ([#1720](https://github.com/prettier/prettier/pull/1720)) - - -```js -// Before -f(action => next => - next(action)); - -// After -f(action => next => - next(action), -); -``` - -#### Put JSX comments inside of the parenthesis ([#1712](https://github.com/prettier/prettier/pull/1712)) - -This mostly affects Facebook engineers where we automatically add `$FlowFixMe` when pushing a new version of flow. Now it no longer messes up those comments. - - -```jsx -// Before -const aDiv = /* $FlowFixMe */ -( -
- Foo bar -
-); - -// After -const aDiv = ( - /* $FlowFixMe */ -
- Foo bar -
-); -``` - -#### Force \n for multiple variable declarations ([#1723](https://github.com/prettier/prettier/pull/1723)) - -This one has been very often requested. We used to only break multiple variable declarations if the line was > 80 columns. Now we do it regardless if there's at least one with an assignment. - - -```js -// Before -var numberValue1 = 1, numberValue2 = 2; - -// After -var numberValue1 = 1, - numberValue2 = 2; -``` - -#### Inline | null and | void ([#1734](https://github.com/prettier/prettier/pull/1734)) - -The expanded version of flow union looks good when they are many objects but if it's used for nullability, then it looks very weird. We're now inlining `| null` and `| void`. - - -```ts -// Before -interface RelayProps { - articles: - | Array< - | { - __id: string, - } - | null - > - | null -} - -// After -interface RelayProps { - articles: Array<{ - __id: string, - } | null> | null, -} -``` - -#### Break on implements instead of extends ([#1730](https://github.com/prettier/prettier/pull/1730)) - -We no longer break on `extends`. This should make classes with extends that can break look less wonky. - - -```ts -// Before -class MyContractSelectionWidget - extends React.Component< - void, - MyContractSelectionWidgetPropsType, - void - > { - method() {} -} - -// After -class MyContractSelectionWidget extends React.Component< - void, - MyContractSelectionWidgetPropsType, - void -> { - method() {} -} -``` - -#### Inline single import ([#1729](https://github.com/prettier/prettier/pull/1729)) - -The same way we don't break long `require` calls, we no longer break `import` statements if there is only a single thing being imported. - - -```js -// Before -import somethingSuperLongsomethingSuperLong - from "somethingSuperLongsomethingSuperLongsomethingSuperLong"; - -// After -import somethingSuperLongsomethingSuperLong from "somethingSuperLongsomethingSuperLongsomethingSuperLong"; -``` - -#### Add the ability for SequenceExpression to break ([#1749](https://github.com/prettier/prettier/pull/1749)) - -Did you know that if none of your code were statements, you could use `()` instead of `{}` and `,` instead of `;`? Now you do. Some people exploit this fact when returning things from arrow functions. This is not recommended but it's easy to support in prettier so might as well ¯\\\_(ツ)\_/¯ - - -```js -// Before -const f = (argument1, argument2, argument3) => - (doSomethingWithArgument(argument1), doSomethingWithArgument( - argument2 - ), argument1); - -// After -const f = (argument1, argument2, argument3) => ( - doSomethingWithArgument(argument1), - doSomethingWithArgument(argument2), - argument1 -); -``` - -#### Don't force line break in empty loop bodies ([#1815](https://github.com/prettier/prettier/pull/1815)) - -Loops with empty body no longer have their `{}` split into two lines. - - -```js -// Before -while (true) { -} - -// After -while (true) {} -``` - -#### Preserve empty lines between switch cases with comments ([#1708](https://github.com/prettier/prettier/pull/1708)) - - -```js -// Before -switch (true) { - case true: - // Good luck getting here - case false: -} - -// After -switch (true) { - case true: - - // Good luck getting here - case false: -} -``` - -## Correctness - -#### Remove ast-types ([#1743](https://github.com/prettier/prettier/pull/1743), [#1744](https://github.com/prettier/prettier/pull/1744), [#1745](https://github.com/prettier/prettier/pull/1745), [#1746](https://github.com/prettier/prettier/pull/1746), [#1747](https://github.com/prettier/prettier/pull/1747)) - -We used to find where to put comments by traversing the AST using the definition from ast-types. This occasionally caused issues when some field wasn't declared, we wouldn't find the node and either print comments in an incorrect location or throw an error. It turns out that we don't need to keep this mapping and can just traverse the objects and if a node has a `type` field, then it's a node. - - -```ts -// Before -Error: did not recognize object of type "ObjectTypeSpreadProperty" - -// After -type X = {...Y/**/}; -type X = {/**/...Y}; -``` - -#### Preserve unusual unicode whitespace ([#1658](https://github.com/prettier/prettier/pull/1658), [#1165](https://github.com/prettier/prettier/pull/1165)) by [@karl](https://github.com/karl) and [@yamafaktory](https://github.com/yamafaktory) - -If you were adding invisible characters inside of JSX text, we would replace them by regular spaces. I don't know why anyone would ever want to do that, but now we print it back as is! - -#### Don't let trailing template literal comments escape ([#1580](https://github.com/prettier/prettier/pull/1580), [#1713](https://github.com/prettier/prettier/pull/1713), [#1598](https://github.com/prettier/prettier/pull/1598), [#1713](https://github.com/prettier/prettier/pull/1713)) by [@josephfrazier](https://github.com/josephfrazier) and [@k15a](https://github.com/k15a) - -We used to have some pretty complicated (and not working well) code to handle comments inside of template literals. We introduced a really nice solution for JSX `{}` expressions. The idea is to introduce a boundary before the end of the `}` and if we still have unprinted comments, then flush them all at once, put a \n and print the `}`. We are now using this logic for template literals :) - - -```js -// Before -`${0} // comment`; - -// After -`${ -0 -// comment -}`; -``` - -#### Parenthesize await correctly ([#1513](https://github.com/prettier/prettier/pull/1513), [#1595](https://github.com/prettier/prettier/pull/1595), [#1593](https://github.com/prettier/prettier/pull/1593)) by [@bakkot](https://github.com/bakkot) and [@existentialism](https://github.com/existentialism) - -We don't have an automated way to put parenthesis, we instead specify all the possible combinations of nodes and when they should or shouldn't have parenthesis. So there's likely a long tail of unusual combinations that are still remaining. In this case, we made `await` handling a lot more robust by both adding parenthesis where they are needed and removing them when they are not. - - -```js -// Before -(await spellcheck) && spellcheck.setChecking(false); -new A((await x)); - -// After -await (spellcheck && spellcheck.setChecking(false)); -new A(await x); -``` - -#### Preserve getter/setter info on flow ObjectTypeProperty ([#1585](https://github.com/prettier/prettier/pull/1585)) by [@josephfrazier](https://github.com/josephfrazier) - -Another long tail option that we haven't got right! - - -```ts -// Before -type T = { method: () => void }; - -// After -type T = { get method(): void } -``` - -#### Add parenthesis for single arg types with generics ([#1814](https://github.com/prettier/prettier/pull/1814)) - -Another case of sneaky parenthesis that we didn't properly add! - - -```ts -// Before -type ExtractType =
B => D - -// After -type ExtractType = (B) => D -``` - -#### Fall back to non-strict mode in babylon ([#1587](https://github.com/prettier/prettier/pull/1587), [#1608](https://github.com/prettier/prettier/pull/1608)) by [@josephfrazier](https://github.com/josephfrazier) - -We want prettier to be able to parse all the JavaScript out there. For babylon parser, we have to chose whether a file is using strict mode or not. We opted in to use strict mode by default as most files parse that way. But if you have octal literals like `0775`, it would not even parse. Now if it fails to parse in strict mode, we're going to try again in non-strict. We also allow `return` outside of a function as it's valid in node files. - - -```js -// Before -SyntaxError - -// After -return 0775; -``` - -## CLI - -#### Allow `--write` to be used with `--list-different` ([#1633](https://github.com/prettier/prettier/pull/1633)) - -This is useful to combine the two if you are writing a commit hook to tell the user what actually changed in a single command. - -#### Ignore node_modules when running prettier from CLI ([#1683](https://github.com/prettier/prettier/pull/1683)) by [@thymikee](https://github.com/thymikee) - -It's very easy to run prettier over the `node_modules/` folder by mistake which is something you almost never want to. So now we disable it by default and add a `--with-node-modules` option if you really want to. - -#### Traverse dot files for glob ([#1844](https://github.com/prettier/prettier/pull/1844)) by [@jhgg](https://github.com/jhgg) - -We enabled the option to go through .dotfiles in the glob parsing library we are using. This means that writing `*` will now catch `.eslintrc`. diff --git a/website/blog/2017-06-28-1.5.0.md b/website/blog/2017-06-28-1.5.0.md deleted file mode 100644 index f17500699d..0000000000 --- a/website/blog/2017-06-28-1.5.0.md +++ /dev/null @@ -1,665 +0,0 @@ ---- -author: Christopher Chedeau (@vjeux) -authorURL: https://twitter.com/vjeux -title: "Prettier 1.5: GraphQL, CSS-in-JS & JSON" ---- - -This release adds GraphQL formatting support, CSS-in-JS (including styled-components), and JSON support to Prettier. - - - -This is the release I've been waiting for a very long time: one that has only minimal changes to JavaScript! - -For the past 6 months, we kept doing changes to various aspects of printing JavaScript, with the hope that one day we would get to a stable place. No automated tool is going to print perfect code for all the possible edge cases. The goal is to find a good place where when people report code that is printed in a funny way, we can't make it better without making other pieces of code look worse, introduce behavior that's very hard to understand for humans and doesn't introduce some disproportionate complexity to the codebase. - -We're not 100% there yet, but we're closer than ever! - -Now that JavaScript needs for support is trending down, it's an opportunity to support other languages that front-end developers are working on and want formatted. We've introduced TypeScript and CSS in the last release and are doing a batch of fixes for them in this release. We're also adding support for new languages: GraphQL queries, embedding CSS-in-JS and JSON are now available in prettier! - -#### Blog Post: [Adding a new layout strategy to Prettier](https://medium.com/geckoboard-under-the-hood/adding-a-new-layout-strategy-to-prettier-8d33084c0f99) by [@karl](https://github.com/karl) - -Prettier is not only a useful tool but it's also a really cool piece of technology. [@karl](https://github.com/karl) spent a bunch of time improving JSX support and in the process implemented a new primitive to prettier: `fill`. He wrote a very interesting blog post [Adding a new layout strategy to Prettier](https://medium.com/geckoboard-under-the-hood/adding-a-new-layout-strategy-to-prettier-8d33084c0f99) that I highly recommend reading if you're interested in how prettier is working behind the scenes. - -### GraphQL - -Thanks to [@stubailo](https://github.com/stubailo), [@jnwng](https://github.com/jnwng), [@tgriesser](https://github.com/tgriesser) and [@azz](https://github.com/azz), prettier now supports printing GraphQL queries! - -It works for `.graphql` files and within JavaScript templates that start with `graphql`, `graphql.experimental` and `gql` in order to work with [Relay](https://facebook.github.io/relay/) and [Apollo](https://www.apollodata.com/). - - -```jsx -ReactDOM.render( - , - mountNode -); -``` - -Note that it only supports the open source syntax of GraphQL, therefore doesn't work with Relay Classic, it only works with Relay Modern. - -### CSS-in-JS - -If you are using [styled-components](https://github.com/styled-components/styled-components) or [styled-jsx](https://github.com/zeit/styled-jsx), prettier will now reformat the CSS inside of your template expressions. Thanks to [@pomber](https://github.com/pomber) for the awesome work! - - -```js -const EqualDivider = styled.div` - margin: 0.5rem; - padding: 1rem; - background: papayawhip; - > * { - flex: 1; - &:not(:first-child) { - ${props => (props.vertical ? "margin-top" : "margin-left")}: 1rem; - } - } -`; -``` - -### JSON - -This was pretty straightforward to implement but nonetheless very useful. Thanks to [@josephfrazier](https://github.com/josephfrazier) for doing it :) - - -```json -{ - "name": "prettier", - "version": "1.5.0", - "description": "Prettier is an opinionated JavaScript formatter", - "bin": { - "prettier": "./bin/prettier.js" - } -} -``` - -### CSS - -I'm really excited because we only put a few days to build the initial CSS support and it has worked surprisingly well. This release brings a handful of important improvements to CSS but nothing that required big changes. - -#### CSS: Every selector is now printed in its own line ([#2047](https://github.com/prettier/prettier/pull/2047)) by [@yuchi](https://github.com/yuchi) - -The biggest unknown when printing CSS was how to deal with multiple selectors. The initial approach we took was to use the 80 columns rule where we would only split if it was bigger than that. Many people reported that they were using another strategy for this: always break after a `,`. It turns out that many popular codebases are using this approach and it feels good as you can see the structure of the selectors when layed out on-top of each others. - - -```css -// Before -.clusterPlannerDialog input[type="text"], .clusterPlannerDialog .uiTypeahead { - color: #333; -} - -// After -.clusterPlannerDialog input[type="text"], -.clusterPlannerDialog .uiTypeahead { - color: #333; -} -``` - -#### CSS: lowercase hex colors ([#2203](https://github.com/prettier/prettier/pull/2203)) by [@azz](https://github.com/azz) - -The concept of code formatting has blurry boundaries. The core aspect of it is around whitespaces but some things like single vs double quotes and semi-colons are usually bundled with it. With prettier on JavaScript, we also lightly reformat strings by removing extra `\` and normalize numbers. For CSS, we need to do a similar interpretation of where the boundary ends. For colors, we decided to turn all the letters into lowercase and stop there. Turning rgb() into hex or 6 hex into 3 hex is out of scope. - - -```css -// Before -.foo { - color: #AAA; - -o-color: #fabcd3; - -ms-color: #AABBCC; -} - -// After -.foo { - color: #aa; - -o-color: #fabcd3; - -ms-color: #aabbcc; -} -``` - -#### CSS: Use fill for CSS values ([#2224](https://github.com/prettier/prettier/pull/2224)) - -The new fill primitive turned out to be very useful for CSS. For long values, instead of breaking and putting a `\n` before every element, we can instead only put a `\n` when it goes over the limit. It leads to much better looking code. - - -```scss -// Before -foo { - border-left: - 1px - solid - mix($warningBackgroundColors, $warningBorderColors, 50%); -} - -// After -foo { - border-left: 1px solid - mix($warningBackgroundColors, $warningBorderColors, 50%); -} -``` - -#### CSS: Allow long media rules to break ([#2219](https://github.com/prettier/prettier/pull/2219)) - -This is another small fix in the journey of properly supporting a new language. We now encode the ability to break on long `@media` rules. - - -```css -// Before -@media all and (-webkit-min-device-pixel-ratio: 1.5), all and (-o-min-device-pixel-ratio: 3/2), all and (min--moz-device-pixel-ratio: 1.5), all and (min-device-pixel-ratio: 1.5) { -} - -// After -@media all and (-webkit-min-device-pixel-ratio: 1.5), - all and (-o-min-device-pixel-ratio: 3/2), - all and (min--moz-device-pixel-ratio: 1.5), - all and (min-device-pixel-ratio: 1.5) { -} -``` - -#### CSS: Print @else on same line as } ([#2088](https://github.com/prettier/prettier/pull/2088)) by [@azz](https://github.com/azz) - -Less and SCSS are turning into real programming languages :) Step by step, we're starting to print all their constructs in the same way as JavaScript. This time, it's the `else` placement. - - -```scss -// Before -@if $media == phonePortrait { - $k: .15625; -} -@else if $media == tabletPortrait { - $k: .065106; -} - -// After -@if $media == phonePortrait { - $k: .15625; -} @else if $media == tabletPortrait { - $k: .065106; -} -``` - -#### CSS: implement prettier-ignore ([#2089](https://github.com/prettier/prettier/pull/2089)) by [@azz](https://github.com/azz) - -While we want prettier to format the entire codebase, there are times where we "know better" and want an escape hatch. This is where the `prettier-ignore` comment comes in. It wasn't working for CSS but that was an oversight, now it is implemented :) - - -```css -// Before -foo { - /* prettier-ignore */ - thing: foo; - -ms-thing: foo; -} - -// After -foo { - /* prettier-ignore */ - thing: foo; - -ms-thing: foo; -} -``` - -#### CSS: Fix css-modules composes breaking with long line width ([#2190](https://github.com/prettier/prettier/pull/2190)) by [@tdeekens](https://github.com/tdeekens) - -In order to be fast, many "packagers" do not parse files in order to extract dependencies but instead use a crude regex. This is a reason why we don't break long `require()` calls and it happens to also affect CSS Modules. If you add new lines in the `composes` field, it doesn't recognize it anymore. So we're no longer breaking it there, even if it goes over 80 columns. - - -```css -// Before -.reference { - composes: - selector - from - "a/long/file/path/exceeding/the/maximum/length/forcing/a/line-wrap/file.css"; -} - -// After -.reference { - composes: selector from "a/long/file/path/exceeding/the/maximum/length/forcing/a/line-wrap/file.css"; -} -``` - -#### CSS: First try scss when there's an [@import](https://github.com/import) with comma ([#2225](https://github.com/prettier/prettier/pull/2225)) - -We made a decision to have only a single high level "parser" for CSS, SCSS and Less even though we are using `postcss-less` and `postcss-scss` under the hood. We use a regex to figure out which parser to try first and fallback to the other one if a syntax error is thrown. Unfortunately, for certain features, the first (incorrect) parser doesn't throw and instead skips some elements. So, we need to beef up the regex to make sure we are right for the early detection. - -Thankfully, this hack is working well in practice. If we find a lot more edge cases, we'll likely want to do the right thing(tm) and split them into two parsers. - - -```scss -// Before -@import "text-shadow"; - -// After -@import "rounded-corners", "text-shadow"; -``` - -### TypeScript - -TypeScript support is now solid, all the changes for this release are small edge cases. - -#### TypeScript: print arrow function type params on same line as params ([#2101](https://github.com/prettier/prettier/pull/2101)) by [@azz](https://github.com/azz) - -The core algorithm of prettier is to expand a group if all the elements do not fit. It works really well in practice for most of JavaScript but there's one case it doesn't handle very well is when there are two groups side by side, in this case: `(Arguments)`. We have to carefully create groups such that arguments expand first as this is generally what people expect. - - -```ts -// Before -export const forwardS = R.curry(< - V, - T ->(prop: string, reducer: ReducerFunction, value: V, state: {[name: string]: T}) => - R.assoc(prop, reducer(value, state[prop]), state) -); - -// After -export const forwardS = R.curry( - ( - prop: string, - reducer: ReducerFunction, - value: V, - state: { [name: string]: T } - ) => R.assoc(prop, reducer(value, state[prop]), state) -); -``` - -#### TypeScript: keep parens around with yield/await non-null assertion ([#2149](https://github.com/prettier/prettier/pull/2149)) by [@azz](https://github.com/azz) - -For better or worse, we decided to manually handle adding parenthesis. So when a new operator is introduced, we need to make sure that we add correct parenthesis when nested with any other combination of operators. In this case, we missed await inside of TypeScript `!`. - - -```ts -// Before -const bar = await foo(false)!; - -// After -const bar = (await foo(false))!; -``` - -#### TypeScript: Print {} in import if it's in the source ([#2150](https://github.com/prettier/prettier/pull/2150)) by [@azz](https://github.com/azz) - -We use typescript-eslint-parser project that translates TypeScript AST into estree AST in order for prettier to print it. From time to time we're going to find edge cases that it doesn't handle yet. In this case, it didn't give a way to tell that there's an empty `{}`, which apparently is important for TypeScript. Thankfully, the team is very responsive and they fixed it after we put a workaround inside of prettier. - - -```ts -// Before -import from "@types/googlemaps"; - -// After -import {} from "@types/googlemaps"; -``` - -#### TypeScript: Always break interfaces onto multiple lines ([#2161](https://github.com/prettier/prettier/pull/2161)) by [@azz](https://github.com/azz) - -The code that implements `interface` is shared with the code that prints `object`s, which contains a rule to keep them expanded if there's a `\n` inside. But, this is not the intended behavior for interfaces. We always want to expand, like we do for classes, even if it fits 80 columns. - - -```ts -// Before -interface FooBar { [id: string]: number; } - -// After -interface FooBar { - [id: string]: number; -} -``` - -#### TypeScript: Fix extra semicolon in ambient typescript declaration emit ([#2167](https://github.com/prettier/prettier/pull/2167)) by [@azz](https://github.com/azz) - -`no-semi` and `semi` are often requested but on the prettier team we're one step ahead and implemented `two-semi` for you! Just kidding, it was a bug and is now fixed ;) - - -```ts -// Before -declare module "classnames" { - export default function classnames( - ...inputs: (string | number | false | object | undefined)[] - ): string;; -} - -// After -declare module "classnames" { - export default function classnames( - ...inputs: (string | number | false | object | undefined)[] - ): string; -} -``` - -#### TypeScript: group function params in call/construct signatures ([#2169](https://github.com/prettier/prettier/pull/2169)) by [@azz](https://github.com/azz) - -Adding a comment before a method used to take into account the comment length and would often expand the method when it wasn't expected. Thankfully, it was a simple fix, just wrap the output in a `group`. - - -```ts -// Before -interface TimerConstructor { - // Line-splitting comment - new ( - interval: number, - callback: (handler: Timer) => void - ): Timer; -} - -interface TimerConstructor { - // Line-splitting comment - new (interval: number, callback: (handler: Timer) => void): Timer; -} -``` - -#### TypeScript: Upgrade tsep ([#2183](https://github.com/prettier/prettier/pull/2183)) by [@azz](https://github.com/azz) - -This bug was very annoying if you ran into it: anytime you formatted the code, it would add one more `_` to the object key! - - -```ts -// Before -obj = { - __: 42 - ___: 42 -}; - -// After -obj = { - _: 42 - __: 42 -}; -``` - -#### TypeScript: break on multiple interface extends ([#2085](https://github.com/prettier/prettier/pull/2085)) by [@azz](https://github.com/azz) - -Unlike in JavaScript, TypeScript lets you extend multiple classes at once. It turns out that people use this feature and prettier now does a better job at printing it. - - -```ts -// Before -export interface ThirdVeryLongAndBoringInterfaceName extends AVeryLongAndBoringInterfaceName, AnotherVeryLongAndBoringInterfaceName, AThirdVeryLongAndBoringInterfaceName {} - -// After -export interface ThirdVeryLongAndBoringInterfaceName - extends AVeryLongAndBoringInterfaceName, - AnotherVeryLongAndBoringInterfaceName, - AThirdVeryLongAndBoringInterfaceName {} -``` - -#### TypeScript: handle ObjectPattern instead of ObjectExpression inside BinaryExpression ([#2238](https://github.com/prettier/prettier/pull/2238)) by [@azz](https://github.com/azz) - -This one isn't very interesting, it's an edge case that's not properly handled in the TypeScript -> estree conversion. - - -```ts -// Before -call(c => { bla: 1 }) || []; - -// After -call(c => ({ bla: 1 })) || []; -``` - -#### Preserve lines after directives ([#2070](https://github.com/prettier/prettier/pull/2070)) - -By supporting TypeScript, prettier is now being used in a lot of Angular codebases which exercises edge cases that were not properly handled. In this case, we didn't preserve empty lines after directives inside of a function. - - -```ts -// Before -export default class { - constructor($log, $uibModal) { - "ngInject"; - Object.assign(this, { $log, $uibModal }); - -// After -export default class { - constructor($log, $uibModal) { - "ngInject"; - - Object.assign(this, { $log, $uibModal }); -``` - -### JavaScript - -This release is very light in terms of JavaScript changes, which is awesome. We're starting to see the light at the end of the tunnel and get towards a great pretty printer. We're never going to get to a 100% perfect automatic pretty printer. The goal is that for every issue we get, there are no clear ways to improve the way it is printed without regressing other pieces. - -#### Allow JSX lines to be recombined ([#1831](https://github.com/prettier/prettier/pull/1831)) by [@karl](https://github.com/karl) - -The goal of prettier is to have a consistent way to format your code: given an AST, we always print the same way. In two places we had to compromise and read the original format: JSX and Objects. With this change, we're no longer relying on the original input for JSX with text inside. This lets us reflow text inside of JSX. - - -```jsx -// Before -const Abc = () => { - return ( -
- Please state your - {" "} - name - {" "} - and - {" "} - occupation - {" "} - for the board of directors. -
- ); -}; - -// After -const Abc = () => { - return ( -
- Please state your name and occupation for the board of - directors. -
- ); -} -``` - -#### Break on non-literal computed member expression ([#2087](https://github.com/prettier/prettier/pull/2087)) by [@azz](https://github.com/azz) - -Printing member chains is the most complicated piece of prettier and we keep finding small tweaks we can do to make it a better experience. - - -```js -// Before -nock(/test/) - .matchHeader("Accept", "application/json")[httpMethodNock(method)]("/foo") - .reply(200, { - foo: "bar", - }); - -// After -nock(/test/) - .matchHeader("Accept", "application/json") - [httpMethodNock(method)]("/foo") - .reply(200, { - foo: "bar", - }); -``` - -#### Indent first variable in one-var scenario ([#2095](https://github.com/prettier/prettier/pull/2095)) by [@azz](https://github.com/azz) - -Up until recently we haven't done much to support printing multiple variables in a single declaration as the most common practice is to do one variable declaration per variable. For single declarations, we don't want to indent it, but it turns out that we do when there are other ones afterwards, otherwise it looks weird. - - -```js -// Before -var templateTagsMapping = { - '%{itemIndex}': 'index', - '%{itemContentMetaTextViews}': 'views' -}, - separator = ''; - -// After -var templateTagsMapping = { - '%{itemIndex}': 'index', - '%{itemContentMetaTextViews}': 'views' - }, - separator = ''; -``` - -#### Allow break with both default named import ([#2096](https://github.com/prettier/prettier/pull/2096)) by [@azz](https://github.com/azz) - -This one is an unfortunate regression from 1.4 where we inlined import that only contained a single element. Turns out the definition of a single element allowed a single type and a single element. This is now corrected! - - -```js -// Before -import transformRouterContext, { type TransformedContextRouter } from '../../helpers/transformRouterContext'; - -// After -import transformRouterContext, { - type TransformedContextRouter -} from '../../helpers/transformRouterContext'; -``` - -#### Turn allowImportExportEverywhere on ([#2207](https://github.com/prettier/prettier/pull/2207)) by [@zimme](https://github.com/zimme) - -The goal of prettier is to format code people write in practice, so we enable loose/experimental modes for all the parsers we support. Babylon allows you to write import within a function, which is not part of the standard, but it doesn't cost us much to allow it. - - -```js -// Before -ParseError - -// After -function f() { - import x from 'x'; -} -``` - -#### Support inline template for new calls ([#2222](https://github.com/prettier/prettier/pull/2222)) - -We keep adding features for function calls and have to backport them to new calls as they have a different AST node type but in practice we want to treat them the same. This fix refactored the two so that they are going through the same call site, so hopefully should prevent more from sneaking in. - - -```js -// Before -new Error( - formatErrorMessage` - This is a really bad error. - Which has more than one line. - ` -); - -// After -new Error(formatErrorMessage` - This is a really bad error. - Which has more than one line. -`); -``` - -#### Don't indent + in object value ([#2227](https://github.com/prettier/prettier/pull/2227)) - -When we switched to using the same heuristic for assignment (`a = b`) for objects (`{a: b}`), we forgot to fix the indentation. Now it's fixed. - - -```js -// Before -var abc = { - thing: - "asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf" + - "asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf" + - "asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf", -} - -// After -var abc = { - thing: - "asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf" + - "asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf" + - "asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf", -} -``` - -#### Handle conditions inside of a ternary ([#2228](https://github.com/prettier/prettier/pull/2228)) - -Prettier already had a special case when the expression was a conditional but it didn't apply when the conditional was the left part of a ternary. Now it does. - - -```js -// Before -room = room.map((row, rowIndex) => - row.map( - (col, colIndex) => - rowIndex === 0 || - colIndex === 0 || - rowIndex === height || - colIndex === width - ? 1 - : 0 - ) -); - -// After -room = room.map((row, rowIndex) => - row.map( - (col, colIndex) => - rowIndex === 0 || - colIndex === 0 || - rowIndex === height || - colIndex === width - ? 1 - : 0 - ) -); -``` - -#### Add caching for printing ([#2259](https://github.com/prettier/prettier/pull/2259)) - -With the 1.0 release, we fixed a bug in the printing that introduced an exponential behavior. We've been able to mitigate the biggest issue such that reasonable code didn't time out, but it wasn't completely fixed it. By adding a caching layer at the right spot, we should now be in the clear. - -This should make printing the IR of prettier using prettier in debug mode no longer time out. - - -```js -// Before -...times out... - -// After -someObject.someFunction().then(function () { - return someObject.someFunction().then(function () { - return someObject.someFunction().then(function () { - return someObject.someFunction().then(function () { - return someObject.someFunction().then(function () { - return someObject.someFunction().then(function () { - return someObject.someFunction().then(function () { - return someObject.someFunction().then(function () { - return someObject.someFunction().then(function () { - anotherFunction(); - }); - }); - }); - }); - }); - }); - }); - }); -}); -``` - -#### Fix variance location ([#2261](https://github.com/prettier/prettier/pull/2261)) - -We refactored the code that prints modifiers when we introduced TypeScript support and accidentally moved around the variance (`+`) part before `static` which is not valid in Flow. This is now fixed. - - -```ts -// Before -class Route { - +static param: T; -} - -// After -class Route { - static +param: T; -} -``` - -### Miscellaneous - -#### Various fixes for range and cursor tracking ([#2266](https://github.com/prettier/prettier/pull/2266), [#2248](https://github.com/prettier/prettier/pull/2248), [#2250](https://github.com/prettier/prettier/pull/2250), [#2136](https://github.com/prettier/prettier/pull/2136)) by [@CiGit](https://github.com/CiGit) and [@josephfrazier](https://github.com/josephfrazier) - -Both those features were introduced in the last release and we discovered a bunch of issues when actually using them in production. A bunch of them got fixed, if you see more, please report them! diff --git a/website/blog/2017-08-29-1.6.0.md b/website/blog/2017-08-29-1.6.0.md deleted file mode 100644 index 0b1ae7c27d..0000000000 --- a/website/blog/2017-08-29-1.6.0.md +++ /dev/null @@ -1,729 +0,0 @@ ---- -author: Christopher Chedeau (@vjeux) -authorURL: https://twitter.com/vjeux -title: "Prettier 1.6: Config File, JSX" ---- - -This release adds configuration file support to Prettier, as well as some significant enhancements to JSX printing. - - - -I want to give a special shout out to [@azz](https://github.com/azz) who has been maintaining the repository and implementing a bunch of the changes in this release as I had less time to devote to prettier due to vacation and switching team :) - -## Highlights - -### Configuration - -#### Implement cosmiconfig for workspace configuration ([#2434](https://github.com/prettier/prettier/pull/2434)) by [@azz](https://github.com/azz) - -Since the very first release of prettier, people have asked for a `.prettierrc` file. We've been trying to have as few options as possible and tried to avoid being one more `.dotfile` that you have to have when starting a new project. - -But, the truth is, we need to have some way to configure prettier that can be kept in sync with all the integrations. By not having one, we pushed the problem to them and saw a bunch of incompatible ways of handling the problem. So now, it's handled by prettier itself. - - -```js -// .prettierrc -{ - "trailingComma": "es5", - "singleQuote": true -} -``` - -For more information on configuration file support, see the [README](https://github.com/prettier/prettier/blob/master/README.md#configuration-file). - -#### Support .prettierignore files ([#2412](https://github.com/prettier/prettier/pull/2412)) by [@evilebottnawi](https://github.com/evilebottnawi) - -Along with telling what configuration to use, you can write a file `.prettierignore` to tell which files not to convert. - -``` -## .prettierignore -dist/ -package.json -``` - -### JSX - -#### Improve JSX Formatting ([#2398](https://github.com/prettier/prettier/pull/2398)) by [@suchipi](https://github.com/suchipi) - -The last big friction point from people trying to adopt prettier was around how JSX was being printed. We went through all the issues that were raised and made a bunch of changes: - -- Arrow Function Expressions returning JSX will now add parens when the JSX breaks - - -```jsx -// Before -const Component = props => -
- Hello {props.name}! -
; - -// After -const Component = props => ( -
- Hello {props.name}! -
-); -``` - -- Conditional expressions within (or containing) JSX are formatted in a different way using parenthesis - - -```jsx -// Before -
- {props.isVisible - ? - : } -
; - -// After -
- {props.isVisible ? ( - - ) : ( - - )} -
-``` - -- JSX in logical expressions (|| or &&) is always wrapped in parens when the JSX breaks - - -```jsx -// Before -
- {props.isVisible && - } -
; - -// After -
- {props.isVisible && ( - - )} -
-``` - -Hopefully this is going to be more in line with how the majority of the community is writing JSX and we can have prettier be used in more place ;) - -#### Inline single expressions in JSX ([#2442](https://github.com/prettier/prettier/pull/2442)) by [@karl](https://github.com/karl) - -With JSX, we started by respecting a lot of line breaks that were in the original source. This had the advantage of doing fewer changes to your codebase but chipped away the value of a consistent pretty printer as the same semantic code could be written in two ways. - -During each new release we've tightened this and made decisions around how to always print a piece of code. The latest of those is what happens if there's a single child in a JSX object, we're now always going to inline it. - - -```jsx -// Before -return ( -
- {this.props.test} -
-); -return
{this.props.test}
; - -// After -return
{this.props.test}
; -return
{this.props.test}
; -``` - -#### Ensure there is a line break after leading JSX white space ([#2348](https://github.com/prettier/prettier/pull/2348)) by [@karl](https://github.com/karl) - -Leading JSX empty spaces are now on their own line. It looked weird to have them before a tag as it "indented" it differently compared to the rest. - - -```jsx -// Before - - {' '}
- - -// After - - {' '} - - -``` - -## Other Changes - -### JSON - -#### Use babylon.parseExpression for JSON ([#2476](https://github.com/prettier/prettier/pull/2476)) by [@josephfrazier](https://github.com/josephfrazier) - -We used to use a strict JSON parser that would throw if there was a comment or a trailing comma. This was inconvenient as many JSON files in practice are parsed using JavaScript or json5 that are not as strict. Now, we have relaxed this and are using the JavaScript parser to parse and print JSON. This means that comments will be maintained if there were some. - -Note that this is purely additive, if your original file was JSON compliant, it will keep printing a valid JSON. - - -```js -// Before -Syntax error - -// After -{ /* some comment */ "a": 1 } -``` - -### JavaScript - -#### Print 3 or more chained calls on multiple lines ([#2673](https://github.com/prettier/prettier/pull/2673)) by [@azz](https://github.com/azz) - -This was a longstanding issue with the way we print long member chains. Prettier would try and cram all but the final callback onto one line, which reduced the readability. The solution we landed on was to always break over multiple lines if there are three or more function calls in a method chain. - - -```js -// Before -Promise.resolve(0).catch(function(err) {}).then(function(res) { - // -}); - -// After -Promise.resolve(0) - .catch(function(err) {}) - .then(function(res) { - // - }); -``` - -#### Add more supervisory parens ([#2423](https://github.com/prettier/prettier/pull/2423)) by [@azz](https://github.com/azz) - -Parenthesis are a hot topic because they are not part of the AST, so prettier ignores all the ones you are putting and re-creating them from scratch. We went through all the things that people reported and came up with a few edge cases that were very confusing when comparisons were chained and `%` was mixed with `*` or `/`. - -One thing that we are not changing is the fact that we remove extra parenthesis around combinations of basic arithmetic operators: `+-*/`. - - -```js -// Before -x !== y === z; -x * y % z; - -// After -(x !== y) === z; -(x * y) % z; -``` - -#### Implement prettier-ignore inside JSX ([#2487](https://github.com/prettier/prettier/pull/2487)) by [@azz](https://github.com/azz) - -It's useful to be able to ignore pieces of JSX, it's now possible to add a comment inside of a JSX expression to ignore the formatting of the next element. - - -```jsx -// Before - - {/*prettier-ignore*/} - - - -// Before - - {/*prettier-ignore*/} - - -``` - -#### Do not swallow prettier-ignore comments ([#2664](https://github.com/prettier/prettier/pull/2664)) - -In order to support some edge cases, in the internals, we have the ability to avoid printing comments in a generic way and print them in the call site instead. It turns out that when we used `prettier-ignore`, we didn't print the comments at all! This is now fixed. - - -```jsx -// Before -push( - :) - , -); - -// After -push( - // prettier-ignore - :) - , -); -``` - -#### Fix indentation of a do-while condition ([#2359](https://github.com/prettier/prettier/pull/2359)) by [@jsnajdr](https://github.com/jsnajdr) - -It took 6 months for someone to report that do-while were broken when the while condition is multi-line, it confirms my hunch that this construct is not widely used in practice. - - -```js -// Before -do {} while ( - someVeryLongFunc( - someVeryLongArgA, - someVeryLongArgB, - someVeryLongArgC -) -); - -// After -do {} while ( - someVeryLongFunc( - someVeryLongArgA, - someVeryLongArgB, - someVeryLongArgC - ) -); -``` - -#### Break sequence expressions ([#2388](https://github.com/prettier/prettier/pull/2388)) by [@bakkot](https://github.com/bakkot) - -Another underused feature of JavaScript is sequence expressions. We used to do a bad job at printing them when they would go multi-line, this has been corrected :) - - -```js -// Before -(a = b ? c : "lllllllllllllllllllllll"), (a = b - ? c - : "lllllllllllllllllllllll"), (a = b ? c : "lllllllllllllllllllllll"), (a = b - ? c - : "lllllllllllllllllllllll"), (a = b ? c : "lllllllllllllllllllllll"); - -// After -(a = b ? c : 'lllllllllllllllllllllll'), - (a = b ? c : 'lllllllllllllllllllllll'), - (a = b ? c : 'lllllllllllllllllllllll'), - (a = b ? c : 'lllllllllllllllllllllll'), - (a = b ? c : 'lllllllllllllllllllllll') -``` - -#### Trim trailing whitespace from comments ([#2494](https://github.com/prettier/prettier/pull/2494)) by [@azz](https://github.com/azz) - -We took the stance with prettier to remove all the trailing whitespaces. We used to not touch comments because it's user generated, but that doesn't mean that they should have whitespace :) - - -```js -// Before -// There is some space here ->______________ - -// After -// There is some space here -> -``` - -#### Fix interleaved comments in class decorators ([#2660](https://github.com/prettier/prettier/pull/2660), [#2661](https://github.com/prettier/prettier/pull/2661)) - -Our handling for comments inside of the class declaration was very naive, we would just move all the comments to the top. We now are more precise and respect the comments that are interleaved inside of decorators and around `extends`. - - -```js -// Before -// A -// B -// C -@Foo() -@Bar() -class Bar {} - -// After -// A -@Foo() -// B -@Bar() -// C -class Bar {} -``` - -#### Improve bind expression formatting ([#2493](https://github.com/prettier/prettier/pull/2493)) by [@azz](https://github.com/azz) - -Bind expressions are being discussed at TC39 and we figured we could print it with prettier. We used to be very naive about it and just chain it. Now, we use the same logic as we have for method chaining with the `.` operator for it. We also fixed some edge cases where it would output invalid code. - - -```js -// Before -observable::filter(data => data.someTest)::throttle(() => - interval(10)::take(1)::takeUntil(observable::filter(data => someOtherTest)) -)::map(someFunction); - -// After -observable - ::filter(data => data.someTest) - ::throttle(() => - interval(10)::take(1)::takeUntil(observable::filter(data => someOtherTest)) - ) - ::map(someFunction); -``` - -#### Add support for printing optional catch binding ([#2570](https://github.com/prettier/prettier/pull/2570)) by [@existentialism](https://github.com/existentialism) - -It's being discussed at TC39 to be able to make the argument of a `catch(e)` optional. Let's make sure we can support it in prettier if people use it. - - -```js -// Before -Syntax error - -// After -try {} catch {} -``` - -#### Add support for printing optional chaining syntax ([#2572](https://github.com/prettier/prettier/pull/2572)) by [@azz](https://github.com/azz) - -Another new proposal being discussed at TC39 is an optional chaining syntax. This is currently a [stage 1 proposal](https://github.com/tc39/proposal-optional-chaining), so the syntax may change at any time. - - -```js -obj?.prop // optional static property access -obj?.[expr] // optional dynamic property access -func?.(...args) // optional function or method call -``` - -#### Handle Closure Compiler type cast syntax correctly ([#2484](https://github.com/prettier/prettier/pull/2484)) by [@yangsu](https://github.com/yangsu) - -Comments are tricky to get right, but especially when they have meaning based on where they are positioned. We're now special casing the way we deal with comments used as type cast for Closure Compiler such that they keep having the same semantics. - - -```js -// Before -let assignment /** @type {string} */ = getValue(); - -// After -let assignment = /** @type {string} */ (getValue()); -``` - -#### Inline first computed property lookup in member chain ([#2670](https://github.com/prettier/prettier/pull/2670)) by [@azz](https://github.com/azz) - -It looks kind of odd to have a computed property lookup on the next line, so we added a special case to inline it. - - -```js -// Before -data - [key]('foo') - .then(() => console.log('bar')) - .catch(() => console.log('baz')); - -// After -data[key]('foo') - .then(() => console.log('bar')) - .catch(() => console.log('baz')); -``` - -### Flow - -#### Support opaque types and export star ([#2543](https://github.com/prettier/prettier/pull/2543), [#2542](https://github.com/prettier/prettier/pull/2542)) by [@existentialism](https://github.com/existentialism) - -The flow team introduced two very exciting features under a new syntax. We now support them in prettier. I've personally been waiting for [opaque types](https://medium.com/flow-type/hiding-implementation-details-with-flows-new-opaque-type-aliases-feature-40e188c2a3f9) for a veerrryyyy long time! - - -```ts -// Before -Syntax error - -// After -opaque type ID = string; -export type * from "module"; -``` - -#### Strip away unnecessary quotes in keys in type objects and interfaces ([#2643](https://github.com/prettier/prettier/pull/2643)) by [@jackyho112](https://github.com/jackyho112) - -We've been doing this on JavaScript objects since the early days of prettier but forgot to apply the same thing to Flow and TypeScript types. - - -```ts -// Before -type A = { - "string": "A"; -} - -// After -type A = { - string: "A"; -} -``` - -#### Print TypeParameter even when unary function type ([#2406](https://github.com/prettier/prettier/pull/2406)) by [@danwang](https://github.com/danwang) - -Oopsy, we were dropping the generic in this very specific case. - - -```ts -// Before -type myFunction = A => B; - -// After -type myFunction = (A) => B; -``` - -#### Keep parens around FunctionTypeAnnotation inside ArrayTypeAnnotation ([#2561](https://github.com/prettier/prettier/pull/2561)) by [@azz](https://github.com/azz) - -Parenthesis... someday we'll get all of them fixed :) - - -```ts -// Before -const actionArray: () => void[] = []; - -// After -const actionArray: (() => void)[] = []; -``` - -### TypeScript - -#### Support TypeScript 2.5 RC ([#2672](https://github.com/prettier/prettier/pull/2672)) by [@azz](https://github.com/azz) - -[TypeScript 2.5 RC](https://blogs.msdn.microsoft.com/typescript/2017/08/17/announcing-typescript-2-5-rc/) was recently announced, allowing you to use the upcoming "optional catch binding" syntax in TypeScript, too. 🎉 - -#### Don't add namespace keyword to global declaration ([#2329](https://github.com/prettier/prettier/pull/2329)) by [@azz](https://github.com/azz) - - -```ts -// Before -namespace global { - export namespace JSX { } -} - -// After -global { - export namespace JSX {} -} -``` - -#### Fix ([#2472](https://github.com/prettier/prettier/pull/2472)) by [@backus](https://github.com/backus) - -Thanks to the untyped and permissive nature of JavaScript, we've been able to concat undefined to a string and get some interesting code as a result. Now fixed for this case :) - - -```jsx -// Before - - -// After - -``` - -#### Allow type assertions to hug ([#2439](https://github.com/prettier/prettier/pull/2439)) by [@azz](https://github.com/azz) - -We want to make sure that all the special cases that we added for JavaScript and Flow also work for TypeScript constructs. In this case, objects should also hug if they are wrapped in a `as` operator. - - -```js -// Before -const state = JSON.stringify( - { - next: window.location.href, - nonce, - } as State -); - -// After -const state = JSON.stringify({ - next: window.location.href, - nonce, -} as State); -``` - -#### Remove parens for type assertions in binary expressions ([#2419](https://github.com/prettier/prettier/pull/2419)) by [@azz](https://github.com/azz) - -Most of the time we add parenthesis for correctness but in this case, we added them for nothing, so we can just get rid of them and have a cleaner code :) - - -```ts -// Before -(a) || {}; - -// After -a || {}; -``` - -#### Print parens around type assertion as LHS in assignment ([#2525](https://github.com/prettier/prettier/pull/2525)) by [@azz](https://github.com/azz) - -Yet another case of missing parenthesis. Thankfully we're getting very few of them nowadays and they are for extremely rare edge cases. - - -```ts -// Before -foo.bar as Baz = [bar]; - -// After -(foo.bar as Baz) = [bar]; -``` - -#### Print declare for TSInterfaceDeclaration ([#2574](https://github.com/prettier/prettier/pull/2574)) by [@existentialism](https://github.com/existentialism) - -The `declare` keyword doesn't do anything for `interface` so we never put it there. However, it felt weird if you were in a declaration file and seeing everything have `declare` before it except for interfaces. So now we reprint `declare` if it was there in the first place. - - -```ts -// Before -interface Dictionary { - [index: string]: T -} - -// After -declare interface Dictionary { - [index: string]: T -} -``` - -### CSS - -#### Normalize quotes in CSS ([#2624](https://github.com/prettier/prettier/pull/2624)) by [@lydell](https://github.com/lydell) - -In order to get a first version of CSS to ship, we kept string quotes as is. We are now respecting the `singleQuote` option of prettier. The difficulty here was to make sure that we output correct code for all the crazy escapes, unicode characters, emoji, special rules like charset which only work with double quotes... - - -```css -// Before -div { - content: "abc"; -} - -// After -div { - content: 'abc'; -} -``` - -#### Normalize numbers in CSS ([#2627](https://github.com/prettier/prettier/pull/2627)) by [@lydell](https://github.com/lydell) - -Another place where we can reuse the logic we've done for JavaScript to improve CSS printing. - - -```css -// Before -foo { - border: 1px solid rgba(0., 0.0, .0, .3); -} - -// After -foo { - border: 1px solid rgba(0, 0, 0, 0.3); -} -``` - -#### Quote unquoted CSS attribute values in selectors ([#2644](https://github.com/prettier/prettier/pull/2644)) by [@lydell](https://github.com/lydell) - -I can never quite remember the rules behind quotes around attributes so we're now always putting quotes there. - - -```js -// Before -a[id=test] {} - -// After -a[id="test"] {} -``` - -#### Add support for css keyword ([#2337](https://github.com/prettier/prettier/pull/2337)) by [@zanza00](https://github.com/zanza00) - - -```js -// Before -const header = css`.top-bar {background: black;margin: 0;position: fixed;}` - -// After -const header = css` - .top-bar { - background: black; - margin: 0; - position: fixed; - } -`; -``` - -#### Support styled-components with existing component ([#2552](https://github.com/prettier/prettier/pull/2552), [#2619](https://github.com/prettier/prettier/pull/2619)) by [@azz](https://github.com/azz) - -styled-components has a lot of different variants for tagging template literals as CSS. It's not ideal that we've got to encode all those ways inside of prettier but since we started, might as well do it for real. - - -```js -styled(ExistingComponent)` - css: property; -`; - -styled.button.attr({})` - border: rebeccapurple; -`; -``` - -#### Trim whitespace in descendant combinator ([#2411](https://github.com/prettier/prettier/pull/2411)) by [@azz](https://github.com/azz) - -The CSS parsers we use do not give us a 100% semantic tree: in many occasions they bail and just give us what is being entered. It's up to us to make sure we clean this up while maintaining correctness. In this case, we just printed spaces between selectors as is but we know it's correct to always replace it by a single space. - - -```cs -// Before -.hello - - .how-you-doin { - height: 42; -} - -// After -.hello .how-you-doin { - height: 42; -} -``` - -#### Strip BOM before parsing ([#2373](https://github.com/prettier/prettier/pull/2373)) by [@azz](https://github.com/azz) - -I still have nightmares from dealing with [BOM](https://en.wikipedia.org/wiki/Byte_order_mark) in a previous life. Thankfully, in 2017 it's no longer a big issue as most tooling is now aware of it. Thanks [@azz](https://github.com/azz) for fixing an edge cases related to CSS parsing. - - -```css -// Before -[BOM]/* Block comment * -html { - content: "#{1}"; -} -``` - - -```css -// After -[BOM]/* Block comment */ -html { - content: "#{1}"; -} -``` - -### GraphQL - -#### Add support for range-formatting GraphQL ([#2319](https://github.com/prettier/prettier/pull/2319)) by [@josephfrazier](https://github.com/josephfrazier) - -If you tried to use the range formatting feature in a GraphQL file, it would throw an exception, now it properly worked again and only reformats the piece you selected. - -#### Add `.gql` file extension to be parsed as GraphQL ([#2357](https://github.com/prettier/prettier/pull/2357)) by [@rrdelaney](https://github.com/rrdelaney) - -At Facebook, we use `.graphql` extension but it looks like it's common to have `.gql` as well, doesn't cost a lot to support it in the heuristic that figures out what parser to use. - -### CLI - -#### Support multiple patterns with ignore pattern ([#2356](https://github.com/prettier/prettier/pull/2356)) by [@evilebottnawi](https://github.com/evilebottnawi) - -It was already possible to have multiple glob patterns but they would be additive, with this change, you can add a glob pattern to ignore some files. It should be very handy to ignore folders that are deeply nested. - - -```sh -prettier --write '{**/*,*}.{js,jsx,json}' '!vendor/**' -``` - -#### Make --list-different to work with --stdin ([#2393](https://github.com/prettier/prettier/pull/2393)) by [@josephfrazier](https://github.com/josephfrazier) - -This is a handy way of knowing if prettier would print a piece of code in a different way. We already had all the concepts in place, we just needed to wire them up correctly. - - -```shellsession -$ echo 'call ( ) ;' | prettier --list-different -(stdin) -$ echo $? -1 -``` diff --git a/website/blog/2017-09-15-1.7.0.md b/website/blog/2017-09-15-1.7.0.md deleted file mode 100644 index 9a0f0ef29b..0000000000 --- a/website/blog/2017-09-15-1.7.0.md +++ /dev/null @@ -1,219 +0,0 @@ ---- -author: @suchipi -authorURL: https://twitter.com/suchipi -title: "Prettier 1.7: JSX tweaks, Pragma, TypeScript and CSS fixes" ---- - -This release features some bugfixes and tweaks around JSX, TypeScript, CSS, and JavaScript formatting, as well as a couple new features. - - - -## Highlights - -### JSX Changes - -We received a lot of community feedback about the changes we made to JSX formatting in the 1.6.0 release, and have made changes to bring formatting closer to community standards and expectations. - -In 1.6.0, we added a second style for ternaries (conditional expressions, `a ? b : c`), based on a format popular in the community where parentheses are used to demarcate JSX content: - - -```jsx -const DinnerOptions = ({ willEatMeat, willEatEggs, willEatVegetables }) => ( -
-
Let's get some dinner...
- {willEatMeat ? ( - - ) : willEatEggs ? ( - - ) : willEatVegetables ? ( - - ) : ( - - )} -
-); -``` - -Before this was added, prettier only formatted ternaries with one consistent style: - - -```jsx -willEatMeat - ? "Full Menu" - : willEatEggs - ? "Vegetarian Menu" - : willEatVegetables ? "Vegan Menu" : "Backup Menu"; -``` - -In 1.6.0, we used the following heuristic to decide when to use the new "JSX mode ternaries": - -``` -We should print a ternary using JSX mode if: - * The ternary contains some JSX in it - OR - * The ternary appears inside of some JSX -``` - -However, this heuristic caused some [unexpected formatting](https://github.com/prettier/prettier/issues/2729): -![GitHub Diff showing a ternary containing internationalization strings appearing inside a JSX element being converted to use JSX-mode style ternaries](/blog/assets/github-diff-ternary-in-jsx.png) - -So, in 1.7.0, we have revised our heuristic to just be: - -``` -We should print a ternary using JSX mode if: - * The ternary contains some JSX in it -``` - -We hope that this change will result in fewer surprising ternaries. - -A big thanks goes out to [@duailibe](https://github.com/duailibe) who implemented this change in addition to several other JSX-related formatting issues that were reported. - -### CSS Letter Case Consistency - -We spent some time this release polishing our CSS formatting, and as part of that, [@lydell](https://github.com/lydell) [did some work to normalize letter case](https://github.com/prettier/prettier/issues/2653). - -So now, almost everything in CSS will print using `lower case`. - - -```css -/* Before */ -DIV.Foo { - HEIGHT: 12PX; -} - -/* After */ -div.Foo { - height: 12px; -} -``` - -Don't worry, though – Prettier won't touch your `$scss-variables`, `[@less](https://github.com/less)-variables`, or `FunctionNames()`. Preprocess on! - -### Pragma Support - -There is a new option called `--require-pragma` (`requirePragma` via the API) which will change prettier's behavior so that it only reformats a file if it has a special "pragma" comment at the top of it, that looks like this: - - -```js -/** - * @prettier - */ -``` - -or - - -```js -/** - * @format - */ -``` - -This was [@ajhyndman](https://github.com/ajhyndman)'s idea and it was implemented by [@wbinnssmith](https://github.com/wbinnssmith). - -## Other Changes - -### TypeScript - -There was a bug in Prettier 1.6.1 where an error would be thrown while parsing any TypeScript using the `never` type, for example: - -```ts -Observable.empty(); -``` - -Also, Prettier 1.6.1 was incorrectly removing the `declare` keyword from `enum` declarations in `*.d.ts` files: - - -```ts -// In -declare const enum Foo {} - -// Out -const enum Foo {} -``` - -Both of these issues have been fixed. Thanks to [@JamesHenry](https://github.com/JamesHenry) and [@existentialism](https://github.com/existentialism) for these fixes which support our TypeScript community! - -### Configuration - -#### Configurable Config Precedence - -There is a new CLI option `--config-precedence` which configures how prettier should prioritize config sources. Valid values are: - -**`cli-override`** (default) - CLI options take precedence over config file - -**`file-override`** - Config file take precedence over CLI options - -**`prefer-file`** - If a config file is found will evaluate it and ignore other CLI options. If no config file is found CLI options will evaluate as normal. - -This option adds support to editor integrations where users define their default configuration but want to respect project specific configuration. - -#### `prettier.resolveConfig.sync` - -Previously, there was no way via the API to resolve configuration for a source file synchronously. Thanks to [some new additions to `cosmiconfig`](https://github.com/davidtheclark/cosmiconfig/pull/78) by [@sudo](https://github.com/sudo)-suhas, [@ikatyang](https://github.com/ikatyang) was able to add support for this to the prettier API. - -### PRs merged in this release - -- [**Update README.md**](https://github.com/prettier/prettier/pull/2690) by [@ikatyang](https://github.com/ikatyang) -- [**Fix config file finding when using stdin**](https://github.com/prettier/prettier/pull/2692) by [@lydell](https://github.com/lydell) -- [**docs(readme): add and sort cli options**](https://github.com/prettier/prettier/pull/2700) by [@levithomason](https://github.com/levithomason) -- [**Add Transloadit as a user**](https://github.com/prettier/prettier/pull/2706) by [@kvz](https://github.com/kvz) -- [**Ensure parens around LogicalExpression inside ExperimentalSpreadProperty**](https://github.com/prettier/prettier/pull/2710) by [@existentialism](https://github.com/existentialism) -- [**Fix printing declare modifier for TS enum**](https://github.com/prettier/prettier/pull/2711) by [@existentialism](https://github.com/existentialism) -- [**Handle +/- before numbers in CSS**](https://github.com/prettier/prettier/pull/2713) by [@xtian](https://github.com/xtian) -- [**Add Tradeshift as a user**](https://github.com/prettier/prettier/pull/2719) by [@sampi](https://github.com/sampi) -- [**feat(resolve-config): add `.sync()` method**](https://github.com/prettier/prettier/pull/2722) by [@ikatyang](https://github.com/ikatyang) -- [**refactor(bin): use `resolveConfigFile.sync()`**](https://github.com/prettier/prettier/pull/2728) by [@ikatyang](https://github.com/ikatyang) -- [**refactor(cli): separate files and make it pure as possible**](https://github.com/prettier/prettier/pull/2730) by [@ikatyang](https://github.com/ikatyang) -- [**Fix cosmiconfig dependency branch**](https://github.com/prettier/prettier/pull/2731) by [@josephfrazier](https://github.com/josephfrazier) -- [**Upgrade chalk to v2.1.0**](https://github.com/prettier/prettier/pull/2732) by [@josephfrazier](https://github.com/josephfrazier) -- [**Add CLI option '--config-precedence'**](https://github.com/prettier/prettier/pull/2733) by [@mitermayer](https://github.com/mitermayer) -- [**Normalize CSS case**](https://github.com/prettier/prettier/pull/2736) by [@lydell](https://github.com/lydell) -- [**Make run-external-typescript-tests.js cross-platform**](https://github.com/prettier/prettier/pull/2737) by [@lydell](https://github.com/lydell) -- [**test(integration): add more tests**](https://github.com/prettier/prettier/pull/2738) by [@ikatyang](https://github.com/ikatyang) -- [**chore(deps): remove devDependency `cross-spawn`**](https://github.com/prettier/prettier/pull/2739) by [@ikatyang](https://github.com/ikatyang) -- [**Ignore some things in coverage**](https://github.com/prettier/prettier/pull/2741) by [@lydell](https://github.com/lydell) -- [**Generalize run-external-typescript-tests.js**](https://github.com/prettier/prettier/pull/2742) by [@lydell](https://github.com/lydell) -- [**Improve lint-staged setup example by adding more filetypes**](https://github.com/prettier/prettier/pull/2746) by [@MoOx](https://github.com/MoOx) -- [**fixes dynamic imports**](https://github.com/prettier/prettier/pull/2748) by [@rkurbatov](https://github.com/rkurbatov) -- [**Refactor error handling**](https://github.com/prettier/prettier/pull/2750) by [@azz](https://github.com/azz) -- [**chore(github): add issue template**](https://github.com/prettier/prettier/pull/2755) by [@ikatyang](https://github.com/ikatyang) -- [**Fix: TypeScript never keyword (fixes [#2718](https://github.com/prettier/prettier/pull/2718))**](https://github.com/prettier/prettier/pull/2756) by [@JamesHenry](https://github.com/JamesHenry) -- [**Group last argument if it's an empty object with a comment**](https://github.com/prettier/prettier/pull/2758) by [@duailibe](https://github.com/duailibe) -- [**Use `files:` over `types:` in pre-commit configuration**](https://github.com/prettier/prettier/pull/2759) by [@asottile](https://github.com/asottile) -- [**refactor(runPrettier): reduce duplicate code**](https://github.com/prettier/prettier/pull/2764) by [@ikatyang](https://github.com/ikatyang) -- [**Change when to print ternaries in JSX mode**](https://github.com/prettier/prettier/pull/2768) by [@duailibe](https://github.com/duailibe) -- [**Fix chained logical expressions with objects/array/etc inlined**](https://github.com/prettier/prettier/pull/2770) by [@duailibe](https://github.com/duailibe) -- [**Add option to require @prettier or @format pragma**](https://github.com/prettier/prettier/pull/2772) by [@wbinnssmith](https://github.com/wbinnssmith) -- [**chore(build): update ISSUE_TEMPLATE.md before publish**](https://github.com/prettier/prettier/pull/2776) by [@ikatyang](https://github.com/ikatyang) -- [**Fix break on conditional expressions inside return**](https://github.com/prettier/prettier/pull/2779) by [@duailibe](https://github.com/duailibe) -- [**Support graphql(schema, `query`)**](https://github.com/prettier/prettier/pull/2781) by [@azz](https://github.com/azz) -- [**fix(prettierignore): support absolute filename**](https://github.com/prettier/prettier/pull/2783) by [@ambar](https://github.com/ambar) -- [**Keep conditional expressions in one line on method chains**](https://github.com/prettier/prettier/pull/2784) by [@duailibe](https://github.com/duailibe) -- [**fix(build): update ISSUE_TEMPLATE using regex `?:` instead of `?!`**](https://github.com/prettier/prettier/pull/2785) by [@ikatyang](https://github.com/ikatyang) -- [**Break closing paren of ConditionalExpression in member chains**](https://github.com/prettier/prettier/pull/2786) by [@duailibe](https://github.com/duailibe) -- [**fix webstorm integration guide**](https://github.com/prettier/prettier/pull/2796) by [@xsburg](https://github.com/xsburg) - -### Issues resolved in this release - -- [**Document missing CLI options**](https://github.com/prettier/prettier/issues/2698) reported by [@levithomason](https://github.com/levithomason) -- [**Formatting of Spread Properties differs between Babylon and TypeScript**](https://github.com/prettier/prettier/issues/2708) reported by [@mariusschulz](https://github.com/mariusschulz) -- [**Removal of the `declare` modifier from `enum`**](https://github.com/prettier/prettier/issues/2709) reported by [@mariusschulz](https://github.com/mariusschulz) -- [**Decimal formatting doesn't get all decimals in a rule.**](https://github.com/prettier/prettier/issues/2712) reported by [@itsgreggreg](https://github.com/itsgreggreg) -- [**Use resolveConfigFile.sync in the CLI**](https://github.com/prettier/prettier/issues/2726) reported by [@azz](https://github.com/azz) -- [**CSS: Normalize case (lower vs upper) on stuff**](https://github.com/prettier/prettier/issues/2653) reported by [@lydell](https://github.com/lydell) -- [**Dynamic import with webpackChunkName comment fails**](https://github.com/prettier/prettier/issues/1489) reported by [@pbomb](https://github.com/pbomb) -- [**TypeScript: never as type parameter causes error: unknown type: undefined**](https://github.com/prettier/prettier/issues/2718) reported by [@hccampos](https://github.com/hccampos) -- [**commented object values**](https://github.com/prettier/prettier/issues/2617) reported by [@sylvainbaronnet](https://github.com/sylvainbaronnet) -- [**Configuring pre-commit for jsx, TypeScript, tsx**](https://github.com/prettier/prettier/issues/2745) reported by [@reywright](https://github.com/reywright) -- [**JSX ternaries include parens**](https://github.com/prettier/prettier/issues/2729) reported by [@jasonLaster](https://github.com/jasonLaster) -- [**Chained Short Circuit Conditionals in JSX**](https://github.com/prettier/prettier/issues/2714) reported by [@brycehill](https://github.com/brycehill) -- [**Support @prettier pragma comment**](https://github.com/prettier/prettier/issues/2397) reported by [@ajhyndman](https://github.com/ajhyndman) -- [**No indentation after breaking return statement**](https://github.com/prettier/prettier/issues/2777) reported by [@jwbay](https://github.com/jwbay) -- [**Support graphql() fn and so make 2nd arg prettier**](https://github.com/prettier/prettier/issues/2780) reported by [@brikou](https://github.com/brikou) -- [**prettierignore: cannot use absolute filename**](https://github.com/prettier/prettier/issues/2782) reported by [@ambar](https://github.com/ambar) -- [**Weird JavaScript format**](https://github.com/prettier/prettier/issues/2775) reported by [@maxime1992](https://github.com/maxime1992) - ---- - -Thank you to everyone who contributed to this release, be it through issue creation, code contribution, code review, or general commenting and feedback. Prettier is a community-run project and is able to continue to exist thanks to people like you. Thank you! diff --git a/website/blog/2017-11-07-1.8.0.md b/website/blog/2017-11-07-1.8.0.md deleted file mode 100644 index 1632239830..0000000000 --- a/website/blog/2017-11-07-1.8.0.md +++ /dev/null @@ -1,666 +0,0 @@ ---- -author: Lucas Azzola (@azz) -authorURL: https://twitter.com/lucasazzola -title: "Prettier 1.8: Markdown Support" ---- - -This release adds Markdown support, a new `--insert-pragma` flag, fixes a number of formatting issues, adds support for some new _experimental_ operators, and improves our editor integration support. - - - -## Highlights - -### Markdown Support - -#### Support markdown ([#2943](https://github.com/prettier/prettier/pull/2943)) by [@ikatyang](https://github.com/ikatyang) - -You can now run Prettier on Markdown files! 🎉 - -The implementation is highly compliant with the [CommonMark spec](http://commonmark.org/), and backed by the excellent [`remark-parse`](https://github.com/wooorm/remark/tree/master/packages/remark-parse) package. - -**Word Wrap** - -One of Prettier's core features is its ability to wrap code at a specified line length. This applies to Markdown too, which means you can maintain nice and clean 80-character-wide Markdown files without having to re-adjust line breaks manually when you add or delete words. - -Input: - -``` -Voilà! In view, a humble vaudevillian veteran cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valourous visitation of a bygone vexation stands vivified and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition! The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honour to meet you and you may call me V. -``` - -Output: - -``` -Voilà! In view, a humble vaudevillian veteran cast vicariously as both victim -and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, -is a vestige of the vox populi, now vacant, vanished. However, this valourous -visitation of a bygone vexation stands vivified and has vowed to vanquish these -venal and virulent vermin vanguarding vice and vouchsafing the violently vicious -and voracious violation of volition! The only verdict is vengeance; a vendetta -held as a votive, not in vain, for the value and veracity of such shall one day -vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage -veers most verbose, so let me simply add that it's my very good honour to meet -you and you may call me V. -``` - -> ~~Note: We're considering adding an option for this, check [#3183](https://github.com/prettier/prettier/pull/3183) for discussion.~~ -> Update: We've added an option in `1.8.2` called [`--no-prose-wrap`](https://prettier.io/docs/en/options.html#prose-wrap) - -> Note for CJK users: If your markdown renderer does not support CJK line ending, you'll have to use plugin like [markdown-it-perfect-newline-for-cjk](https://www.npmjs.com/package/markdown-it-perfect-newline-for-cjk), [hexo-filter-fix-cjk-spacing](https://www.npmjs.com/package/hexo-filter-fix-cjk-spacing), etc. to remove additional spaces. -> -> ``` -> // Source -> 一二三 -> 四五六 -> 七八九 -> -> // Rendered content with unsupported renderer -> 一二三 四五六 七八九 -> -> // Rendered content with supported renderer or via plugin -> 一二三四五六七八九 -> ``` - -**Code Formatting** - -Powered by Prettier's generic "multiparser", Prettier will format code blocks in Markdown! We use the language code provided with the code block to determine which language it is, and thus we can format any language that Prettier supports (including Markdown itself, if you're into that). - -Input: - - -````md -```js -reallyUgly ( -javascript - ) -``` - -```css -.h1 { color : red } -``` -```` - -Output: - -````md -```js -reallyUgly(javascript); -``` - -```css -.h1 { - color: red; -} -``` -```` - - -> Note: In some cases you may not want to format your code in Markdown, and just like in other languages, in Markdown you can use an ignore comment before the code block to ignore it from formatting: -> -> ````md -> -> ```js -> ugly ( code ) ; -> ``` -> ```` - -**Lists** - -When rearranging list items, after running Prettier all the numbers will be fixed! - -![Markdown Lists](/blog/assets/markdown-lists.gif) - -> Note: you can actually opt out of this by using `1.` for all list items if you want to optimize for cleaner diffs. - -**Tables** - -Tables will also automatically be adjusted to fit their contents. This could be completely unmaintainable without an automated tool. - -![Markdown Tables](/blog/assets/markdown-tables.gif) - -**Markdown-in-JS** - -By using either `md` or `markdown` tagged template literals, you can format markdown code inside JavaScript. - - -```js -const markdown = md` - # heading - - 1. list item -`; -``` - -### CLI - -#### Add option to insert `@format` to first docblock if absent ([#2865](https://github.com/prettier/prettier/pull/2865)) by [@samouri](https://github.com/samouri) - -In 1.7, we added an option called `--require-pragma` to require files contain an `/** @format */` pragma to be formatted. In order to add this pragma to a large set of files you can now use [`--insert-pragma`](https://prettier.io/docs/en/cli.html#insert-pragma) flag. - -``` -prettier --write "folder/**/*.js" --insert-pragma -``` - -#### Add `--loglevel` option ([#2992](https://github.com/prettier/prettier/pull/2992)) by [@ikatyang](https://github.com/ikatyang) - -This [nifty feature](https://prettier.io/docs/en/cli.html#loglevel) allows you to opt in (or out) of Prettier's logging. We've also cleaned up the logging substantially since 1.7. - - -```bash -$ prettier --loglevel=debug blarg -$ ./bin/prettier.js --loglevel=debug blarg -[debug] normalized argv: {"_":["blarg"],"bracket-spacing":false,"color":true,"debug-check":false,"debug-print-doc":false,"flow-parser":false,"insert-pragma":false,"jsx-bracket-same-line":false,"list-different":false,"require-pragma":false,"semi":false,"single-quote":false,"stdin":false,"use-tabs":false,"version":false,"with-node-modules":false,"write":false,"loglevel":"debug","ignore-path":".prettierignore","config-precedence":"cli-override"} -[error] No matching files. Patterns tried: blarg !**/node_modules/** !./node_modules/** - -``` - -### JavaScript - -#### Fix indentation for JSDoc comments ([#2470](https://github.com/prettier/prettier/pull/2470)) by [@maxdeviant](https://github.com/maxdeviant) - -This has been a long-time known issue with Prettier. When formatting code that results in a change of indentation level, the JSDoc comments would end up being out of alignment. We're happy to report this is now fixed! - - -```js -// Before -function theFunction2(action$, store) { - /* - * comments - */ - return true; -} - -// After -function theFunction2(action$, store) { - /* - * comments - */ - return true; -} -``` - -#### Print pipeline and nullish-coalescing operators ([#3036](https://github.com/prettier/prettier/pull/3036)) by [@azz](https://github.com/azz) - -We've added support for two new proposed operators to Prettier: the _pipeline operator_ and the _nullish coalescing operator_. - -The [pipeline operator](https://github.com/tc39/proposal-pipeline-operator/) is currently a stage one proposal. - -> This proposal introduces a new operator |> similar to F#, OCaml, Elixir, Elm, Julia, Hack, and LiveScript, as well as UNIX pipes. It's a backwards-compatible way of streamlining chained function calls in a readable, functional manner, and provides a practical alternative to extending built-in prototypes. - - -```js -// Before -let result = exclaim(capitalize(doubleSay("hello"))); - -// After -let result = "hello" - |> doubleSay - |> capitalize - |> exclaim; -``` - -The [nullish coalescing operator](https://github.com/tc39-transfer/proposal-nullish-coalescing) is another stage one proposal. - -> When performing optional property access in a nested structure in conjunction with the optional chaining operator, it is often desired to provide a default value if the result of that property access is null or undefined. - -This operator is similar to `||` except it only evaluates the right-hand-side if the left is `undefined` or `null`, not `""`, `0`, `NaN`, etc. - - -```js -const foo = object.foo ?? "default"; -``` - -#### Improved template literal expressions line breaks ([#3124](https://github.com/prettier/prettier/pull/3124)) by [@duailibe](https://github.com/duailibe) - -This was another known issue with Prettier, when printing a template literal string with expressions inside that went over the print width, it would wrap the code in weird places inside the expressions. Now, if Prettier needs to insert a line break, it should happen right between `${` and `}`. - - -```jsx -// Before -const description = `The value of the ${cssName} css of the ${this - ._name} element`; - -const foo = `mdl-textfield mdl-js-textfield ${className} ${content.length > 0 - ? "is-dirty" - : ""} combo-box__input`; - -// After -const description = `The value of the \${cssName} css of the \${ - this._name -} element`; - -const foo = `mdl-textfield mdl-js-textfield ${className} ${ - content.length > 0 ? 'is-dirty' : '' -} combo-box__input` -``` - -### JSX - -#### Don't inline trailing `}` for arrow functions attributes ([#3110](https://github.com/prettier/prettier/pull/3110)) by [@duailibe](https://github.com/duailibe) - -In order to align closer to the [Airbnb style guide](https://github.com/airbnb/javascript/), and since it was never intentionally printed this way, we've moved the `}` from to the next line in JSX. This is more diff friendly, and makes it easier to move code around by shifting lines in your editor. - - -```jsx -// Before - - doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)} -/>; - -// After - - doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data) - } -/>; -``` - -## Other Changes - -### JavaScript - -#### Make the factory detection handle multiple elements ([#3112](https://github.com/prettier/prettier/pull/3112)) by [@vjeux](https://github.com/vjeux) - -There was a bug in the heuristic that Prettier uses to determine whether an expression is a factory or not. It now works correctly with longer member expressions. - - -```js -// Before -window.FooClient - .setVars({ - locale: getFooLocale({ page }), - authorizationToken: data.token - }) - .initVerify("foo_container"); - -// After -window.FooClient.setVars({ - locale: getFooLocale({ page }), - authorizationToken: data.token -}).initVerify("foo_container"); -``` - -#### Handle comments between function name and open paren ([#2979](https://github.com/prettier/prettier/pull/2979)) by [@azz](https://github.com/azz) - -Printing comments in the right place is an endless challenge 😉. This fix ensures that comments next to function names are re-printed correctly. - - -```js -// Before -function f(/* comment*/ promise) {} - -// After -function f /* comment*/(promise) {} -``` - -#### Support sequential CallExpressions in member chains ([#2990](https://github.com/prettier/prettier/pull/2990)) by [@chrisvoll](https://github.com/chrisvoll) - -Member chains are one of the most complex parts of Prettier. This PR fixes an issue where repeated calls lead to the next method not being pushed to the next line. - - -```js -// Before -wrapper - .find("SomewhatLongNodeName") - .prop("longPropFunctionName")().then(function() { - doSomething(); -}); - -// After -wrapper - .find("SomewhatLongNodeName") - .prop("longPropFunctionName")() - .then(function() { - doSomething(); - }); -``` - -#### Account for empty lines in long member call chain ([#3035](https://github.com/prettier/prettier/pull/3035)) by [@jackyho112](https://github.com/jackyho112) - -Previously, Prettier would delete all newlines within a member chain. Now we keep up to one if it's in the source. This is nice for fluent APIs that you want to break up over multiple lines. - - -```js -angular - .module("AngularAppModule") - - // Constants. - .constant("API_URL", "http://localhost:8080/api") - - // App configuration. - .config(appConfig) - .run(appRun); -``` - -#### Fix issue where first argument is left behind when line breaks ([#3079](https://github.com/prettier/prettier/pull/3079)) by [@mutdmour](https://github.com/mutdmour) - -This addresses an issue where due to our special object inline behaviour, the indentation missing from the function call. - - -```js -// Before -db.collection("indexOptionDefault").createIndex({ a: 1 }, -{ - indexOptionDefaults: true -}, -function(err) { - // code -}); - -// After -db.collection("indexOptionDefault").createIndex( - { a: 1 }, - { - indexOptionDefaults: true - }, - function(err) { - // code - } -); -``` - -#### Break parens for binaries in member expression ([#2958](https://github.com/prettier/prettier/pull/2958)) by [@duailibe](https://github.com/duailibe) - -Similarly, there was another edge case where indentation was missing from logical expressions. This is fixed, too. - - -```js -// Before -const someLongVariable = (idx( - this.props, - props => props.someLongPropertyName -) || [] -).map(edge => edge.node); - -// After -const someLongVariable = ( - idx(this.props, props => props.someLongPropertyName) || [] -).map(edge => edge.node); -``` - -#### Prevent breaking MemberExpression inside NewExpression ([#3075](https://github.com/prettier/prettier/pull/3075)) by [@duailibe](https://github.com/duailibe) - -There are so many ways to break a line. Some of them look much worse than others. Breaking between in this case looked really weird, so it has been fixed! - - -```js -// Before -function functionName() { - if (true) { - this._aVeryLongVariableNameToForceLineBreak = new this - .Promise((resolve, reject) => { - // do something - }); - } -} - -// After -function functionName() { - if (true) { - this._aVeryLongVariableNameToForceLineBreak = new this.Promise( - (resolve, reject) => { - // do something - } - ); - } -} -``` - -#### Fix array accessors in method chains ([#3137](https://github.com/prettier/prettier/pull/3137)) by [@duailibe](https://github.com/duailibe) - -In a method chain we split lines by grouping elements together and accessing an array should be printed in the end of a group instead of the beginning. - - -```js -// Before -find('.org-lclp-edit-copy-url-banner__link') - [0].getAttribute('href') - .indexOf(this.landingPageLink) - -// After -find('.org-lclp-edit-copy-url-banner__link')[0] - .getAttribute('href') - .indexOf(this.landingPageLink) -``` - -### Flow and TypeScript - -#### Fix indentation of intersection object types ([#3074](https://github.com/prettier/prettier/pull/3074)) by [@duailibe](https://github.com/duailibe) - -This was a minor alignment bug in intersection types, and has now been fixed. - - -```js -// Before -type intersectionTest = { - propA: X -} & { - propB: X -} & { - propC: X - } & { - propD: X - }; - -// After -type Props = { - propA: X -} & { - propB: X -} & { - propC: X -} & { - propD: X -}; -``` - -#### Keep parens around TSAsExpression in ConditionalExpression ([#3053](https://github.com/prettier/prettier/pull/3053)) by [@azz](https://github.com/azz) - -We missed a case where we need to keep the parenthesis with TypeScript's `as` assertions. This is now fixed. - - -```ts -// Before -aValue as boolean ? 0 : -1; - -// After -(aValue as boolean) ? 0 : -1; -``` - -### JSX - -#### Collapse multiple JSX whitespaces ([#2973](https://github.com/prettier/prettier/pull/2973)) by [@karl](https://github.com/karl) - -This fixes up the issue where JSX formatting occasionally needed to be run twice to become stable. This occurred when you had multiple JSX whitespace elements or JSX whitespace followed by a space. - - -```jsx -// Before -
- {" "} -
; - -// After -
- {" "} - -
-``` - -#### Don't print JSX bracket on same line when it has trailing comments ([#3088](https://github.com/prettier/prettier/pull/3088)) by [@azz](https://github.com/azz) - -This was an issue with the `--jsx-bracket-same-line` option. Turns out you can't _always_ put the bracket on the same line... - - -```jsx -// Input -
- {foo} -
- -// Before -
-// comment - {foo} -
; - -// After -
- {foo} -
; -``` - -### CSS - -#### Preserve line breaks in grid declarations ([#3133](https://github.com/prettier/prettier/pull/3133)) by [@duailibe](https://github.com/duailibe) - -Prettier will now preserve line breaks included in the source code when formatting the `grid` and `grid-template-*` rules, since those are important to keep in separate lines, but still applies the formatting like other rules (e.g., numbers and quotes). - - -```css -/* Original Input */ -div { - grid: - [wide-start] 'header header header' 200.000px - [wide-end] "footer footer footer" .50fr - / auto 50.000px auto; -} - -/* Before */ -div { - grid: [wide-start] "header header header" 200px [wide-end] - "footer footer footer" 0.5fr / auto 50px auto; -} - -/* After */ -div { - grid: - [wide-start] "header header header" 200px - [wide-end] "footer footer footer" 0.5fr - / auto 50px auto; -} -``` - -### SCSS - -#### Format SCSS maps like CSS rules ([#3070](https://github.com/prettier/prettier/pull/3070)) by [@asmockler](https://github.com/asmockler) - -Turns out SCSS maps are much prettier when printed over multiple lines. - - -```scss -// Before -$map: (color: [#111111](https://github.com/prettier/prettier/pull/111111), text-shadow: 1px 1px 0 salmon) - -// After -$map: ( - color: [#111111](https://github.com/prettier/prettier/pull/111111), - text-shadow: 1px 1px 0 salmon -); -``` - -### CSS-in-JS - -#### Fix formatting styled(Foo).attrs(...)`` ([#3073](https://github.com/prettier/prettier/pull/3073)) by [@existentialism](https://github.com/existentialism) - -Prettier will now format the CSS in styled-components code that looks like this: - - -```js -styled(Component).attrs({})` - color: red; -`; -``` - -### GraphQL - -#### Prevent formatting GraphQL template literals with expressions ([#2975](https://github.com/prettier/prettier/pull/2975)) by [@duailibe](https://github.com/duailibe) - -Prettier doesn't support formatting JavaScript expressions in GraphQL. See [#2640](https://github.com/prettier/prettier/pull/2640) for tracking. There was a bug where formatting an expression lead to invalid code, so we've completely disabled formatting GraphQL when it contains JavaScript expressions until we fully support it. - - -```js -// Before -(invalid code) - -// After -graphql(schema, `{ query test { id }} ${fragment}`) -``` - -### CLI - -#### Don't use ANSI codes if stdout isn't a TTY ([#2903](https://github.com/prettier/prettier/pull/2903)) by [@Narigo](https://github.com/Narigo) - -Previously, piping the output of `--list-different` to other tools was troublesome due to the ANSI color codes we use to show whether a file was modified or not. This PR disables the use of color when Prettier is piped to a different process. - -### Configuration - -#### Use relative paths with CLI ([#2969](https://github.com/prettier/prettier/pull/2969)) by [@ahmedelgabri](https://github.com/ahmedelgabri) - -This fixes a bug where passing a path starting with `./` to the CLI wouldn't match patterns used in `.prettierignore`. - -``` -## .prettierignore -path/to/*.js -``` - -After this fix, no files will be written to when executing: - - -```bash -$ prettier --write ./path/to/*.js -``` - -#### Resolve file paths relative to config file ([#3037](https://github.com/prettier/prettier/pull/3037)) by [@azz](https://github.com/azz) - -This fixes an issue where `.prettierrc` overrides, under certain conditions, were not being respected for absolute paths with the `resolveConfig` API. - -### Core - -#### Respect CJK width and Combined Characters ([#3003](https://github.com/prettier/prettier/pull/3003), [#3015](https://github.com/prettier/prettier/pull/3015)) by [@ikatyang](https://github.com/ikatyang) - -Chinese, Japanese and Korean characters are now considered two characters wide. - - -```js -// Before (exceeds print width when CJK characters are 2x monospace chars) -const x = ["中文", "中文", "中文", "中文", "中文", "中文", "中文", "中文", "中文", "中文", "中文"]; - -// After -const x = [ - "中文", - // ... - "中文" -]; -``` - -#[#3015](https://github.com/prettier/prettier/pull/3015) also ensures that combining characters (e.g. `Á`) are counted as one character. - -### Editor Support - -#### Implement getSupportInfo() and use it for inference ([#3033](https://github.com/prettier/prettier/pull/3033)) by [@azz](https://github.com/azz) - -We've added a new function to the API (`prettier.getSupportInfo([version])`), and the CLI `--support-info`. This can be used to interrogate Prettier to find out which languages the current version, or an older version, supports. It also provides useful information such as CodeMirror IDs, tmScopes, etc, which can be used to automate some of the work done with lookup tables in text editor integrations. - -Internally, we use this information to drive which extensions trigger which parsers, and support some common files that don't have extensions, like `.prettierrc`, `Jakefile`, etc. - - -```bash -## prettier knows that this file is JSON now. -$ prettier --write .prettierrc -``` - -#### Split source elements relative to their language. ([#3069](https://github.com/prettier/prettier/pull/3069)) by [@CiGit](https://github.com/CiGit) - -This fixes an issue in editors that support range formatting, where formatting an object would cause Prettier to crash. - ---- - -## Thanks! ❤️ - -Thanks to everyone who contributed to this release, as well as those who raised issues! Prettier has become a highly stable piece of software that a large amount of people trust with their code. We take that trust seriously, and fix rare issues that break code with the highest priority. We can't fix these issues if we don't know about them, so never be afraid to [create an issue](https://github.com/prettier/prettier/issues/new)! diff --git a/website/blog/2017-12-05-1.9.0.md b/website/blog/2017-12-05-1.9.0.md deleted file mode 100644 index 87b0922fd8..0000000000 --- a/website/blog/2017-12-05-1.9.0.md +++ /dev/null @@ -1,321 +0,0 @@ ---- -author: Lucas Duailibe (@duailibe) -authorURL: https://twitter.com/duailibe -title: "Prettier 1.9: JSX Fragments, EditorConfig and Arrow Parens" ---- - -This release adds an option for arrow function parens in arguments, support for the [new JSX fragment syntax (`<>`)](https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html), support for `.editorconfig` files, and nice additions to our GraphQL and Markdown support. - - - -## Highlights - -### JavaScript - -#### Option to add parens in arrow function arguments ([#3324](https://github.com/prettier/prettier/pull/3324)) by [@rattrayalex](https://github.com/rattrayalex) and [@suchipi](https://github.com/suchipi) - -When printing arrow functions, Prettier omitted parens around the arguments if they weren’t strictly necessary, like so: - - -```js -// no parens -foo => {}; - -// parens -(foo: Number) => {}; - -// parens -({ foo }) => {} - -// parens -(foo = 5) => {} -``` - -This lead to the [most commented thread](https://github.com/prettier/prettier/issues/812) in our issue tracker. Prettier now has the `--arrow-parens` option (`arrowParens` in the config) that can assume two values today: - -- `"avoid"` - (default) preserve the behavior that omits parens when possible -- `"always"` - always includes parens - -#### JSX fragment syntax ([#3237](https://github.com/prettier/prettier/pull/3237)) by [@duailibe](https://github.com/duailibe) - -Prettier will now recognize and format JSX with the [new fragment syntax](https://github.com/facebook/jsx/issues/84), like the code below: - - -```jsx -function MyComponent() { - return ( - <> - - - - - ); -} -``` - -#### Fix slow formatting long texts in JSX ([#3268](https://github.com/prettier/prettier/pull/3268), [#3273](https://github.com/prettier/prettier/pull/3273)) by [@duailibe](https://github.com/duailibe) - -We received feedback that formatting a JSX file with a really long text (~1000 lines) was really slow and noticed there was two performance bottlenecks in our `fill` primitive, which prints text until it reaches the print width and then insert a line break. - -### Markdown - -#### Add an option to preserve text line breaks ([#3340](https://github.com/prettier/prettier/pull/3340)) by [@ikatyang](https://github.com/ikatyang) - -After the release of our Markdown support, we received feedback that breaking text to respect the print width could affect some renderers that could be sensitive to line breaks. In _1.8.2_ we released a new option `proseWrap: false` that would print a paragraph in a single line, and users would rely on the "soft wrapping" feature of editors. - -In _1.9_ we are releasing a new option `proseWrap: "preserve"` which will respect the original line breaks of text, and lets the users decide where the text should break. - -[WARNING] `proseWrap` with boolean value is deprecated, use `"always"`, `"never"` or `"preserve"` instead. - -**[BREAKING CHANGE]** `proseWrap` option now defaults to `"preserve"` as some renderers are linebreak-sensitive. - -### GraphQL - -#### Support top-level interpolations ([#3370](https://github.com/prettier/prettier/pull/3370)) by [@lydell](https://github.com/lydell) - -When GraphQL support was released, Prettier did not support interpolation so it would skip formatting if any interpolations were present, because interpolations make formatting very difficult. While that works well for the most part, users of the [Apollo Client](https://www.apollographql.com/) were missing out on Prettier’s GraphQL support sometimes, because Apollo Client uses interpolation to share fragments between queries. The good news is that only _top-level_ interpolations are allowed, and that was way easier to add support for in Prettier. - -In _1.9_ we format GraphQL queries with top-level interpolation: - - -```js -gql` - query User { - user(id: "Bob") { - ...UserDetails - } - } - - ${UserDetailsFragment} -` -``` - -(Prettier will continue to skip formatting if the interpolation is inside a query or mutation or so.) - -#### Preserve intentional new lines in GraphQL ([#3252](https://github.com/prettier/prettier/pull/3252)) by [@duailibe](https://github.com/duailibe) - -Prettier will now respect intentional line breaks inside GraphQL queries (but limit to 1), where before it would remove them. - - -```graphql -query User { - name - - age -} -``` - -### CSS - -#### Don't lowercase element names and attribute names in selectors ([#3317](https://github.com/prettier/prettier/pull/3317)) by [@lydell](https://github.com/lydell) - -CSS is mostly case insensitive, so Prettier has been lowercasing stuff for a while to keep things consistent. Turns out we overlooked a detail in the CSS spec. Element and attribute names in selectors depend on the markup language: In HTML they are case insensitive, but in SVG (XML) they are not. Previously Prettier would incorrectly lowercase element and attribute names, but now we don’t anymore. - -### Configuration - -#### Add EditorConfig support ([#3255](https://github.com/prettier/prettier/pull/3255)) by [@josephfrazier](https://github.com/josephfrazier) - -It's taken a while, but Prettier will finally respect your `.editorconfig` file. This includes: - -- `indent_style` -- `indent_size`/`tab_width` -- `max_line_length` - -The `prettier` CLI respects `.editorconfig` by default, but you can opt out with `--no-editorconfig`. -However, the API _doesn't_ respect `.editorconfig` by default, in order to avoid potential editor integration issues (see [here](https://github.com/prettier/prettier/pull/3255#discussion_r152259674) for details). To opt in, add `editorconfig: true` to the `prettier.resolveConfig` options. - -## Other changes - -### JavaScript - -#### Don't break simple elements in JSX ([#3250](https://github.com/prettier/prettier/pull/3250)) by [@duailibe](https://github.com/duailibe) - -Prettier won't break an element with no attributes anymore, keeping elements like `
` as an unit. - -#### Don't break identifiers inside template literals expressions ([#3299](https://github.com/prettier/prettier/pull/3299)) by [@duailibe](https://github.com/duailibe) - -In the previous release we tried a new strategy of breaking template literals with expressions inside to respect the print width. We've received feedback that for some cases it was actually preferred that it would exceed print width than breaking in multiple lines. - -From now on, template literals expressions that contain a single identifier won't break anymore: - - -```js -const foo = `Hello ${username}. Today is ${month} ${day}. You have ${newMessages} new messages`. -``` - -#### Fix formatting of comment inside arrow function ([#3334](https://github.com/prettier/prettier/pull/3334)) by [@jackyho112](https://github.com/jackyho112) - -Fixes an edge case where Prettier was moving comments around breaking tools like Webpack: - - -```js -const API = { - loader: () => import('./test' /* webpackChunkName: "test" */), -}; - -// would get formatted to - -const API = { - loader: (/* webpackChunkName: "test" */) => import("./test") -}; -``` - -#### Fix printing of comments around decorators and class properties ([#3382](https://github.com/prettier/prettier/pull/3382)) by [@azz](https://github.com/azz) - -There was a case where comments between a decorator and a class property were moved to an invalid position. - - -```js -// Before -class Something { - @decorator - static // comment - property = 1; -} - -// After -class Something { - @decorator - // comment - static property = 1; -} -``` - -### Flow - -#### Do not break on empty type parameters ([#3281](https://github.com/prettier/prettier/pull/3281)) by [@Vjeux](https://github.com/Vjeux) - -It won't break empty type parameters (`foo: Type<>`) anymore. - -#### Add support for flow mixins when using babylon ([#3391](https://github.com/prettier/prettier/pull/3391)) by [@bakkot](https://github.com/bakkot) - -We were accidentally dropping flow mixins, this has been fixed, but only for the `babylon` parser. - - -```js -// Before -class Foo extends Bar {} - -// After -class Foo extends Bar mixins Baz {} -``` - -### TypeScript - -#### Don't print a trailing comma after object rest spread ([#3313](https://github.com/prettier/prettier/pull/3313)) by [@duailibe](https://github.com/duailibe) - -This was inconsistent with JavaScript and Flow, Prettier won't print a trailing comma in the following cases, when using the TypeScript parser: - - -```js -const { - bar, - baz, - ...rest -} = foo; -``` - -#### Print parens around type assertions for decorators ([#3329](https://github.com/prettier/prettier/pull/3329)) by [@azz](https://github.com/azz) - -We were omitting parens around type assertions inside decorators: - - -```typescript -@(bind as ClassDecorator) -class Decorated {} -``` - -### Markdown - -#### Don't break `inlineCode` ([#3230](https://github.com/prettier/prettier/pull/3230)) by [@ikatyang](https://github.com/ikatyang) - -Prettier won't break text inside `inlineCode` meaning it will only break of after it. - -#### No extra whitespace between non-CJK and CJK-punctuation and vice-versa ([#3244](https://github.com/prettier/prettier/pull/3244), [#3249](https://github.com/prettier/prettier/pull/3249)) by [@ikatyang](https://github.com/ikatyang) - -Fixes cases where Prettier would insert extra whitespace like in the following examples: - - -```markdown -扩展运算符(spread )是三个点(`...`)。 - -This is an english paragraph with a CJK quote " 中文 ". -``` - -#### Escape all emphasis-like text ([#3246](https://github.com/prettier/prettier/pull/3246)) by [@ikatyang](https://github.com/ikatyang) - -Fixes the case where `\_\_text\_\_` would be formatted as `__text__`. - -#### Handle punctuation variants ([#3254](https://github.com/prettier/prettier/pull/3254)) by [@ikatyang](https://github.com/ikatyang) - -Prettier now considers not only ASCII punctuation characters but Unicode as well. - -#### Support TOML front matter ([#3290](https://github.com/prettier/prettier/pull/3290)) by [@ikatyang](https://github.com/ikatyang) - -We already supported YAML in the front matter of Markdown files and we added the TOML format as well, since some static site generators support it. - - -```markdown -+++ -date: '2017-10-10T22:49:47.369Z' -title: 'My Post Title' -categories: ['foo', 'bar'] -+++ - -This is the markdown body of my post. -``` - -#### Only indent the first non-list node in checkbox list item ([#3297](https://github.com/prettier/prettier/pull/3297)) by [@ikatyang](https://github.com/ikatyang) - -Fixes a bug where it would indent lines after a list when it shouldn't: - - -```markdown -* parent list item - - * child list item - -* [x] parent task list item - - * [x] child task list item -``` - -would become: - - -```markdown -* parent list item - - * child list item - -* [x] parent task list item - - * [x] child task list item -``` - -#### Preserve non-breaking whitespaces ([#3327](https://github.com/prettier/prettier/pull/3327)) by [@ikatyang](https://github.com/ikatyang) - -Non-breaking whitespaces are useful to keep words separated by spaces together in the same line (i.e. number and units or multi-word product names). Prettier was wrongfully converting them to regular whitespaces. - -#### Do not break before special prefix ([#3347](https://github.com/prettier/prettier/pull/3347)) by [@ikatyang](https://github.com/ikatyang) - -Fixes a bug where Prettier could break text if it went over the print width right before a number followed by `.` which would be parsed as a numbered list: - - -```markdown -She grew up in an isolated village in the 19th century and met her father aged -29. Oh no, why are we in a numbered list now? -``` - -#### Omit semicolon in simple JSX expressions ([#3330](https://github.com/prettier/prettier/pull/3330)) by [@sapegin](https://github.com/sapegin) - -Prettier will omit the semicolon (before and after) inside code samples if it's a simple JSX expression: - -````markdown -No semi: - - -```jsx -
Example
-``` -```` diff --git a/website/blog/2018-01-10-1.10.0.md b/website/blog/2018-01-10-1.10.0.md deleted file mode 100644 index 9976a04d1e..0000000000 --- a/website/blog/2018-01-10-1.10.0.md +++ /dev/null @@ -1,460 +0,0 @@ ---- -author: Christopher Chedeau (@vjeux) -authorURL: https://twitter.com/vjeux -title: "Prettier 1.10: One Year of Prettier 🎂" ---- - -Happy Prettier-versary! It's pretty incredible that Prettier was only released a year ago and has already seen such a massive adoption and great number of contributors. For this special release, we're going to do a small retrospective around the project. - -It's also an exciting release in itself because Prettier now has partial support for `.vue` files and the internals have been refactored such that there's a proper plugin API in order to support different languages! - - - -## Retrospective - -Ever since gofmt came out in 2013, I ([@vjeux]) became obsessed with the idea of automatic formatting. I started seeing problems that would be solved by an automatic formatter all the time: arguing about coding style, having to format the code manually, difficulty to write codemod tools… - -When last December there were not one but two people independently working on a JavaScript pretty printer, it was a sign! Pieter Vanderwerff built one in Reason based on Flow infrastructure and James Long in JavaScript. I played the role of a cheerleader by setting up the same test suite for the two projects as well as running their pretty printer on existing codebases and extracting lists of [things that](https://github.com/prettier/prettier/issues/2) were [not printed well](https://github.com/prettier/prettier/issues/6). - -Sadly, after the holidays were over, both of them had to go back to work on their real job :( I decided to step in and convince my manager to work on it full time. James had open sourced his project (Prettier) and I was more familiar with JavaScript so I decided that this was the one I would work on! - -Here's a list of some of the things that worked well during this project. - -### Spend time on release notes - -Release notes have an interesting property that they are very often shared, even if the content is terrible. Everyone seems to want to know that version 1.5.8 of some software has been released. This is a very good opportunity to also sell your project. - -For Prettier releases, I spent a lot of time explaining the rationale behind all the changes and talked about some things that would likely have been written as a separate blog post (like this!). Plus, you're likely going to be lazy and find all the excuses in the world not to write that blog post, but you really want to publish that new version, so it's a good forcing function. - -### Clear decision-making process - -Style rules are one of the most controversial subjects and at the same time a lot of decisions needed to be made. I tried to design a decision-making process that would let us make progress. - -People find all sort of emotional arguments in order to convince you that their opinion on style is the best. We needed to have something purely rational so that even though it's not what people would prefer, they couldn’t argue against the methodology. - -The best I could find was to count how many times each variant was used in the Facebook codebase. It’s easy for me to run and provide relative numbers (style A is used 5x more than style B) to convince people. If such a big codebase that has been written by thousands of people over the years has a winner, it may not be the best but is likely not going to be hugely controversial. - -Not everything could be solved this way, some things didn't have a clear winner or it was not obvious how to come up with an algorithm to print it well. In those cases, it was important to have an escalation process with a single person making the decision at the end (me). This way we could make progress without needing to find a consensus which would have likely been very hard. - -### Open source as guinea pigs - -A total pretty printer is one of those projects where you need it to be close to perfect to bring it to a big codebase like Facebook. The first impression is extremely important and it's very hard to get something that will be correct (it won't introduce invalid JavaScript or code that would behave differently) for all the edge cases. - -My initial plan was to work on it alone in a cave hidden from the outside world for 6 months until I got everything just right and then get people to adopt it. What I didn't expect is that people in open source didn't have that same quality bar and started using it way earlier than that. The risks of using it on a side project are vastly different than on millions of lines of code at Facebook. - -It ended up being very beneficial for the project to get feedback along the way until it was finally ready to be used at Facebook. - -### Open source as contributors - -For the first 6 months of the project, I was working full time on it and ended up writing only half of the commits. This is pretty mind-blowing in itself! Not only was the throughput two times better on the project itself, but people ended up working on things that I wouldn't have spent time on like integrations with all the editors on earth, a fuzzer to find bugs, TypeScript support, infrastructure to support parsing multiple languages in the same file, and more. - -Even though we don't use all those things at Facebook, many of them ended up being useful. CSS-in-JS support made it easy to get GraphQL fragments in template literals formatted. The large number of users was also a great way to surface obscure bugs that we would eventually hit and many different people chimed in to fix them. - -The best thing is that I stopped working on the project full time 6 months ago and the project kept going under the leadership of [@azz]. I'd like to thank all the people that helped in various ways, this is so exciting to make history together! - -Open source has been doing wonders for the project, delivering a ton of value for Facebook (almost all our JavaScript files are now pretty printed) and for the industry at large as seen by the huge adoption. - -### Tooling: Jest Snapshot Tests & Playground - -All those contributions were possible because it was easy to report errors, contribute and review code. The two tools that were most impactful in this project were jest snapshot tests and the playground. - -Snapshot tests are a wonder for a pretty printer. Adding new tests is dead easy, just create a file in the test folder with the code you want to format and run jest, voila! Anytime you change something, you can see how a bunch of examples would be printed differently, then it's up to you to decide if it's better or not. For a reviewer, it's also really nice, you can look at the before/after of all the things it changed. I've come to pay more attention to the snapshots than the actual implementation. - -[The playground](https://prettier.io/playground) is a really nice way to get to a repro or play with Prettier without having to install the development environment, being on the right branch... This has proven to be extremely valuable to get people to provide really good bug reports that are actionable. - -## Highlights - -### Support for Vue Single File Components ([#3563]) by [@vjeux] - -There's a lot of demand for Vue SFC ([#2097]). We've introduced partial support for them: All the HTML is printed as is, but now the ` - - - -``` - -Read more about it in the [docs](https://prettier.io/docs/en/browser.html) or try it on this [JS Bin](https://jsbin.com/vabiyomoso/edit?html,output). - -#### Don't default to the JavaScript parser ([#4528] by [@duailibe]) - -In Prettier 1.12 and earlier, when running Prettier on a file without a file extension, Prettier would assume the file contained JavaScript. This lead to a couple of confusing bugs, namely: - -- If you ran prettier on your `.git` directory, it would reformat files and break your git repo. -- If you tried to run prettier on html files, it would sometimes throw an error, but other times parse the HTML as JSX, and format it as if it was JSX (which was often unsafe). - -In Prettier 1.13, we are changing this behavior. If Prettier cannot determine what language a file is from its extension, and the user has not manually specified a parser to use, Prettier will skip the file. - -If you need to format files with unsupported or nonstandard extensions, you can use the `--parser` option to specify which parser to use. If you are piping file contents into `stdin`, make sure to include `--stdin-filepath` so that prettier can use the file extension to detect what language to parse the input as. - -When using the JavaScript API, `prettier.format` and `prettier.formatWithCursor` will now throw an error if you do not include either `parser` or `filepath` in the options you pass in. It will also throw an error if you include `filepath` but not `parser` and the correct parser cannot be inferred from the file path. - -#### `prettier.getFileInfo()` method and `--file-info` CLI option ([#4341] by [@kachkaev]) - -When invoking Prettier from the API, there was no way to find out if a file should be ignored or not (for `.prettierignore`) so editor integration plugins would have to implement this logic. Also, there was no way to find out if a file was supported by Prettier, so users would need to call Prettier anyway. In 1.13 there's a way to check if a parser will be inferred (and which one) and if the file is ignored or not before actually calling `format`. - -You can read more about this in the [docs](https://prettier.io/docs/en/api.html#prettiergetfileinfofilepath-options). - -#### Support for global Prettier and plugins ([#4192] by [@kachkaev]) - -When installing Prettier and plugins globally, Prettier was not able to automatically load plugins because it searched for them in the nearest `package.json`. Now Prettier will look for plugins in the `node_modules` directory it's installed in. Additionally, for cases where Prettier can't find the plugins automatically (because of other setups we haven't added support for), a new `--plugin-search-dir` option was added so you can specify where Prettier should search for plugins. - -You can read more about this in the [Plugin docs](https://prettier.io/docs/en/plugins.html#using-plugins). - -#### Improve cursor offset tracking ([#4397] by [@ds300]) - -Prettier 1.13 vastly improves the cursor offset tracking for several cases where Prettier was outputting the wrong location, making editor integrations move the cursor to an incorrect location. - -### JavaScript - -#### Insert more parentheses in math expressions ([#4413] and [#4407] by [@duailibe]) - -Prettier will now add parens around module operations when they're inside an additive operation or when mixing two different multiplicative operations, even though they're not necessary. This is to help more quickly understand a code snippet. - - -```js -// Input -a % 10 - 5; -2 / 3 * 10 / 2 + 2; - -// Output with Prettier 1.13 -(a % 10) - 5; -((2 / 3) * 10) / 2 + 2; -``` - -#### Inline AngularJS tests that use `inject` ([#4495] by [@thorn0]) - -Prettier will now keep AngularJS tests with dependency injection in a single line, like it does for our other tests. - - -```js -// Input: -it("has calculated the answer correctly", inject(function(DeepThought) { - expect(DeepThought.answer).toBe(42); -})); - -// Output with Prettier 1.12.1: -it( - "has calculated the answer correctly", - inject(function(DeepThought) { - expect(DeepThought.answer).toBe(42); - }) -); - -// Output with Prettier 1.13: -it("has calculated the answer correctly", inject(function(DeepThought) { - expect(DeepThought.answer).toBe(42); -})); -``` - -#### Nicer line wrapping for D3 ([#4285] by [@1wheel], [#4505] by [@duailibe]) - -In Prettier 1.12 and earlier, chains that started with `d3` and other short names were broken before the first `.`. In Prettier 1.13, we will not add a newline after the name if it is shorter than the indentation width. - - -```js -// Input -d3.select('body') - .append('circle') - .at({ width: 30, fill: '#f0f' }) - .st({ fontWeight: 600 }) - -// Output with Prettier 1.12.1: -d3 - .select("body") - .append("circle") - .at({ width: 30, fill: "#f0f" }) - .st({ fontWeight: 600 }); - -// Output with Prettier 1.13: -d3.select("body") - .append("circle") - .at({ width: 30, fill: "#f0f" }) - .st({ fontWeight: 600 }); -``` - -#### Format new `describe.each` table in Jest 23 ([#4423] by [@ikatyang]) - -Jest 23 introduced a new feature called [data driven tests](https://facebook.github.io/jest/docs/en/api.html#describeeachtable-name-fn) where you can describe examples to test in a table. Prettier 1.13 includes support for this feature, and will automatically indent the table when using data driven tests. - - -```js -// Input -describe.each` -a|b|expected -${11 } | ${ 1 }|${222} -${1-1}|${2+2}|${ 3333} -${2+1+2}|${1111}|${3} -`('$a + $b', ({a, b, expected}) => { - test(`returns ${expected}`, () => { - expect(a + b).toBe(expected); - }); - - test(`returned value not be greater than ${expected}`, () => { - expect(a + b).not.toBeGreaterThan(expected); - }); - - test(`returned value not be less than ${expected}`, () => { - expect(a + b).not.toBeLessThan(expected); - }); -}); - -// Output with Prettier 1.13 -describe.each` - a | b | expected - ${11} | ${1} | ${222} - ${1 - 1} | ${2 + 2} | ${3333} - ${2 + 1 + 2} | ${1111} | ${3} -`("$a + $b", ({ a, b, expected }) => { - test(`returns ${expected}`, () => { - expect(a + b).toBe(expected); - }); - - test(`returned value not be greater than ${expected}`, () => { - expect(a + b).not.toBeGreaterThan(expected); - }); - - test(`returned value not be less than ${expected}`, () => { - expect(a + b).not.toBeLessThan(expected); - }); -}); -``` - -#### Format functional composition more nicely ([#4431] by[@suchipi]) - -One of the most requested changes in Prettier was to format function composition better. This pattern is pretty common in functional programming libraries like RxJS, Redux, Lodash, and Ramda. In 1.13, Prettier now has an heuristic to detect this type of function composition and format it such that the composed functions are each on their own line. This improves readability when using functions like `pipe`, `compose`, `flowRight`, etc. - - -```js -// Input -compose( - sortBy(x => x), - flatten, - map(x => [x, x * 2]) -); - -pipe( - filter(x => x % 2 === 0), - map(x => x + x), - scan((acc, x) => acc + x, 0) -); - -// Output with Prettier 1.12.1 -compose(sortBy(x => x), flatten, map(x => [x, x * 2])); - -pipe(filter(x => x % 2 === 0), map(x => x + x), scan((acc, x) => acc + x, 0)); - -// Output with Prettier 1.13 -compose( - sortBy(x => x), - flatten, - map(x => [x, x * 2]) -); - -pipe( - filter(x => x % 2 === 0), - map(x => x + x), - scan((acc, x) => acc + x, 0) -); -``` - -#### Keep parens around `do` expressions when needed and improve their formatting ([#4479] by [@existentialism]) - -In Prettier 1.12 and earlier, there were some cases where Prettier would remove parens around `do` expressions where it was not safe to do so, which would cause the code to become invalid. Those cases are now fixed in 1.13. Also, formatting of `do` expressions has been improved in general with this release. - - -```js -// Input -(do {}); -(do {} + 1); -(1 + do {}); - -() => do { - var obj = { foo: "bar", bar: "foo" }; - for (var key in obj) { - obj[key]; - } -}; - -// Output with Prettier 1.12 -do { -}; -do { -} + 1; -1 + - do { - }; - -() => - do { - var obj = { foo: "bar", bar: "foo" }; - for (var key in obj) { - obj[key]; - } - }; - -// Output with Prettier 1.13 -(do {}); -(do {} + 1); -1 + do {}; - -() => do { - var obj = { foo: "bar", bar: "foo" }; - for (var key in obj) { - obj[key]; - } -}; -``` - -### Flow - -#### Print classes mixins and implements correctly ([#4326] by [@existentialism]) - -In versions 1.12 and earlier, Prettier would incorrectly remove `mixins` and `implements` from flow libdef classes, which would change the meaning of the code. This has been fixed in 1.13. - - -```js -// Input -declare class A implements B {} -declare class C mixins D {} - -// Output with Prettier 1.12 -declare class A {} -declare class C {} - -// Output with Prettier 1.13 -declare class A implements B {} -declare class C mixins D {} -``` - -#### Added support for the nullish coalescing operator and literal numeric separators ([#4536] by [@vjeux]) - -These JS features were already supported when using the default Babylon parser, but Prettier 1.13 adds support for them when using the Flow parser. - -#### Added support for Flow new syntax features ([#4543], [#4540] and [#4551] by [@existentialism]) - -New features added to Flow are now supported by Prettier: - -- inline interfaces - - - ```ts - type A = interface { p: string}; - ``` - -- explicit type arguments - - - ```ts - fnCall("name"); - ``` - -- proto modifier syntax - - - ```ts - declare class A { proto: T } - ``` - -### TypeScript - -#### Added support for TypeScript import types ([#4429] and [#4438] by [@ikatyang]) - -A new feature added in TypeScript 2.9 for describing the shapes of a module imported dynamically. - -```ts -// Input -export const x: import("./foo") = { x: 0, y: 0 }; - -export let y: import("./foo2").Bar.I = { a: "", b: 0 }; - -export let shim: typeof import("./foo2") = { Bar: Bar2 }; - -// Output with Prettier 1.13 -export const x: import("./foo") = { x: 0, y: 0 }; - -export let y: import("./foo2").Bar.I = { a: "", b: 0 }; - -export let shim: import("./foo2") = { Bar: Bar2 }; -``` - -#### Added support for generic JSX elements in TypeScripts ([#4268] by [@ikatyang]) - -Another feature added in TypeScript 2.9 is the support for generics in JSX elements and Prettier 1.13 can now format them. - - -```ts -// Example: - data={12} /> -``` - -#### Added support for TaggedTemplateExpression typeParameters ([#4353] by [@ikatyang]) - -Also added in TypeScript 2.9, it's now possible to pass type parameters to template expression tags. - - -```ts -// Example: -export const RedBox = styled.div<{ foo: string }>` - background: red; - ${props => props.foo}; -`; -``` - -#### Improve format of type casts with generics and unions ([#4219] by [@kpdonn]) - - -```ts -// Input -const finalConfiguration = - >someExistingConfigMap.mergeDeep(fallbackOpts); - -// Output with Prettier 1.12 -const finalConfiguration = >someExistingConfigMap.mergeDeep(fallbackOpts); - -// Output with Prettier 1.13 -const finalConfiguration = >( - someExistingConfigMap.mergeDeep(fallbackOpts) -); -``` - -### JSON - -#### Split JSON and JSON5 parsers ([#4367] and [#4371] by [@ikatyang], [#4333] by [@duailibe]) - -JSON5 is a superset of JSON that supports comments, trailing commas and unquoted property keys. Some files (like `.babelrc`) use JSON5, so comments, trailing commas, and unquoted property keys are allowed in those files. Other files (like `package.json`) do not use JSON5, so comments, trailing commas, and unquoted property keys are not allowed. Prettier previously had one parser and printer called `JSON` which was used for both, but maintaining both together led to some subtle bugs being introduced, notably around the `/* @prettier */` pragma comment detection and insertion. With the two split apart, these bugs are fixed and Prettier is more robust. - -#### Added `json-stringify` parser for `JSON.stringify`-style formatting ([#4450] by [@ikatyang]) - -One common complain with prettier was that it would format `package.json` and `package-lock.json` differently from how `npm` and `yarn` would, so if you ran an `npm` or `yarn` command, it could introduce prettier violations, and editing `package.json` could add line breaks that would later be removed when you next ran an `npm` or `yarn` command. This led to a lot of unnecessary diff noise and a bad user experience. In Prettier 1.13, a new parser/printer called `json-stringify` has been added that behaves the same as `JSON.stringify`, so that changes will not flip-flop back and forth when using prettier and npm/yarn. Also, this is now the default parser/printer for `package.json` and `package-lock.json`, so if you upgrade to the latest version of prettier, these noisy diffs will stop appearing without any configuration change on your part. - -### CSS/Less/SCSS - -#### Improve format for SCSS maps ([#4487] by [@evilebottnawi]) - - -```less -/* Output with Prettier 1.12 */ -a { - @include section-type-1( - $header: (margin: 0 0 $margin-base, text-align: left), - $decoration: - ( - type: base, - margin: 0 auto -1px 0, - primary-color: $brand-primary, - secondary-color: $gray-light - ), - $title: - ( - margin: 0 0 $margin-small, - color: false, - font-size: $font-size-h3, - font-weight: false, - line-height: $line-height-h3 - ) - ); -} - -/* Output with Prettier 1.13 */ -a { - @include section-type-1( - $header: ( - margin: 0 0 $margin-base, - text-align: left - ), - $decoration: ( - type: base, - margin: 0 auto -1px 0, - primary-color: $brand-primary, - secondary-color: $gray-light - ), - $title: ( - margin: 0 0 $margin-small, - color: false, - font-size: $font-size-h3, - font-weight: false, - line-height: $line-height-h3 - ) - ); -} -``` - -#### Improve format for `@support` at-rule ([#4372] by [@evilebottnawi]) - - -```css -/* Input */ -@supports (transform-style: preserve) or (-moz-transform-style: preserve) or (-o-transform-style: preserve) or (-webkit-transform-style: preserve) {} - -/* Output with Prettier 1.12 */ -@supports (transform-style: preserve) or (-moz-transform-style: preserve) or (-o-transform-style: preserve) or (-webkit-transform-style: preserve) { -} - -/* Output with Prettier 1.13 */ -@supports (transform-style: preserve) or (-moz-transform-style: preserve) or - (-o-transform-style: preserve) or (-webkit-transform-style: preserve) { -} -``` - -### Markdown - -#### Change unordered list symbol to a hyphen ([#4440] by [@ikatyang]) - -With the release of Markdown support in Prettier, we used [GitHub BigQuery data](https://cloud.google.com/bigquery/public-data/github) and discovered that the `*` symbol was marginally more used than `-` for unordered lists. Since then, we have received massive feedback from the community that the `-` is actually preferred. Prettier 1.13 will now format unordered lists using the `-` symbol. - - -```markdown - -* Top level list item 1 -* Top level list item 2 - * Nested List item 1 - * Nested List item 2 - * Sub-Nested List item 1 - * Sub-Nested List item 2 - - -* Top level list item 1 -* Top level list item 2 - * Nested List item 1 - * Nested List item 2 - * Sub-Nested List item 1 - * Sub-Nested List item 2 - - -- Top level list item 1 -- Top level list item 2 - - Nested List item 1 - - Nested List item 2 - - Sub-Nested List item 1 - - Sub-Nested List item 2 -``` - -#### Preserve Liquid tag contents ([#4484] by [@duailibe]) - -Liquid is a templating language popular among static site generators such as Jekyll. In Prettier 1.12 and earlier, Liquid tags in markdown files were not properly handled, because Prettier thought they were just text. This would sometimes alter the contents of the tags, changing their meaning. Now Prettier 1.13 understands Liquid tags and will not change their contents. - - -```markdown - -{% include_relative _installations/tarball.md %} - -{% cloudinary nice_prefix_-_for_the_filename.jpg %} - - -{% include_relative \_installations/tarball.md %} - -{% cloudinary nice*prefix*-\_for_the_filename.jpg %} - - -{% include_relative _installations/tarball.md %} - -{% cloudinary nice_prefix_-_for_the_filename.jpg %} -``` - -#### Break link definitions onto multiple lines when needed ([#3531] by [@j-f1]) - -Link definitions will be broken onto multiple lines when used with `--prose-wrap always` if they exceed the print width. - - -```markdown - -[just-url]: https://example.com -[url-with-short-title]: https://example.com "title" -[url-with-long-title]: https://example.com "a long, long title. It's really really long. Here have words." - -[long]: https://example.com/a-long-url/another-segment/yet-another-segment/a-really-long-file-name.php.aspx -[long-with-title]: https://example.com/a-long-url/another-segment/yet-another-segment/a-really-long-file-name.php.aspx "look a title!" - - -[just-url]: https://example.com -[url-with-short-title]: https://example.com "title" -[url-with-long-title]: https://example.com "a long, long title. It's really really long. Here have words." -[long]: https://example.com/a-long-url/another-segment/yet-another-segment/a-really-long-file-name.php.aspx -[long-with-title]: https://example.com/a-long-url/another-segment/yet-another-segment/a-really-long-file-name.php.aspx "look a title!" - - -[just-url]: https://example.com -[url-with-short-title]: https://example.com "title" -[url-with-long-title]: - https://example.com - "a long, long title. It's really really long. Here have words." -[long]: - https://example.com/a-long-url/another-segment/yet-another-segment/a-really-long-file-name.php.aspx -[long-with-title]: - https://example.com/a-long-url/another-segment/yet-another-segment/a-really-long-file-name.php.aspx - "look a title!" -``` - -### GraphQL - -#### Only add blank lines after top-level definitions if present in the original source ([#4512] by [@ad1992]) - -In Prettier 1.12 and earlier, we would always print a blank line between top level definitions. In 1.13, we would only output a blank line if it was there originally. This behavior is similar to how Prettier formats JavaScript. - - -```graphql -# Input -type TypeA { - fieldA: string -} -type TypeB { - fieldB: string -} - -type TypeC { - fieldC: string -} - -# Output with Prettier 1.12.1 -type TypeA { - fieldA: string -} - -type TypeB { - fieldB: string -} - -type TypeC { - fieldC: string -} - -# Output with Prettier 1.13 -type TypeA { - fieldA: string -} -type TypeB { - fieldB: string -} - -type TypeC { - fieldC: string -} -``` - -## Other changes - -### API/CLI - -#### Don't format range if required pragma is missing in the file ([#3996] by [@josephfrazier]) - -In Prettier 1.12 and earlier, if a file didn't have a `/** @prettier */` pragma and Prettier was called only for a range with `--require-pragma`, it would format it anyway. Now Prettier will check if the file has the pragma even when only formatting a range. - -#### Improve plugin resolution when path does not start with `./` ([#4451] by [@kachkaev]) - -When passing `--plugin=path/to/plugin` Prettier 1.12 and earlier would crash because it looked for a `path/to/plugin` in `node_modules` folder. Prettier 1.13 will look in the current directory first and failing that will look in `node_modules`. - -#### Adding plugin interface for isBlockComment ([#4347] by [@mgrip]) - -A block comment is a comment that can be printed inline (for JS, it's `/* comment */`) with code. Since Prettier is responsible for printing comments we needed to let plugins determine if a comment is a block comment. Read more in our [docs](plugins.md). - -### JavaScript - -#### Apply destructuring rules in functions to catch param ([#4385] by [@duailibe]) - -In 1.12 we formatted destructuring in `catch` arguments like destructuring in assignments, but the code looks better if we treat it like destructuring in function parameters instead, so we made that change: - - -```js -// Input -try { - doSomething(); -} catch ({data: {message}}) { - handleError(message.errors); -} - -try { - doSomething(); -} catch ({data: {message: {errors}}}) { - handleError(errors); -} - -// Output with Prettier 1.12.1 -try { - doSomething(); -} catch ({ - data: { message } -}) { - handleError(message.errors); -} - -try { - doSomething(); -} catch ({ - data: { - message: { errors } - } -}) { - handleError(errors); -} - -// Output with Prettier 1.13 -try { - doSomething(); -} catch ({ data: { message } }) { - handleError(message.errors); -} - -try { - doSomething(); -} catch ({ - data: { - message: { errors } - } -}) { - handleError(errors); -} -``` - -#### Escape backslashes correctly for Markdown in JS ([#4381] by [@ikatyang]) - -Prettier 1.12 and earlier was incorrectly removing backslashes in Markdown template literals in some cases. Prettier 1.13 will print them correctly. - - -```js -// Input -markdown` - const cssString = css\` - background-color: \$\{color('base')\} - \`; -` -// Output with Prettier 1.12.1 -markdown` - const cssString = css\`background-color: ${color('base')}\`; -`; - -// Output with Prettier 1.13 -markdown` - const cssString = css\`background-color: \$\{color('base')\}\`; -`; -``` - -#### Support styled-components ` Foo.extend.attrs()`` ` ([#4434] by [@duailibe]) - -In Prettier 1.12.1, Prettier did not detect that the template literal passed to the `styled-components` function `Foo.extends.attrs()` was CSS. In 1.13, Prettier now supports this syntax and will format the contents of the template literal as CSS. - - -```js -// Input -Button.extend.attrs({})` -border-color : black; -`; - -// Output with Prettier 1.12 -Button.extend.attrs({})` -border-color : black; -`; - -// Output with Prettier 1.13 -Button.extend.attrs({})` - border-color: black; -`; -``` - -#### Added support for the GraphQL comment tag ([#4395] by [@tjallingt]) - -We format GraphQL in tagged template literals but there are GraphQL libraries that use untagged template literals. Many GraphQL editor plugins have settled on using the comment `/* GraphQL */` before an untagged template literal to detect GraphQL. In 1.13, Prettier now also detects that comment and formats the GraphQL code. - - -```js -// Input -const query = /* GraphQL */` - { - user( id : 5 ) { - firstName - lastName - } - } -`; - -// Output with Prettier 1.13 -const query = /* GraphQL */ ` - { - user(id: 5) { - firstName - lastName - } - } -`; -``` - -#### Format Angular Component styles ([#4361] by [@JamesHenry]) - -Prettier 1.13 formats the inline styles of Angular components. - - -```js -// Input -@Component({ - selector: 'app-test', - styles: [ ` - - :host { - color: red; - } - div { background: blue - } -` - -] -}) -class TestComponent {} - -// Output with Prettier 1.13 -@Component({ - selector: "app-test", - styles: [ - ` - :host { - color: red; - } - div { - background: blue; - } - `, - ], -}) -class TestComponent { -``` - -#### Correctly break class property initializers ([#4442] by [@nicolo-ribaudo]) - -Prettier 1.12 did not indent the following lines when breaking a class property initializer. This is now fixed in 1.13. - - -```js -// Input -class Something { - someInstanceProperty = this.props.foofoofoofoofoofoo && - this.props.barbarbarbar; -} - -// Output with Prettier 1.12 -class Something { - someInstanceProperty = this.props.foofoofoofoofoofoo && - this.props.barbarbarbar; -} - -// Output with Prettier 1.13 -class Something { - someInstanceProperty = this.props.foofoofoofoofoofoo && - this.props.barbarbarbar; -} -``` - -#### Fix long name method in bind expressions ([#4447] by [@misoguy]) - -Prettier 1.13 improves formatting of long member expression chains in a bind expression. - - -```js -// Input -function Foo() { - const longVariableName = ::veryLongObjectName.veryLongObjectChain.veryLongObjectProperty; -} - -// Output with Prettier 1.12 -function Foo() { - const longVariableName = ::veryLongObjectName.veryLongObjectChain - .veryLongObjectProperty; -} - -// Output with Prettier 1.13 -function Foo() { - const longVariableName = - ::veryLongObjectName.veryLongObjectChain.veryLongObjectProperty; -} -``` - -#### Stop removing parens for the `?.` operator ([#4542] by [@duailibe]) - -There's an [edge case](https://github.com/tc39/proposal-optional-chaining#edge-case-grouping) in the optional chaining proposal that wrapping in parens has a difference in the runtime behavior. Prettier 1.12 and earlier were removing the parens in that case, which is now fixed in 1.13. - - -```js -// Input -(a?.b).c - -// Output with Prettier 1.12 -a?.b.c - -// Output with Prettier 1.13 -(a?.b).c -``` - -### Flow - -#### Wrap `?() => T` in parens when needed. ([#4475] by [@nicolo-ribaudo]) - -Prettier 1.12 and earlier unintentionally changed the meaning of types when using nullable operator because of the precedence of operators. This is now fixed in Prettier 1.13. - - -```ts -// Input -type Foo = { arg: ?(() => void) | string }; - -// Output with Prettier 1.12 -type Foo = { arg: ?() => void | string }; -// which is equivalent to: -type Foo = { arg: ?() => (void | string) }; - -// Output with Prettier 1.13 -type Foo = { arg: ?(() => void) | string }; -``` - -### TypeScript - -#### Preserve quoted class properties ([#4517] by [@ikatyang]) - -Strict property initialization checks are not applied to quoted class properties in TypeScript. In Prettier 1.13 we'll preserve the quotes if they were originally in the code. - - -```ts -// Input -class Username { - age: number; - "username": string; -} - -// Output with Prettier 1.12 -class Username { - age: number; - username: string; -} - -// Output with Prettier 1.13 -class Username { - age: number; - "username": string; -} -``` - -### Markdown - -#### Remove newline in empty `.md` files ([#4388] by [@huyvohcmc]) - -In Prettier 1.12.1, a newline would be printed when formatting an empty markdown file. This is now fixed in 1.13. - -#### Prevent merge continuous CJK text with `--prose-wrap preserve` ([#4504] by [@ikatyang]) - -When using `--prose-wrap preserve`, Prettier will no longer merge continuous CJK text broken across multiple lines. - - -```markdown - -::: warning 注意 -该网站在国外无法访问,故以下演示无效 -::: - - -::: warning 注意该网站在国外无法访问,故以下演示无效 -::: - - -::: warning 注意 -该网站在国外无法访问,故以下演示无效 -::: -``` - -### CSS/SCSS/Less - -#### Print trailing commas in SCSS list and maps ([#4317] by [@ad1992]) - -Prettier now prints trailing commas in lists and maps in SCSS if `trailingComma` is not `"none"` and the list or map is broken onto multiple lines. - - -```css -/* Input */ -$list: (a); -$colors: ( - "red", - "blue" -); -$map: ( - 'medium': (min-width: 800px), - 'large': (min-width: 1000px), - 'huge': (min-width: 1200px), -); - -/* Output with Prettier 1.13 */ -$list: (a); -$colors: ( - "red", - "blue", -); -$map: ( - "medium": (min-width: 800px), - "large": (min-width: 1000px), - "huge": (min-width: 1200px), -); -``` - -#### Fix empty front-matter ([#4392] and [#4457] by [@eliasmeire]) - -Prettier 1.12 was released with support for front-matter blocks in CSS/SCSS/Less files, but it was removing empty blocks (or blocks with only comments). This is now fixed in 1.13. - -#### Don't format SCSS string interpolation ([#4490] by [@evilebottnawi]) - -Prettier would break SCSS code when formatting a string with interpolation for some cases. Prettier 1.13 will print the original code. - - -```less -/* Input -a { - content: "#{my-fn("_")}"; -} - -/* Output with Prettier 1.12 */ -a { - content: "#{my-fn(" _ ")}"; -} - -/* Output with Prettier 1.13 */ -a { - content: "#{my-fn("_")}"; -} -``` - -#### Escape characters correctly ([#4472] by [@evilebottnawi]) - -Prettier 1.12 would not escape characters correctly in some cases. - - -```less -/* Input */ -@media only screen and (max-width: 767px) { - @include widths(2 3 4, \@small); -} - -$widths-breakpoint-separator: \@small; - -/* Output with Prettier 1.12 */ -@media only screen and (max-width: 767px) { - @include widths(2 3 4, \ @small); -} - -$widths-breakpoint-separator: \ @small; - -/* Output with Prettier 1.13 */ -@media only screen and (max-width: 767px) { - @include widths(2 3 4, \@small); -} - -$widths-breakpoint-separator: \@small; -``` - -#### Fix SCSS interpolation in CSS variables ([#4471] by [@evilebottnawi]) - - -```less -/* Input */ -a { - --bg: var(--#{$type}); -} - -/* Output with Prettier 1.12 */ -a { - --bg: var(-- #{$type}); -} - -/* Output with Prettier 1.13 */ -a { - --bg: var(--#{$type}); -} -``` - -#### Fix spacing issue in PostCSS computed variables ([#4408] by [@ad1992]) - - -```less -/* Input */ -background-color: $$(style)Color; - -/* Output with Prettier 1.12 */ -background-color: $$(style) Color; - -/* Output with Prettier 1.13 */ -background-color: $$(style)Color; -``` - -[@1wheel]: https://github.com/1wheel -[@ad1992]: https://github.com/ad1992 -[@ds300]: https://github.com/ds300 -[@duailibe]: https://github.com/duailibe -[@eliasmeire]: https://github.com/eliasmeire -[@evilebottnawi]: https://github.com/evilebottnawi -[@existentialism]: https://github.com/existentialism -[@huyvohcmc]: https://github.com/huyvohcmc -[@ikatyang]: https://github.com/ikatyang -[@j-f1]: https://github.com/j-f1 -[@josephfrazier]: https://github.com/josephfrazier -[@kachkaev]: https://github.com/kachkaev -[@kpdonn]: https://github.com/kpdonn -[@mgrip]: https://github.com/mgrip -[@misoguy]: https://github.com/misoguy -[@n8n8baby]: https://github.com/n8n8baby -[@nicolo-ribaudo]: https://github.com/nicolo-ribaudo -[@suchipi]: https://github.com/suchipi -[@thorn0]: https://github.com/thorn0 -[@tjallingt]: https://github.com/tjallingt -[@vjeux]: https://github.com/vjeux -[@jameshenry]: https://github.com/JamesHenry -[#3531]: https://github.com/prettier/prettier/pull/3531 -[#3996]: https://github.com/prettier/prettier/pull/3996 -[#4192]: https://github.com/prettier/prettier/pull/4192 -[#4219]: https://github.com/prettier/prettier/pull/4219 -[#4268]: https://github.com/prettier/prettier/pull/4268 -[#4285]: https://github.com/prettier/prettier/pull/4285 -[#4288]: https://github.com/prettier/prettier/pull/4288 -[#4317]: https://github.com/prettier/prettier/pull/4317 -[#4326]: https://github.com/prettier/prettier/pull/4326 -[#4333]: https://github.com/prettier/prettier/pull/4333 -[#4341]: https://github.com/prettier/prettier/pull/4341 -[#4347]: https://github.com/prettier/prettier/pull/4347 -[#4353]: https://github.com/prettier/prettier/pull/4353 -[#4361]: https://github.com/prettier/prettier/pull/4361 -[#4367]: https://github.com/prettier/prettier/pull/4367 -[#4371]: https://github.com/prettier/prettier/pull/4371 -[#4372]: https://github.com/prettier/prettier/pull/4372 -[#4381]: https://github.com/prettier/prettier/pull/4381 -[#4385]: https://github.com/prettier/prettier/pull/4385 -[#4388]: https://github.com/prettier/prettier/pull/4388 -[#4392]: https://github.com/prettier/prettier/pull/4392 -[#4395]: https://github.com/prettier/prettier/pull/4395 -[#4397]: https://github.com/prettier/prettier/pull/4397 -[#4407]: https://github.com/prettier/prettier/pull/4407 -[#4408]: https://github.com/prettier/prettier/pull/4408 -[#4413]: https://github.com/prettier/prettier/pull/4413 -[#4414]: https://github.com/prettier/prettier/pull/4414 -[#4418]: https://github.com/prettier/prettier/pull/4418 -[#4423]: https://github.com/prettier/prettier/pull/4423 -[#4429]: https://github.com/prettier/prettier/pull/4429 -[#4431]: https://github.com/prettier/prettier/pull/4431 -[#4434]: https://github.com/prettier/prettier/pull/4434 -[#4435]: https://github.com/prettier/prettier/pull/4435 -[#4438]: https://github.com/prettier/prettier/pull/4438 -[#4440]: https://github.com/prettier/prettier/pull/4440 -[#4442]: https://github.com/prettier/prettier/pull/4442 -[#4447]: https://github.com/prettier/prettier/pull/4447 -[#4450]: https://github.com/prettier/prettier/pull/4450 -[#4451]: https://github.com/prettier/prettier/pull/4451 -[#4457]: https://github.com/prettier/prettier/pull/4457 -[#4471]: https://github.com/prettier/prettier/pull/4471 -[#4472]: https://github.com/prettier/prettier/pull/4472 -[#4475]: https://github.com/prettier/prettier/pull/4475 -[#4479]: https://github.com/prettier/prettier/pull/4479 -[#4484]: https://github.com/prettier/prettier/pull/4484 -[#4487]: https://github.com/prettier/prettier/pull/4487 -[#4490]: https://github.com/prettier/prettier/pull/4490 -[#4495]: https://github.com/prettier/prettier/pull/4495 -[#4504]: https://github.com/prettier/prettier/pull/4504 -[#4505]: https://github.com/prettier/prettier/pull/4505 -[#4512]: https://github.com/prettier/prettier/pull/4512 -[#4517]: https://github.com/prettier/prettier/pull/4517 -[#4528]: https://github.com/prettier/prettier/pull/4528 -[#4536]: https://github.com/prettier/prettier/pull/4536 -[#4542]: https://github.com/prettier/prettier/pull/4542 -[#4540]: https://github.com/prettier/prettier/pull/4540 -[#4543]: https://github.com/prettier/prettier/pull/4543 -[#4551]: https://github.com/prettier/prettier/pull/4551 diff --git a/website/blog/2018-07-29-1.14.0.md b/website/blog/2018-07-29-1.14.0.md deleted file mode 100644 index d1033d0d18..0000000000 --- a/website/blog/2018-07-29-1.14.0.md +++ /dev/null @@ -1,1045 +0,0 @@ ---- -author: Ika (@ikatyang) -authorURL: https://github.com/ikatyang -title: "Prettier 1.14: YAML Support" ---- - -This release adds YAML support, pragma (i.e. `/** @prettier */`) support for every language, and improves performance on large files. It also adds support for several new syntax features, and has a few formatting tweaks to make your code even prettier. ✨ - - - -## Highlights - -### YAML - -#### Support YAML ([#4563], [#4742], [#4773], [#4854] by [@ikatyang]) - -Prettier can now format YAML files! 🎉 - -The implementation is highly compliant with the [YAML spec](http://yaml.org/spec/), and backed by the excellent [`yaml`](https://github.com/eemeli/yaml) package thanks to [@eemeli]. A few highlights: - -##### Word wrap - -Just like in Markdown, we’ll hard-wrap prose at 80-characters if it doesn’t affect the meaning of the file. - -Input: - - -```yaml -> - Voilà! In view, a humble vaudevillian veteran cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valourous visitation of a bygone vexation stands vivified and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition! The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it’s my very good honour to meet you and you may call me V. -``` - -Output: (`--prose-wrap always`) - - -```yaml -> - Voilà! In view, a humble vaudevillian veteran cast vicariously as both victim - and villain by the vicissitudes of Fate. This visage, no mere veneer of - vanity, is a vestige of the vox populi, now vacant, vanished. However, this - valourous visitation of a bygone vexation stands vivified and has vowed to - vanquish these venal and virulent vermin vanguarding vice and vouchsafing the - violently vicious and voracious violation of volition! The only verdict is - vengeance; a vendetta held as a votive, not in vain, for the value and - veracity of such shall one day vindicate the vigilant and the virtuous. - Verily, this vichyssoise of verbiage veers most verbose, so let me simply add - that it’s my very good honour to meet you and you may call me V. -``` - -> Note: the [`proseWrap`](https://prettier.io/docs/en/options.html#prose-wrap) option is set to `preserve` by default so you’ll have to specify `always` or `never` to enable this feature. - -##### Ignore a portion of the file - -If for some reason you don’t want to format a part of the YAML file, you can always put an ignore comment before it: - - -```yaml -# prettier-ignore -key : value -hello: world -``` - -### Front Matter - -#### Format YAML front matter ([#4773] by [@ikatyang]) - -Prettier can now format `---`-delimited YAML front matter in CSS and Markdown files: - -Input & Output (Prettier 1.13): - - -```markdown ---- -key : value ---- - -# heading - -content -``` - -Output (Prettier 1.14): - - -```markdown ---- -key: value ---- - -# heading - -content -``` - -### Pragma - -#### Support `requirePragma`/`insertPragma` in every language ([#4688], [#4699], [#4713] by [@ikatyang]) - -Prettier 1.7.0 and 1.8.0 introduced two new options: -[`--require-pragma`](https://prettier.io/docs/en/options.html#require-pragma) and -[`--insert-pragma`](https://prettier.io/docs/en/options.html#insert-pragma). -However, these options were only supported in a few languages. -Now these options are available in every language, including YAML! - -- YAML - - - ```yaml - # @prettier - - key: value - ``` - -- CSS/Less/SCSS - - - ```css - /** @prettier */ - - .class { - display: none; - } - ``` - -- GraphQL - - - ```gql - # @prettier - - query Browse($offset: Int) { - browse(offset: $offset) - } - ``` - -- Vue - - - ```html - - - - ``` - -### JavaScript - -#### Never inline decorators unless they’re lone parameter decorators ([#4830] by [@suchipi]) - -Previously, decorators were always inlined since MobX inlined them by convention, -but reports from the community led us to discover that MobX is the only major library that follows this convention. -Prettier now puts decorators on their own lines unless they’re parameter decorators. - - -```ts -// Input -@observer -class OrderLine { - @observable - price: number = 0; - @observable amount: number = 1; - - foo(@required name) { - console.log(name); - } -} - -// Output (Prettier 1.13) -@observer -class OrderLine { - @observable price: number = 0; - @observable amount: number = 1; - - foo(@required name) { - console.log(name); - } -} - -// Output (Prettier 1.14) -@observer -class OrderLine { - @observable - price: number = 0; - @observable - amount: number = 1; - - foo(@required name) { - console.log(name); - } -} -``` - -#### Handle JSX whitespace separately from fbt whitespace ([#4717] by [@karl]) - -Previously, JSX whitespace was always preserved -since Facebook has a custom translation pipeline (`fbt`) that uses JSX syntax but treats whitespace differently than regular JSX, -which meant we couldn’t change JSX whitespace without breaking the Facebook codebase. -In Prettier 1.14, we now detect Facebook `fbt` tags and handle whitespace for them differently from other JSX tags, -improving the consistency across different but equivalent inputs. - - -```jsx -// Input and Output from Prettier 1.13 -first = ( -
- Text
- More text
- And more
-
-); - -second = ( -
- Text
More text
And more
-
-); - -third = ( -
- Text -
- More text -
- And more -
-
-); - -// Output from Prettier 1.14 -first = ( -
- Text -
- More text -
- And more -
-
-); - -second = ( -
- Text -
- More text -
- And more -
-
-); - -third = ( -
- Text -
- More text -
- And more -
-
-); -``` - -When the text separating tags or expressions is just a single character -we print the entire group on a single line where possible. - - -```jsx -// Input and Output from Prettier 1.13 -x = ( -
- {hour}:{minute}:{second} -
-); - -x = ( -
- {hour} - : - {minute} - : - {second} -
-); - -x = ( -
- {hour}: - {minute}: - {second} -
-); - -// Output from Prettier 1.14 -x = ( -
- {hour}:{minute}:{second} -
-); - -x = ( -
- {hour}:{minute}:{second} -
-); - -x = ( -
- {hour}:{minute}:{second} -
-); -``` - -It also improves the output of edges cases like this: - - -```jsx -// Input -this_really_should_split_across_lines = -
- before{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after -
- -// Output (Prettier 1.13) -this_really_should_split_across_lines = ( -
- before{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{ - stuff - }after -
-); - - -// Output (Prettier 1.14) -this_really_should_split_across_lines = ( -
- before - {stuff} - after - {stuff} - after - {stuff} - after - {stuff} - after - {stuff} - after - {stuff} - after - {stuff} - after -
-); -``` - -#### Break JSX in arrow functions in JSX expressions ([#4601] by [@duailibe]) - -In previous versions, JSX in arrow functions in JSX expressions followed the general fit-or-break rule, -but it’s less readable when iterating over an array. -Prettier 1.14 forces these arrow functions to break, improving readability. - - -```jsx -// Input -const UsersList = ({ users }) => ( -
-

Users list

-
    - {users.map(user => ( -
  • {user.name}
  • - ))} -
-
-) - -// Output (Prettier 1.13) -const UsersList = ({ users }) => ( -
-

Users list

-
    {users.map(user =>
  • {user.name}
  • )}
-
-); - -// Output (Prettier 1.14) -const UsersList = ({ users }) => ( -
-

Users list

-
    - {users.map(user => ( -
  • {user.name}
  • - ))} -
-
-); -``` - -### TypeScript - -#### Support for TypeScript 3.0 ([#4625], [#4757] by [@ikatyang]) - -A few new features that include new syntax are added in the upcoming TypeScript 3.0: -the [`unknown` type](https://github.com/Microsoft/TypeScript/pull/24439) and -[tuples in rest parameters and spread expressions](https://github.com/Microsoft/TypeScript/pull/24897). -Prettier 1.14 adds support for them so you can format them when TypeScript 3.0 is released. - - -```ts -// UnknownType -const json: unknown = JSON.parse(jsonText); - -// RestType -type Foo = [string, number]; -type Bar = [boolean, ...Foo]; - -// OptionalType -type Baz = [string, number?]; -``` - -### JSON - -#### Do not put values on a separate line from the key ([#4852] by [@ikatyang]) - -Putting long values on new rows is the core feature of Prettier, -but we found that it doesn’t improve readability for objects with long string values inside JSON files. -Prettier 1.14 will not move an object’s string value regardless if it fits the print width or not. - - -```json5 -// Input -{ - "description": "a long long long long long long long long long long long long long long long long long paragraph" -} - -// Output (Prettier 1.13) -{ - "description": - "a long long long long long long long long long long long long long long long long long paragraph" -} - -// Output (Prettier 1.14) -{ - "description": "a long long long long long long long long long long long long long long long long long paragraph" -} -``` - -### Markdown - -#### Only align lists if they’re already aligned ([#4893] by [@ikatyang]) - -Previously, we always align lists for [better indenting experience and -as a workaround for indented codeblock mis-parsing](https://prettier.io/blog/2018/02/26/1.11.0.html#respect-tabwidth-for-list-items-3990-by-ikatyang), -but this introduced double spaces in front of ordered lists, which is not common in markdown. -In Prettier 1.14, we only align lists in the following cases: - -- They’re already aligned. -- There’re at least two spaces in front of the first list item. -- There’s an indented codeblock inside of it. - -Input: - - -```md -1. 123 -1. 123 - ---- - -1. 123 -1. 123 - ---- - -11. 123 -1. 123 - ---- - -11. 123 -1. 123 - ---- - -1. 123 -1. 123 -``` - -Output: (Prettier 1.13) - - -```md -1. 123 -1. 123 - ---- - -1. 123 -1. 123 - ---- - -11. 123 -1. 123 - ---- - -11. 123 -1. 123 - ---- - -1. 123 -1. 123 -``` - -Output: (Prettier 1.14) - - -```md -1. 123 -1. 123 - ---- - -1. 123 -1. 123 - ---- - -11. 123 -1. 123 - ---- - -11. 123 -1. 123 - ---- - -1. 123 -1. 123 -``` - -### Performance - -#### Performance improvement on big files ([#4790], [#4848] by [@sompylasar]) - -The core feature of Prettier is to wrap lines when they go past the print width, -and to do this we need to calculate the visual width of every character. -The easiest way to count them is by using JavaScript’s `String#length` property -but some non-ASCII characters like CJK characters have widths larger than a Latin character. -As a workaround, we replaced those 2-char-wide characters with 2 spaces before calculating the string’s length. -This works fine but it also slows down Prettier because we have to run the replacement on every token. -In Prettier 1.14, we check if the string contains only ASCII characters -so we don’t need to perform unnecessary string replacement. -This results in a **20% speed-up** on large files. - -## Other changes - -### API/CLI - -#### Support relative paths for `plugins` and `pluginSearchDirs` in config files ([#4667] by [@ikatyang]) - -In Prettier 1.13, we introduced a new `pluginSearchDirs` option that changes where Prettier looks for plugins. -It worked well when specified in the CLI since it was always relative to the current directory, -but relative paths didn’t work in config files. -In Prettier 1.14, relative paths for `pluginSearchDirs` and `plugins` in config files are now supported. - -#### Do not throw error if `prettier` installed in a directory not named `prettier` ([#4706] by [@asottile]) - -We added support for globally installed plugins in Prettier 1.13 by searching up the directory tree to -find the nearest `node_modules` from `prettier`. We assumed that there would always be a `prettier` directory -which caused Prettier to crash if it was in a differently-named directory. -We changed our searching logic in Prettier 1.14 so you should now be able to rename the `prettier` directory if you need to -(for example if publishing a fork to npm). - -#### Support `filepath` in browser ([#4721] by [@ikatyang]) - -In Prettier 1.13, we added first-class support for running Prettier in the browser, but the only way to -choose which parser to use was via the `parser` option. Prettier 1.14 adds support for the `filepath` option in the browser -API, which will allow Prettier to infer which parser to use, just like the it can with the Node.js API. This -should be especially useful for web editor applications! - -#### Expose `isPreviousLineEmpty` to plugins ([#4748] by [@warrenseine]) - -Previously, we exposed `isNextLineEmpty` to plugins but not `isPreviousLineEmpty`. -Prettier 1.14 exposes it, because it can be useful for some scenarios like directives in C#. - -### JavaScript - -#### Support BigInt literals ([#4697] by [@ikatyang]) - -[BigInt](https://github.com/tc39/proposal-bigint) literals are now supported in the default `babylon` parser. - - -```js -const bigInt = 1n; -``` - -#### Support `throw` expressions ([#4695] by [@VojtechStep]) - -[Throw expressions](https://github.com/tc39/proposal-throw-expressions) are now supported in the default `babylon` parser. - - -```js -const assert = x => x || throw new Error('...'); -``` - -#### Always expand the first argument if the second argument is also a call expression ([#4657] by [@duailibe]) - -Previously, we had a special case to not break function calls -if there were only 2 parameters passed and the first parameter was a function. -This worked well, but if the second parameter was also a function, it didn’t look very good. - - -```js -// Input -somePromise.then((args) => { - this.props.receiveFavoritesActions(id, [].concat(...args)); -}, ({ isCanceled }) => !isCanceled && logger.warn(`Error getting actions for the product: ${id}`)); - -// Output (Prettier 1.13) -somePromise.then(args => { - this.props.receiveFavoritesActions(id, [].concat(...args)); -}, ({ isCanceled }) => !isCanceled && logger.warn(`Error getting actions for the product: ${id}`)); - -// Output (Prettier 1.14) -somePromise.then( - args => { - this.props.receiveFavoritesActions(id, [].concat(...args)); - }, - ({ isCanceled }) => - !isCanceled && logger.warn(`Error getting actions for the product: ${id}`) -); -``` - -#### Add parens for await in bind ([#4778] by [@ikatyang]) - -Previously, Prettier wrongly removed the necessary parentheses for `await` in the experimental bind syntax, -causing its meaning to be change. Prettier 1.14 now preserves the parentheses correctly. - - -```js -// Input -const doBothThings = async () => { - const request = doAsyncThing(); - return (await request)::doSyncThing(); -}; - -// Output (Prettier 1.13) -const doBothThings = async () => { - const request = doAsyncThing(); - return await request::doSyncThing(); // means `await (request::doSyncThing)` -}; - -// Output (Prettier 1.14) -const doBothThings = async () => { - const request = doAsyncThing(); - return (await request)::doSyncThing(); -}; -``` - -#### Allow top level `super` and `await` ([#4823] by [@ikatyang]) - -`super` and `await` are not allowed to be in places other than classes and async functions, respectively, -but our [range format](https://prettier.io/docs/en/options.html#range) option didn’t quite work properly when selecting the contents of a function. -Prettier 1.14 allows them to be everywhere. - - -```js -super(); - -await doSomething(); -``` - -#### Blacklist `this` and `super` in functional composition heuristics ([#4836] by [@princed]) - -In Prettier 1.13, we improved the formatting for functional composition functions (e.g., `pipe`, `compose`, etc.) -by putting their parameters on their own line, but this introduced false positives for functions with the same name in classes. -Prettier 1.14 blacklists `this` and `super` in functional composition heuristics. - - -```js -// Input -class X { - x() { - this.compose(a(), b); - super.compose(a(), b); - } -} - -// Output (Prettier 1.13) -class X { - x() { - this.compose( - a(), - b - ); - super.compose( - a(), - b - ); - } -} - -// Output (Prettier 1.14) -class X { - x() { - this.compose(a(), b); - super.compose(a(), b); - } -} -``` - -### TypeScript - -#### Support `import.meta` ([#4762] by [@ikatyang]) - -In Prettier 1.13, the version of the TypeScript parser we used did not support parsing `import.meta` syntax. -We updated our TypeScript parser in Prettier 1.14 so they are now parsed and formatted correctly. - - -```js -console.log(import.meta.url); -``` - -#### Optional property with StringLiteral key in class ([#4762] by [@ikatyang]) - -In the prior version, the `?` in an optional property with a string literal as the key was wrongly removed. -We fixed this bug in Prettier 1.14 so it won’t be removed. - - -```ts -// Input -export class ClassExample { - "a-prop"?: boolean; -} - -// Output (Prettier 1.13) -export class ClassExample { - "a-prop": boolean; -} - -// Output (Prettier 1.14) -export class ClassExample { - "a-prop"?: boolean; -} -``` - -#### Throw error on multiple super classes in class ([#4762] by [@ikatyang]) - -Classes are only allowed to have one parent class -but the TypeScript AST allows for multiple since the `extends` clause -has the same structure internally as the `implements` clause. -Previously, any extra super classes were silently dropped during printing, -which may have caused confusion after formatting. -In Prettier 1.14, they are now marked as syntax errors instead. - - -```ts -// Input -class Foo extends BarComponent, BazService, QuuxProvider {} - -// Output (Prettier 1.13) -class Foo extends BarComponent {} - -// Output (Prettier 1.14) -/* - SyntaxError: Classes can only extend a single class. -*/ -``` - -#### Support JSX spread child ([#4885] by [@ikatyang]) - -Previously, the `...` in children spread in JSX expressions were wrongly removed. -We fixed this issue in Prettier 1.14. - - -```tsx -// Input -const x =
{...[0]}
- -// Output (Prettier 1.13) -const x =
{[0]}
; - -// Output (Prettier 1.14) -const x =
{...[0]}
; -``` - -### Flow - -#### Support `.js.flow` extension ([#4777] by [@ikatyang]) - -[`.js.flow`](https://flow.org/en/docs/libdefs/creation/#toc-declaring-a-module) -is the extension for Flow declaration files but previously we didn’t recognize it. -In Prettier 1.14, they should be picked up automatically -so you don’t need to add overrides for them in config files. - -### CSS/Less/SCSS - -#### Handle newline between front-matter and comment correctly ([#4701] by [@evilebottnawi]) - -Multiple newlines between front matter and a CSS comment were replaced with a space in Prettier 1.13. -In Prettier 1.14, we print a newline between them instead. - - -```css -/* Input */ ---- -key: value ---- - -/* comment */ -.class { - display: none; -} - -/* Output (Prettier 1.13) */ ---- -key: value ---- - /* comment */ -.class { - display: none; -} - -/* Output (Prettier 1.14) */ ---- -key: value ---- - -/* comment */ -.class { - display: none; -} -``` - -#### Support at-rule ends with right curly bracket ([#4733] by [@davidgomes]) - -In the prior version, at-rules that ended with `}` were not parsed correctly. -Prettier 1.14 now correctly recognizes and formats them. - - -```scss -/* Input */ -@mixin placeholder { - &::placeholder {@content} -} - -/* Output (Prettier 1.13) */ -/* - SyntaxError: CssSyntaxError Unclosed block -*/ - -/* Output (Prettier 1.14) */ -@mixin placeholder { - &::placeholder { - @content; - } -} -``` - -### Markdown - -#### Preserve email autolink ([#4740] by [@ikatyang]) - -Autolinks are formatted as their url in the prior version, which is fine. -But there’s a special case for email links that they’ll be resolved as `mailto:` links. -In Prettier 1.14, email autolinks are preserved. - - -```md - - - - - - - - -``` - -#### Do not require space after markdown block language name ([#4783] by [@kachkaev]) - -In Prettier 1.12, we added the support for fenced codeblock lang followed by attributes, -which requires them to be separated by whitespaces. -But this introduced the inconsistency for codeblock highlighting in Atom that -codeblocks are highlighted but we do not format them. -We updated our detection logic in Prettier 1.14 so they should behave the same now. - - -````md - -```js{something=something} -const x = 1; -``` - - -```js{something=something} -const x = 1; -``` - - -```js{something=something} -const x = 1; -``` -```` - -#### Use language aliases to find parser for markdown codeblocks ([#4734] by [@ikatyang]) - -Previously, we used the language `name` and `extensions` to determine which parser to use for codeblock formatting, -but we found that it’s impossible to format `JSON with Comments` codeblocks and keep syntax highlighter working at the same time -since they share the same `.json` extension with `JSON` and the comment syntax highlighting is only available in `JSON5`. -We added the support for using the language `aliases` to find parser in Prettier 1.14 -so you should be able to use `jsonc` to format and trigger syntax highlighting for `JSON with Comments` codeblocks. - - -````md - -```jsonc -// comment -{"a":1} -``` - - -```jsonc -// comment -{"a":1} -``` - - -```jsonc -// comment -{ "a": 1 } -``` -```` - -#### Preserve entity for encoded character if its code point is greater than U+FFFF ([#4832] by [@ikatyang]) - -The markdown parser we use (`remark`) parses every encoded character into a single AST node -so that we’re able to restore the encoded character by detecting if the value in the AST node is in length of 1. -But there’s an exception that a single character can be in length of 2 if its code point is greater than 0xffff -since JavaScript uses UTF-16 (2 bytes) to encode strings. -Prettier 1.14 correctly recognizes these characters so they won’t be transformed into the literal character. - - -````md - -😉 - - -😉 - - -😉 -```` - -### Vue - -#### Support range format for Vue files ([#4868] by [@ikatyang]) - -Previously, [range formatting](https://prettier.io/docs/en/options.html#range) was not available in Vue, -but Prettier 1.14 adds support for it. - -### GraphQL - -#### Preserve linebreak in non-block stringValue ([#4808] by [@ikatyang]) - -Non-block string values are only allowed to be in a single line -but Prettier 1.13 wrongly transformed the escaped `\n` into a real newline. -Prettier 1.14 now correctly prints `\n`. - - -```gql -# Input -{ - foo(input: {multiline: "ab\ncd"}) { id } -} - -# Output (Prettier 1.13) -{ - foo(input: { multiline: "ab -cd" }) { - id - } -} - -# Output (Prettier 1.14) -{ - foo(input: { multiline: "ab\ncd" }) { - id - } -} -``` - -[@asottile]: https://github.com/asottile -[@davidgomes]: https://github.com/davidgomes -[@duailibe]: https://github.com/duailibe -[@eemeli]: https://github.com/eemeli -[@evilebottnawi]: https://github.com/evilebottnawi -[@ikatyang]: https://github.com/ikatyang -[@kachkaev]: https://github.com/kachkaev -[@karl]: https://github.com/karl -[@princed]: https://github.com/princed -[@sompylasar]: https://github.com/sompylasar -[@suchipi]: https://github.com/@suchipi -[@vojtechstep]: https://github.com/VojtechStep -[@warrenseine]: https://github.com/warrenseine -[#4563]: https://github.com/prettier/prettier/pull/4563 -[#4601]: https://github.com/prettier/prettier/pull/4601 -[#4625]: https://github.com/prettier/prettier/pull/4625 -[#4657]: https://github.com/prettier/prettier/pull/4657 -[#4667]: https://github.com/prettier/prettier/pull/4667 -[#4688]: https://github.com/prettier/prettier/pull/4688 -[#4695]: https://github.com/prettier/prettier/pull/4695 -[#4697]: https://github.com/prettier/prettier/pull/4697 -[#4699]: https://github.com/prettier/prettier/pull/4699 -[#4701]: https://github.com/prettier/prettier/pull/4701 -[#4706]: https://github.com/prettier/prettier/pull/4706 -[#4713]: https://github.com/prettier/prettier/pull/4713 -[#4717]: https://github.com/prettier/prettier/pull/4717 -[#4721]: https://github.com/prettier/prettier/pull/4721 -[#4733]: https://github.com/prettier/prettier/pull/4733 -[#4734]: https://github.com/prettier/prettier/pull/4734 -[#4740]: https://github.com/prettier/prettier/pull/4740 -[#4742]: https://github.com/prettier/prettier/pull/4742 -[#4748]: https://github.com/prettier/prettier/pull/4748 -[#4757]: https://github.com/prettier/prettier/pull/4757 -[#4762]: https://github.com/prettier/prettier/pull/4762 -[#4773]: https://github.com/prettier/prettier/pull/4773 -[#4777]: https://github.com/prettier/prettier/pull/4777 -[#4778]: https://github.com/prettier/prettier/pull/4778 -[#4783]: https://github.com/prettier/prettier/pull/4783 -[#4790]: https://github.com/prettier/prettier/pull/4790 -[#4808]: https://github.com/prettier/prettier/pull/4808 -[#4823]: https://github.com/prettier/prettier/pull/4823 -[#4830]: https://github.com/prettier/prettier/pull/4830 -[#4832]: https://github.com/prettier/prettier/pull/4832 -[#4836]: https://github.com/prettier/prettier/pull/4836 -[#4848]: https://github.com/prettier/prettier/pull/4848 -[#4852]: https://github.com/prettier/prettier/pull/4852 -[#4854]: https://github.com/prettier/prettier/pull/4854 -[#4868]: https://github.com/prettier/prettier/pull/4868 -[#4885]: https://github.com/prettier/prettier/pull/4885 -[#4893]: https://github.com/prettier/prettier/pull/4893 diff --git a/website/blog/2018-11-07-1.15.0.md b/website/blog/2018-11-07-1.15.0.md deleted file mode 100644 index 26ed13a731..0000000000 --- a/website/blog/2018-11-07-1.15.0.md +++ /dev/null @@ -1,1849 +0,0 @@ ---- -author: Ika (@ikatyang) -authorURL: https://github.com/ikatyang -title: "Prettier 1.15: HTML, Vue, Angular and MDX Support" ---- - -This release adds support for HTML, Vue, Angular and MDX. -It also respects decorator position, -adds an option for JSX single quotes, -allows parser inference via shebang, -adds support for several new syntax features, and has a few formatting tweaks. - - - -## Highlights - -### HTML/Vue/Angular - -#### Support HTML, Vue, and Angular ([#5259] by [@ikatyang], [#4753] by [@evilebottnawi], [#2083] by [@azz]) - -Prettier can now format HTML, Vue and Angular files! 🎉 - -We use [angular-html-parser][angular-html-parser], an HTML parser extracted from [Angular][@angular/compiler/ml_parser], -to parse these HTML and HTML template files so it should be highly compliant with the HTML spec thanks to the Angular team. - -[angular-html-parser]: https://github.com/ikatyang/angular-html-parser/tree/master/packages/angular-html-parser -[@angular/compiler/ml_parser]: https://github.com/angular/angular/tree/master/packages/compiler/src/ml_parser - -A few highlights: - -##### Whitespace-sensitive formatting - -As you may notice during daily HTML works, the following two cases won't produce the same output: - -| | html | output | -| -------------- | :------------: | :----------: | -| with spaces | `1 2 3` | 1 2 3 | -| without spaces | `123` | 123 | - -This happens because whitespace is significant in inline elements. - -For this reason, we cannot safely format - - -```html -
Prettier is an opinionated code formatter. -``` - -into - - -```html - - Prettier is an opinionated code formatter. - -``` - -since it may modify the displayed output in the browser. - -Instead of breaking your code or just doing nothing, we introduce _whitespace-sensitive formatting_, which: - -- follows the default CSS `display` value for every element to identify if the whitespace inside it is significant, -- and wraps the tags in such a way as to avoid adding or removing significant whitespace. - -For example: - - -```html - - - -Est molestiae sunt facilis qui rem. -
Architecto rerum architecto incidunt sint.
- - -Est molestiae sunt facilis qui rem. -
- Architecto rerum architecto incidunt sint. -
-``` - -We also allow magic comments (e.g., ``) to tell Prettier how to format elements -due to the fact that CSS display can be changed: - - -```html - - -Est molestiae sunt facilis qui rem. - - - - - Est molestiae sunt facilis qui rem. - -``` - -There's also an option for the global whitespace sensitivity -in case you may want maximum safety or you just don't care about that whitespace: - -`--html-whitespace-sensitivity` (defaults to `css`) - -- `css` - Respect the default value of CSS `display` property. -- `strict` - All whitespace is considered significant. -- `ignore` - All whitespace is considered insignificant. - -##### Automatic parser inference - -Prettier uses filename to infer which parser to use. Here's the default patterns for HTML, Vue, and Angular: - -- `*.html`: `--parser html` -- `*.component.html`: `--parser angular` -- `*.vue`: `--parser vue` - -Make sure your filename matches the correct parser (especially for Angular users); if it does not, -you will have to manually specify which parser to use via the [overrides] field. - -[overrides]: https://prettier.io/docs/en/configuration.html#configuration-overrides - -Note that framework-specific formatting won't be triggered in `--parser html`. - -##### HTML template literal in JavaScript - -This release also adds support for the `html` template tag (or a “tag” comment containing `HTML`): - -- `` html`code` `` -- `` /* HTML */ `code` `` - - -```js -// input -const foo = html`
Architecto rerum ${interpolation} architecto incidunt sint.
`; - -// output -const foo = html` -
- Architecto rerum ${interpolation} architecto incidunt sint. -
-`; -``` - -##### Vue formatting - -The following Vue-specific syntax structures are supported: - -- interpolation - - `{{ something }}` -- attribute - - `v-something` - - `:something` - - `@something` - - `v-for` - - `slot-scope` - -##### Angular formatting - -The following Angular-specific syntax structures are supported: - -- interpolation - - `{{ something }}` -- attribute - - `(something)` - - `[something]` - - `[(something)]` - - `*something` -- inline template - - `` @Component({ template: `
Hello World
` }) `` - -### MDX - -#### Support MDX ([#4975] by [@ikatyang]) - -[MDX](https://mdxjs.com/) is a markdown extension that lets you use JSX to build cool documentation. -You can now use Prettier to format it, and we’ll format both the Markdown and JS pieces for you! - - -```jsx - - -import { - colors } from - './theme' -import Palette from './components/palette' - -# Colors - - - - - -import { colors } from "./theme"; -import Palette from "./components/palette"; - -# Colors - - -``` - -### JavaScript - -#### Flatten else-branch for nested ternaries ([#5039] by [@suchipi], [#5272] by [@duailibe], [#5333] by [@ikatyang]) - -Previously, nested ternaries were always indented, which caused increasing levels of indentation for deeply-nested ternaries. -To solve this problem, we flattened the else-branch for nested ternaries in a fashion similar to how `if..else if..else` blocks are formatted. - - -```js -// Input -const example1 = - someValue === 'a' ? 'hello world, branch a' - : someValue === 'b' ? 'hello world, branch a && b' - : someValue === 'c' ? 'hello world, branch a && b && c' - : someValue === 'd' ? 'hello world, branch a && b && c && d' - : null; - -const example2 = - someValue === 'a' - ? someValue === 'b' - ? someValue === 'c' - ? 'hello world, branch a && b && c' - : 'hello world, branch a && b && !c' - : 'hello world, branch a && !b' - : null; - -// Output (Prettier 1.14) -const example1 = - someValue === "a" - ? "hello world, branch a" - : someValue === "b" - ? "hello world, branch a && b" - : someValue === "c" - ? "hello world, branch a && b && c" - : someValue === "d" - ? "hello world, branch a && b && c && d" - : null; - -const example2 = - someValue === "a" - ? someValue === "b" - ? someValue === "c" - ? "hello world, branch a && b && c" - : "hello world, branch a && b && !c" - : "hello world, branch a && !b" - : null; - -// Output (Prettier 1.15) -const example1 = - someValue === "a" - ? "hello world, branch a" - : someValue === "b" - ? "hello world, branch a && b" - : someValue === "c" - ? "hello world, branch a && b && c" - : someValue === "d" - ? "hello world, branch a && b && c && d" - : null; - -const example2 = - someValue === "a" - ? someValue === "b" - ? someValue === "c" - ? "hello world, branch a && b && c" - : "hello world, branch a && b && !c" - : "hello world, branch a && !b" - : null; -``` - -#### Keep decorators inline if they were written inline ([#5188] by [@duailibe]) - -Prior to Prettier 1.14, we were always placing decorators on the same line as what they were decorating. - -We received feedback from some users that this was not ideal formatting, so after consideration, we changed it and in Prettier 1.14, decorators were always placed on a separate line from what they were decorating. - -However, we received feedback from other users that this formatting was not ideal in all cases. - -We want to have consistent formatting in Prettier when we can, so we tried to think of a heuristic that we could use to decide when to put decorators on the same line and when to put them on another line. - -However, after a long discussion in [#4924], we concluded that there's no reliable way to identify which should be inlined and which shouldn't be, so in Prettier 1.15 we decided to respect the original style that the user wrote. So if they put a newline between the decorator and what it decorates, we will print a newline there. If they didn't, we won't. - - -```js -// Input -class Hello { - @decorator inline = 'value'; - - @decorator - ownLine = 'value'; - - @decorator({ - hello: 'world' - }) multiLine = 'value'; -} - -// Output (Prettier 1.14) -class Hello { - @decorator - inline = "value"; - - @decorator - ownLine = "value"; - - @decorator({ - hello: "world" - }) - multiLine = "value"; -} - -// Output (Prettier 1.15) -class Hello { - @decorator inline = "value"; - - @decorator - ownLine = "value"; - - @decorator({ - hello: "world" - }) - multiLine = "value"; -} -``` - -#### Respect original decorator order ([#5207] by [@duailibe]) - -Decorators are still not part of the official ECMA standard and -[where decorators on exported classes should go] is a question whose answer has not yet been decided. -To help proposal authors to get feedback, -Babel 7 added support for both decorators before and after the exported classes. -Prettier 1.15 adds support for them and respects where you put the decorator(s). -(Once the spec is standardized, we'll change it to be consistent and not respect user input.) - - -```js -// decorator before export -@decorator export class Bar {} - -// decorator after export -export @decorator class Foo {} -``` - -[where decorators on exported classes should go]: https://babeljs.io/blog/2018/09/17/decorators#where-should-decorators-on-exported-classes-go - -#### Improved object-break heuristic ([#5205] by [@j-f1]) - -Previously, Prettier would automatically break objects onto multiple lines if they didn’t fit within the print width. -Prettier would also keep objects broken onto multiple lines if there was a newline somewhere inside them in the input code. -This made it difficult to collapse an object since you had to manually merge the object onto one line. -Since manual formatting changes are a task Prettier aims to eliminate, we’ve changed the behavior to only check for a newline between the `{` and the first key: - - -```js -// Input -const data = { foo: 'bar', - baz: 'quux' -} -/* You’d get this format by deleting the newline after the `{` */ - -// Output (Prettier 1.14) -const data = { - foo: 'bar', - baz: 'quux' -} - -// Output (Prettier 1.15) -const data = { foo: 'bar', baz: 'quux' } -``` - -### JSX - -#### Option to use single quotes in JSX ([#4798] by [@smirea]) - -After [huge demand] from the community, -Prettier 1.15 adds an option for printing single quotes in JSX: `--jsx-single-quote` (or `jsxSingleQuote` in the config/API). - -[huge demand]: https://github.com/prettier/prettier/issues/1080 - - -```jsx -// with --jsx-single-quote -
world
- -// without --jsx-single-quote -
world
-``` - -#### Split JSX text correctly ([#5006] by [@yuliaHope]) - -Prettier 1.14 accidentally introduced some very unfortunate line breaks in JSX. Those cases have now been fixed. - - -```jsx -// Input -
- Sales tax estimated using a rate of {salesTax * 100}%. -
; -(avg. {value}/5); - - Go to {this.props.org.name}'s profile -; - -// Output (Prettier 1.14) -
- Sales tax estimated using a rate of {salesTax * 100} - %. -
; - - (avg. {value} - /5) -; - - Go to {this.props.org.name} - 's profile -; - -// Output (Prettier 1.15) -
Sales tax estimated using a rate of {salesTax * 100}%.
; -(avg. {value}/5); - - Go to {this.props.org.name}'s profile -; -``` - -### Flow - -#### Support inexact ([#5304] by [@jbrown215], [#5356] by [@existentialism]) - -The Flow team [plans to treat all object types as _exact_ by default][inexact] in the future, -so they introduced a new syntax to indicate if an object type is inexact. -This syntax is now supported in Prettier 1.15. - -[inexact]: https://medium.com/flow-type/on-the-roadmap-exact-objects-by-default-16b72933c5cf - - -```ts -type T = { - a: number, - ... -} -``` - -#### Do not break Flow typecast comments ([#5280], [#5290] by [@swac]) - -Previously, parentheses that surrounds Flow typecast comments were sometimes removed, -which would break Flow's comment syntax. This issue has been fixed in Prettier 1.15. - - -```js -// Input -(obj /*: Class */).property - -// Output (Prettier 1.14) -obj /*: Class */.property; - -// Output (Prettier 1.15) -(obj /*: Class */).property; -``` - -### Markdown - -#### Preserve math syntax ([#5050], [#5220] by [@ikatyang]) - -Previously, some of [remark-math]'s syntax structures were mangled since we treated them as normal text. -They are now preserved in Prettier 1.15 so you can safely use math syntax. - -[remark-math]: https://github.com/Rokt33r/remark-math - - -```md -$inline-math$ - -$$ -block-math -$$ -``` - -## Other changes - -### API/CLI - -#### Infer parser via shebang if there's no extension in the filename ([#5149] by [@haggholm]) - -Previously, we used filename and extension to infer which parser to use, -but often there's no extension for CLI scripts, -so the user has to specify the parser manually, which is not ideal. -In Prettier 1.15, -when formatting a file with no extension, -we'll look at the first line of the file, -and if there's a shebang, -we'll use it to infer which parser to use. - - -# Input
-$ cat bin/example
-\#!/usr/bin/env node
-  require ( "../src/cli" ) . run ( )
-
-$ prettier bin/example
-
-# Output (Prettier 1.14)
-[error] No parser could be inferred for file: bin/example
-
-# Output (Prettier 1.15)
-#!/usr/bin/env node
-require("../src/cli").run(); -
- -#### Add a new `trim` command to trim whitespaces in the current line ([#4772] by [@warrenseine]) - -Previously in the plugin API, there was no method to delete the current line’s indentation. -It's possible to use some workarounds to achieve the same goal, but there wasn't a reliable workaround, -so we introduced a new [`trim`] command to trim whitespaces in a reliable way. - -[`trim`]: https://github.com/prettier/prettier/blob/master/commands.md#trim - -#### Colorful validation message ([#5020], [#5057] by [@ikatyang]) - -Previously, there was no color for the option validation error message, -so it wasn’t easy to see what option had an invalid value passed to it, and what the valid values were. -In Prettier 1.15, you should be able to understand what's going on at a glance. - - -# Input
-$ prettier filename.js --trailing-comma wow
-
-# Output (Prettier 1.14)
-[error] Invalid \`\`--trailing-comma\`\` value. Expected "all", "es5" or "none", but received \`"wow"\`. -

-# Output (Prettier 1.15)
-[error] Invalid --trailing-comma value. Expected "all", "es5" or "none", but received "wow". -
- -#### Allow printer to preprocess the AST ([#5041] by [@ikatyang]) - -Sometimes we need to transform the AST to make it easier to print. -Previously, it was done in the parser but this way it also exposed the internal stuff to external users, -who may have tried to build a custom parser, which is not ideal. -In Prettier 1.15, you can now use `printer.preprocess` to preprocess the AST without exposing any internals of the API. - -```ts -interface Printer { - preprocess(ast: AST, options: object): AST; -} -``` - -#### Better error message for unsupported config format ([#4969] by [@ikatyang]) - -Previously, loading a config file of an unsupported format would throw an error message -that looks like a bug in Prettier, so we improved the message in Prettier 1.15. - - -# Input
-$ prettier filename.js --config .prettierrc.wow
-
-# Output (Prettier 1.14)
-[error] Invalid configuration file: Cannot read property 'sync' of undefined -

-# Output (Prettier 1.15)
-[error] Invalid configuration file: No sync loader specified for extension ".wow" -
- -#### Add an option to enforce line endings ([#5327] by [@kachkaev]) - -Previously, Prettier always respected your original line endings, which is fine in the most cases. -But when people collaborate on a project from different operating systems, -it becomes easy to end up with mixed line endings in the central git repository and cause large diffs. -Prettier 1.15 adds an option `--end-of-line ` to help you deal with these line ending issues. - -### JavaScript - -#### Treat single-star comments as JSDoc ([#5206] by [@j-f1], [#5330] by [@lydell]) - -Prettier will now properly indent JSDoc-style comments with only a single `*` on the first line (`/*` vs `/**`) when the comment’s indentation changes: - - -```js -// Input -if (true) { - /* - * Oh no - */ -} - -// Output (Prettier 1.14) -if (true) { - /* - * Oh no - */ -} - -// Output (Prettier 1.15) -if (true) { - /* - * Oh no - */ -} -``` - -#### Correct parentheses for mixed exponentiation/modulo ([#5243] by [@bakkot]) - -Previously, parentheses for mixed exponentiation/modulo were wrongly removed, -but we fixed this in Prettier 1.15. - - -```js -// Input -const val = (n % 10) ** 2 - -// Output (Prettier 1.14) -const val = n % 10 ** 2; - -// Output (Prettier 1.15) -const val = (n % 10) ** 2; -``` - -#### Correctly print comments in `try..finally` ([#5252] by [@aquibm]) - -In previous versions, some comments in a `try`-`finally` statement were printed in the wrong order. -Prettier now prints them correctly. - - -```js -// Input -// comment 1 -try { - // comment 2 -} -// comment 3 -finally // comment 4 -{ - // comment 5 -} - -// Output (Prettier 1.14) -// comment 1 -try { - // comment 2 -} finally { // comment 4 - // comment 3 - // comment 5 -} - -// Output (Prettier 1.15) -// comment 1 -try { - // comment 2 -} finally { - // comment 3 - // comment 4 - // comment 5 -} -``` - -#### Printing comments in catch clause to the correct place ([#5202] by [@duailibe]) - -Comments in `catch` clauses are now printed on their own line just like other clauses. - - -```js -// Input -try {} catch ( - // comment - e -) {} - -// Output (Prettier 1.14) -try { -} catch (// comment -e) {} - -// Output (Prettier 1.15) -try { -} catch ( - // comment - e -) {} -``` - -#### Inline the argument if it's an arrow function with conditional expression as body ([#5209] by [@duailibe]) - -There's no need to add an extra indentation level for -a function call argument that's an arrow function with conditional expression as body. -We now inline them in Prettier 1.15. - - -```js -// Input -x.then(() => a ? - veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong: - veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong -); - -// Output (Prettier 1.14) -x.then( - () => - a - ? veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong - : veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong -); - -// Output (Prettier 1.15) -x.then(() => - a - ? veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong - : veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong -); -``` - -#### Fix unexpected indentation in variable declarator caused by comments ([#5190] by [@duailibe]) - -In previous versions, comments in variable declarations caused variable declarators to be printed without indentation, -but this has been fixed in Prettier 1.15. - - -```js -// Input -const // Comment - a = 1; - -// Output (Prettier 1.14) -const // Comment -a = 1; - -// Output (Prettier 1.15) -const // Comment - a = 1; -``` - -#### Do not remove parens for ternary in optional member expression ([#5179] by [@existentialism]) - -Prettier 1.14 was incorrectly removing parens around ternary operators when they appeared within optional member expressions (`?.`). Those cases are now printed correctly in Prettier 1.15. - - -```js -// Input -(a ? b : c)?.d; - -// Output (Prettier 1.14) -a ? b : c?.d; - -// Output (Prettier 1.15) -(a ? b : c)?.d; -``` - -#### Escape `${` as well as backticks in GraphQL tags ([#5137] by [@lydell]) - -Previously, interpolation-like strings were wrongly unescaped in embedded GraphQL, -which led to JavaScript treating it as an interpolation. They're correctly escaped in Prettier 1.15. - - -```js -// Input -const schema = gql` -type Project { - "Pattern: \`\${project}\`" - pattern: String -} -`; - -// Output (Prettier 1.14) -const schema = gql` - type Project { - "Pattern: \`${project}\`" - pattern: String - } -`; - -// Output (Prettier 1.15) -const schema = gql` - type Project { - "Pattern: \`\${project}\`" - pattern: String - } -`; -``` - -#### Do not strip quotes in keys if they're not es5 compatible ([#5157] by [@koba04]) - -Previously, Prettier stripped quotes in keys if they weren’t necessary in ES2015, -which caused the output to be incompatible with ES5. -Prettier 1.15 only strips them if they're not necessary in ES5. - - -```js -// Input -var obj = { - "𐊧": 'ok', - 𐊧: 'ok' -}; - -// Output (Prettier 1.14) -var obj = { - 𐊧: "ok", - 𐊧: "ok" -}; - -// Output (Prettier 1.15) -var obj = { - "𐊧": "ok", - 𐊧: "ok" -}; -``` - -#### Do not hug arguments if the second argument in function is a ternary ([#5151] by [@onurtemizkan]) - -We have some special cases that will _hug_ function call arguments -if the first one is a function and the second one is a not a complex expression, -but we considered ternaries non-complex expressions. They actually can be complex, -so we’ve changed this in Prettier 1.15. - - -```js -// Input -func( - () => { thing(); }, - something(longArgumentName, anotherLongArgumentName) ? someOtherThing() : somethingElse(true, 0) -); - -// Output (Prettier 1.14) -func(() => { - thing(); -}, something(longArgumentName, anotherLongArgumentName) ? someOtherThing() : somethingElse(true, 0)); - -// Output (Prettier 1.15) -func( - () => { - thing(); - }, - something(longArgumentName, anotherLongArgumentName) - ? someOtherThing() - : somethingElse(true, 0) -); -``` - -#### Add support for timeouts passed as numbers to test functions ([#5085] by [@j-f1]) - -This preserves Prettier’s special formatting for testing functions when a timeout (number) is passed as a third parameter: - - -```js -// Input -it('Handles at least 10k untracked files without failing', async () => { - hello() -}, 25000) - -// Output (Prettier 1.14) -it( - "Handles at least 10k untracked files without failing", - async () => { - hello(); - }, - 25000 -); - -// Output (Prettier 1.15) -it('Handles at least 10k untracked files without failing', async () => { - hello() -}, 25000) -``` - -#### Format beforeEach-like calls like regular function calls ([#5011] by [@ericsakmar]) - -Previously, arguments in `beforeEach` were wrongly hugged. We've fixed this issue in Prettier 1.15. - - -```js -// Input -beforeEach(done => - startService() - .pipe(tap(service => (instance = service))) - .subscribe(() => done()), -); - -// Output (Prettier 1.14) -beforeEach(done => - startService() - .pipe(tap(service => (instance = service))) - .subscribe(() => done())); - -// Output (Prettier 1.15) -beforeEach(done => - startService() - .pipe(tap(service => (instance = service))) - .subscribe(() => done()) -); -``` - -#### Print pipeline operator's leading comment on its own line ([#5015] by [@flxwu]) - -In Prettier 1.14, a comment in front of a pipeline operator causes the right argument to be not indented. -This issue has been fixed in Prettier 1.15. - - -```js -// Input -function pipeline() { - 0 - // Comment - |> x -} - -// Output (Prettier 1.14) -function pipeline() { - 0 - |> // Comment - x; -} - -// Output (Prettier 1.15) -function pipeline() { - 0 |> - // Comment - x; -} -``` - -#### Preserve dangling comments in `new` expressions ([#5017] by [@flxwu]) - -Passing a comment instead of an expression to a `new` call is now preserved -instead of being pulled out of the parens. - - -```js -// Input -new Thing(/* comment */) - -// Output (Prettier 1.14) -new Thing /* comment */(); - -// Output (Prettier 1.15) -new Thing(/* comment */); -``` - -#### Remove redundant ASI protection for bind expression ([#4970] by [@TitanSnow]) - -Unnecessary semicolons for bind expressions are removed with `--no-semi` in Prettier 1.15. - - -```js -// Input -a::b.c - -// Output (Prettier 1.14) -;a::b.c - -// Output (Prettier 1.15) -a::b.c -``` - -#### Do not remove necessary parens in bind expression ([#4964] by [@TitanSnow]) - -Necessary parens in bind expressions are preserved in Prettier 1.15. - - -```js -// Input -a::(b.c()); - -// Output (Prettier 1.14) -a::b.c(); - -// Output (Prettier 1.15) -a::(b.c()); -``` - -#### Fix indentation for ternary in function call ([#4368] by [@malcolmsgroves]) - -Logical expressions in a ternary in a function call are now indented correctly. - - -```js -// Input -fn( - bifornCringerMoshedPerplexSawder, - askTrovenaBeenaDependsRowans, - glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && - anodyneCondosMalateOverateRetinol // <-- - ? annularCooeedSplicesWalksWayWay - : kochabCooieGameOnOboleUnweave -); - -// Output (Prettier 1.14) -fn( - bifornCringerMoshedPerplexSawder, - askTrovenaBeenaDependsRowans, - glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && - anodyneCondosMalateOverateRetinol // <-- - ? annularCooeedSplicesWalksWayWay - : kochabCooieGameOnOboleUnweave -); - -// Output (Prettier 1.15) -fn( - bifornCringerMoshedPerplexSawder, - askTrovenaBeenaDependsRowans, - glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && - anodyneCondosMalateOverateRetinol // <-- - ? annularCooeedSplicesWalksWayWay - : kochabCooieGameOnOboleUnweave -); -``` - -#### Do not move comments in `import`s ([#5016] by [@ericsakmar]) - -Comments in `import`s won't be moved output of the `import`. - - -```js -// Input -import x, { - // comment - y -} from 'z'; - - -// Output (Prettier 1.14) -import x, { y } from "z"; -// comment - -// Output (Prettier 1.15) -import x, { - // comment - y -} from "z"; -``` - -#### Fix unstable `while` comment ([#5251] by [@jaideng123]) - -Comments in `while` are now correctly formatted -so that it does not need to be formatted twice to get to a stable output. - - -```js -// Input -while( - true - // Comment -) {} - -// First Output (Prettier 1.14) -while (true) // Comment -{} - -// Second Output (Prettier 1.14) -while ( - true // Comment -) {} - -// First & Second Output (Prettier 1.15) -while ( - true - // Comment -) {} -``` - -#### Stably print comments between function declaration and its body ([#5250] by [@jaideng123]) - -Comments between a function declaration and its body do not need to be formatted twice to get the final result now. - - -```js -// Input -function foo() // this is a function -{ - return 42 -} - -// First Output (Prettier 1.14) -function foo() { // this is a function - return 42; -} - -// Second Output (Prettier 1.14) -function foo() { - // this is a function - return 42; -} - -// First & Second Output (Prettier 1.15) -function foo() { - // this is a function - return 42; -} -``` - -### JSX - -#### Do not break logical expression chain in JSX ([#5092] by [@duailibe]) - -Unnecessary indentations for logical expression chains in JSX are now prevented. - - -```js -// Input -const TestComponent = () => { - return ( - <> - {cats && memes && ( - - )} - - ); -} - -// Output (Prettier 1.14) -const TestComponent = () => { - return ( - <> - {cats && - memes && ( - - - - )} - - ); -}; - -// Output (Prettier 1.15) -const TestComponent = () => { - return ( - <> - {cats && memes && ( - - - - )} - - ); -}; -``` - -#### Do not change non-breaking whitespace into the regular one ([#5165] by [@vjeux], [#5334] by [@ikatyang]) - -Previously, non-breaking whitespaces were treated as regular whitespaces, -which caused them to be replaced with regular whitespaces. -This issue has been fixed in Prettier 1.15. - -(`·` represents a non-breaking whitespace) - - -```js -// Input -function OhMyWhitespace() { - return ( - -

- Supprimer l’objectif «·{goal.name}·»·? -

-
- ) -} - -// Output (Prettier 1.14) -function OhMyWhitespace() { - return ( - -

- Supprimer l’objectif « - {goal.name} - ·»·? -

-
- ); -} - -// Output (Prettier 1.15) -function OhMyWhitespace() { - return ( - -

Supprimer l’objectif «·{goal.name}·»·?

-
- ); -} -``` - -#### Do not break simple jsx opening tag ([#5078] by [@duailibe]) - -Simple jsx opening tags are no longer broken onto multiple lines. - - -```jsx -// Input -function HelloWorld() { - const listItemText = ( - {`Two Factor Authentication is ${enabledText}`} - } - /> - ); -} - -// Output (Prettier 1.14) -function HelloWorld() { - const listItemText = ( - {`Two Factor Authentication is ${enabledText}`} - } - /> - ); -} - -// Output (Prettier 1.15) -function HelloWorld() { - const listItemText = ( - {`Two Factor Authentication is ${enabledText}`} - } - /> - ); -} -``` - -#### Fix a regression for arrow function in jsx expression ([#5063] by [@ikatyang]) - - -```jsx -// Input -
- {scopes.filter(scope => scope.value !== "").map((scope, i) => ( - - ))} -
; - -// Output (Prettier 1.14) -
- {scopes.filter(scope => scope.value !== "").map((scope, i) => ( - - ))} -
; - -// Output (Prettier 1.15) -
- {scopes - .filter(scope => scope.value !== "") - .map((scope, i) => ( - - ))} -
; -``` - -### Flow - -#### Inline generics with a single identifier ([#5066] by [@duailibe]) - -Generics with a single identifier are now always inlined. - - -```ts -// Input -const longVariableName: Array = this.foo.bar.baz.collider.body.vertices.reduce(); - -// Output (Prettier 1.14) -const longVariableName: Array< - number -> = this.foo.bar.baz.collider.body.vertices.reduce(); - -// Output (Prettier 1.15) -const longVariableName: Array = this.foo.bar.baz.collider.body.vertices.reduce(); -``` - -#### Do not always inline classes in `extends` ([#5244] by [@aquibm]) - -Classes in `extends` are now correctly broken into multiple lines. - - -```ts -// Input -declare interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 { - x: string; -} - -// Output (Prettier 1.14) -declare interface ExtendsMany - extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 { - x: string; -} - -// Output (Prettier 1.15) -declare interface ExtendsMany - extends Interface1, - Interface2, - Interface3, - Interface4, - Interface5, - Interface6, - Interface7 { - x: string; -} -``` - -#### Do not add unnecessary parens for async function in `export default` ([#5303] by [@jbrown215]) - -Unnecessary parens around `export default async function` are now removed. -This error occurred only when using the `flow` parser. - - -```jsx -// Input -export default async function foo() {}; - -// Output (Prettier 1.14) -export default (async function foo() {}); - -// Output (Prettier 1.15) -export default async function foo() {} -``` - -### TypeScript - -#### Add ASI protection for non-null assertion ([#5262] by [@duailibe]) - -Necessary semicolons for non-null assertions won't be removed in `--no-semi` mode. - - -```ts -// Input -const el = ReactDOM.findDOMNode(ref) -;(el as HTMLElement)!.style.cursor = 'pointer' - -// Output (Prettier 1.14) -const el = ReactDOM.findDOMNode(ref) -(el as HTMLElement)!.style.cursor = "pointer" - -// Output (Prettier 1.15) -const el = ReactDOM.findDOMNode(ref) -;(el as HTMLElement)!.style.cursor = "pointer" -``` - -#### Do not add extra semicolon for method signature when `prettier-ignore` is used ([#5160] by [@onurtemizkan]) - -Extra semicolon for method signature is removed in Prettier 1.15. - - -```ts -// Input -interface SharedWorkerGlobalScope extends WorkerGlobalScope { - // prettier-ignore - addEventListener(): void; - addEventListener(type: string): void; -} - -// Output (Prettier 1.14) -interface SharedWorkerGlobalScope extends WorkerGlobalScope { - // prettier-ignore - addEventListener(): void;; - addEventListener(type: string): void; -} - -// Output (Prettier 1.15) -interface SharedWorkerGlobalScope extends WorkerGlobalScope { - // prettier-ignore - addEventListener(): void; - addEventListener(type: string): void; -} -``` - -#### Do not print invalid parens for destructuring with default value ([#5096] by [@ikatyang]) - -Previously, Prettier printed invalid parens for destructuring with default value, we fixed this issue in Prettier 1.15. - - -```ts -// Input -({ prop: toAssign = "default" } = { prop: "propval" }); - -// Output (Prettier 1.14) -({ prop: (toAssign = "default") } = { prop: "propval" }); - -// Output (Prettier 1.15) -({ prop: toAssign = "default" } = { prop: "propval" }); -``` - -#### Do not print semicolon for class properties with modifiers in `--no-semi` mode ([#5083] by [@ikatyang]) - -In Prettier 1.14, semicolons are added to the end of a class property -when there are modifiers in its next property, however these semicolons are not needed. -Unnecessary semicolons are removed in Prettier 1.15. - - -```ts -// Input -class Reader { - private [kBuffer]: Buffer - private [kOffset]: number -} - -// Output (1.14) -class Reader { - private [kBuffer]: Buffer; - private [kOffset]: number -} - -// Output (1.15) -class Reader { - private [kBuffer]: Buffer - private [kOffset]: number -} -``` - -#### Do not remove parens for complex nodes in ClassExpression's `extends` ([#5074] by [@ikatyang]) - -Previously, parens for complex nodes in class expression's `extends` were wrongly removed, producing invalid code. -This issue has been fixed in Prettier 1.15. - - -```ts -// Input -let Subclass2 = class extends (Superclass as AssertedSuperclass) {}; - -// Output (Prettier 1.14) -let Subclass2 = class extends Superclass as AssertedSuperclass {}; - -// Output (Prettier 1.15) -let Subclass2 = class extends (Superclass as AssertedSuperclass) {}; -``` - -#### Do not remove necessary parens for TSOptionalType ([#5056] by [@ikatyang]) - -Previously, necessary parens for optional types in tuple were wrongly removed, producing invalid code. -This issue has been fixed in Prettier 1.15. - - -```ts -// Input -type T = [("a" | "b")?]; - -// Output (Prettier 1.14) -type T = ["a" | "b"?]; - -// Output (Prettier 1.15) -type T = [("a" | "b")?]; -``` - -### CSS - -#### Do not print wrong output if both front matter and `/* prettier-ignore */` exist ([#5103] by [@ikatyang]) - -In Prettier 1.14, location information in the AST were wrongly shifted -due to how we extract front matters from the source, -which led to `/* prettier-ignore */` producing invalid output. -We've fixed this issue in Prettier 1.15. - - -```css -/* Input */ ---- -hello: world ---- - -/* prettier-ignore */ -.foo {} - -/* Output (Prettier 1.14) */ ---- -hello: world ---- - -/* prettier-ignore */ - pretti - -/* Output (Prettier 1.15) */ ---- -hello: world ---- - -/* prettier-ignore */ -.foo {} -``` - -#### Keep newlines in CSS-in-JS Templates ([#5240] by [@onurtemizkan]) - -Interpolations in CSS-in-JS templates could be anything, so we keep newlines for them in Prettier 1.15. - - -```js -// Input -const foo = styled.div` - ${secondary} - flex: 0 0 auto; -`; - -// Output (Prettier 1.14) -const foo = styled.div` - ${secondary} flex: 0 0 auto; -`; - -// Output (Prettier 1.15) -const foo = styled.div` - ${secondary} - flex: 0 0 auto; -`; -``` - -### Markdown - -#### Trailing spaces for front matters' delimiters are allowed ([#5107] by [@ikatyang]) - -Previously, we only detected front matters which did not use trailing spaces for their delimiters, -which led to an issue where thematic breaks (i.e., `---`) were wrongly recognized as the end of the front matter. -We've fixed this issue by allowing trailing spaces for front matters' delimiters in Prettier 1.15, -which is also the way how GitHub processes front matters. - -(`·` represents a whitespace) - - -```md - ---- -Title: Title ----··· - -__strong__ **strong** - ---- - - ---- -Title: Title ----··· -__strong__ **strong** ---- - - ---- -Title: Title ----··· - -**strong** **strong** - ---- -``` - -#### Do not add whitespaces between Latin and Hangul ([#5040] by [@ikatyang]) - -Previously, we always inserted whitespace between Latin and CJK characters to improve readability, -but according to feedback we received, Korean uses conventional spaces, -and inserting whitespaces would cause issues for them, -so we disabled this behavior for Hangul in Prettier 1.15. Behavior is not changing for Chinese or Japanese. - - -```md - -예문Latin예문Latin 예문Latin예문 Latin예문Latin 예문 Latin 예문 - - -예문 Latin 예문 Latin 예문 Latin 예문 Latin 예문 Latin 예문 Latin 예문 - - -예문Latin예문Latin 예문Latin예문 Latin예문Latin 예문 Latin 예문 -``` - -#### Preserve leading and trailing newlines in fenced code block ([#5038] by [@ikatyang]) - -In Prettier 1.14, leading and trailing newlines are removed in fenced code block, -which causes other plugins (e.g., php) to fail to format these code blocks. -Leading and trailing newlines are preserved in Prettier 1.15. - - -````md - -``` - -hello - -``` - - -``` -hello -``` - - -``` - -hello - -``` -```` - -#### Inline footnote definition if there's only a single line paragraph ([#5025] by [@ikatyang]) - -Previously, anything that did not fit within the print width in a footnote definition was broken into multiple lines, -but breaking a single line paragraph out onto its own was not much of a readability improvement, so we always inline them in Prettier 1.15. - - -```md - -[^1]: In eos repellat fugit dolor veritatis doloremque nobis. Provident ut est illo. - - -[^1]: - - In eos repellat fugit dolor veritatis doloremque nobis. Provident ut est illo. - - -[^1]: In eos repellat fugit dolor veritatis doloremque nobis. Provident ut est illo. -``` - -#### Correctly print lists in front of whitespace-only trailing newlines ([#5024] by [@ikatyang]) - -In Prettier 1.14, lists in front of whitespace-only trailing newlines -are wrongly recognized as [loose](https://spec.commonmark.org/0.28/#loose) lists. -This caused an issue where the user would need to format their code twice to get it stable, but when the code stabilized, it would produce the wrong output. -This issue has been fixed in Prettier 1.15. - - -```js -// Input -if (condition) { - md` -- 123 - - 456 -`; -} - -// First Output (Prettier 1.14) -if (condition) { - md` -- 123 - - 456 - `; -} - -// Second Output (Prettier 1.14) -if (condition) { - md` -- 123 - - - 456 - `; -} - -// First & Second Output (Prettier 1.15) -if (true) { - md` -- 123 - - 456 - `; -} -``` - -### YAML - -#### Escape quotes correctly ([#5236] by [@ikatyang]) - -Previously, string with escaped quotes in doubleQuote would cause invalid output. -They're now correctly escaped in Prettier 1.15. - - -```yaml -# Input -"'a\"b" - -# Output (Prettier 1.14) -''a"b' - -# Output (Prettier 1.15) -'''a"b' -``` - -#### Preserve trailing comments for document and document head ([#5027] by [@ikatyang]) - -In Prettier 1.14, there were some situations where trailing comments for document and document head may be moved. -In Prettier 1.15, they're now always preserved. - - -```yml -# Input ---- # hello -... # world - -# Output (Prettier 1.14) -# hello -# world - -# Output (Prettier 1.15) ---- # hello -... # world -``` - -#### Do not throw error for flow mapping item with long value ([#5027] by [@ikatyang]) - -Previously, long flow mapping values were wrongly recognized as keys, -which produced syntax errors since implicit keys with more than [1024 characters] are not allowed. -This issue has been fixed in Prettier 1.15. - -(`long` represents a long text that is more than 1024 characters) - -[1024 characters]: http://yaml.org/spec/1.2/spec.html#id2792501 - - -```yml -# Input -{x: long} - -# Output (Prettier 1.14) -SyntaxError: The "undefine...ndefined" key is too long - -# Output (Prettier 1.15) -{ - x: long -} -``` - -#### Prefer implicit key for empty mapping value ([#4972] by [@ikatyang]) - -Previously, a mapping item with an empty value was always printed with an [explicit key], -which is not that common and this confused people. -In Prettier 1.15, we always print it with an implicit key in that situations. - -[explicit key]: http://yaml.org/spec/1.2/spec.html#id2798425 - - -```yaml -# Input -a: - b: - -# Output (Prettier 1.14) -a: - ? b - -# Output (Prettier 1.15) -a: - b: -``` - -## Thanks! ❤️ - -Thanks to everyone who contributed to this release, -as well as those who raised issues and gave us feedback. -Prettier is a community-driven project -and is only able to continue to exist thanks to people like you. Thank you! - -Special thanks to [@j-f1], [@suchipi] and [@existentialism] for reviewing this blog post! - -[@aquibm]: https://github.com/aquibm -[@azz]: https://github.com/azz -[@bakkot]: https://github.com/bakkot -[@duailibe]: https://github.com/duailibe -[@ericsakmar]: https://github.com/ericsakmar -[@evilebottnawi]: https://github.com/evilebottnawi -[@existentialism]: https://github.com/existentialism -[@flxwu]: https://github.com/flxwu -[@haggholm]: https://github.com/haggholm -[@ikatyang]: https://github.com/ikatyang -[@j-f1]: https://github.com/j-f1 -[@jaideng123]: https://github.com/jaideng123 -[@jbrown215]: https://github.com/jbrown215 -[@kachkaev]: https://github.com/kachkaev -[@koba04]: https://github.com/koba04 -[@lydell]: https://github.com/lydell -[@malcolmsgroves]: https://github.com/malcolmsgroves -[@onurtemizkan]: https://github.com/onurtemizkan -[@onurtemizkan]: https://github.com/onurtemizkan -[@smirea]: https://github.com/smirea -[@suchipi]: https://github.com/suchipi -[@swac]: https://github.com/swac -[@titansnow]: https://github.com/TitanSnow -[@vjeux]: https://github.com/vjeux -[@warrenseine]: https://github.com/warrenseine -[@yuliahope]: https://github.com/yuliaHope -[#2083]: https://github.com/prettier/prettier/pull/2083 -[#4368]: https://github.com/prettier/prettier/pull/4368 -[#4753]: https://github.com/prettier/prettier/pull/4753 -[#4772]: https://github.com/prettier/prettier/pull/4772 -[#4798]: https://github.com/prettier/prettier/pull/4798 -[#4924]: https://github.com/prettier/prettier/pull/4924 -[#4964]: https://github.com/prettier/prettier/pull/4964 -[#4969]: https://github.com/prettier/prettier/pull/4969 -[#4970]: https://github.com/prettier/prettier/pull/4970 -[#4972]: https://github.com/prettier/prettier/pull/4972 -[#4975]: https://github.com/prettier/prettier/pull/4975 -[#5006]: https://github.com/prettier/prettier/pull/5006 -[#5011]: https://github.com/prettier/prettier/pull/5011 -[#5015]: https://github.com/prettier/prettier/pull/5015 -[#5016]: https://github.com/prettier/prettier/pull/5016 -[#5017]: https://github.com/prettier/prettier/pull/5017 -[#5020]: https://github.com/prettier/prettier/pull/5020 -[#5024]: https://github.com/prettier/prettier/pull/5024 -[#5025]: https://github.com/prettier/prettier/pull/5025 -[#5027]: https://github.com/prettier/prettier/pull/5027 -[#5038]: https://github.com/prettier/prettier/pull/5038 -[#5039]: https://github.com/prettier/prettier/pull/5039 -[#5040]: https://github.com/prettier/prettier/pull/5040 -[#5041]: https://github.com/prettier/prettier/pull/5041 -[#5050]: https://github.com/prettier/prettier/pull/5050 -[#5056]: https://github.com/prettier/prettier/pull/5056 -[#5057]: https://github.com/prettier/prettier/pull/5057 -[#5063]: https://github.com/prettier/prettier/pull/5063 -[#5066]: https://github.com/prettier/prettier/pull/5066 -[#5074]: https://github.com/prettier/prettier/pull/5074 -[#5078]: https://github.com/prettier/prettier/pull/5078 -[#5083]: https://github.com/prettier/prettier/pull/5083 -[#5085]: https://github.com/prettier/prettier/pull/5085 -[#5092]: https://github.com/prettier/prettier/pull/5092 -[#5096]: https://github.com/prettier/prettier/pull/5096 -[#5103]: https://github.com/prettier/prettier/pull/5103 -[#5107]: https://github.com/prettier/prettier/pull/5107 -[#5137]: https://github.com/prettier/prettier/pull/5137 -[#5149]: https://github.com/prettier/prettier/pull/5149 -[#5151]: https://github.com/prettier/prettier/pull/5151 -[#5157]: https://github.com/prettier/prettier/pull/5157 -[#5160]: https://github.com/prettier/prettier/pull/5160 -[#5165]: https://github.com/prettier/prettier/pull/5165 -[#5179]: https://github.com/prettier/prettier/pull/5179 -[#5188]: https://github.com/prettier/prettier/pull/5188 -[#5190]: https://github.com/prettier/prettier/pull/5190 -[#5202]: https://github.com/prettier/prettier/pull/5202 -[#5205]: https://github.com/prettier/prettier/pull/5205 -[#5206]: https://github.com/prettier/prettier/pull/5206 -[#5207]: https://github.com/prettier/prettier/pull/5207 -[#5209]: https://github.com/prettier/prettier/pull/5209 -[#5220]: https://github.com/prettier/prettier/pull/5220 -[#5236]: https://github.com/prettier/prettier/pull/5236 -[#5240]: https://github.com/prettier/prettier/pull/5240 -[#5243]: https://github.com/prettier/prettier/pull/5243 -[#5244]: https://github.com/prettier/prettier/pull/5244 -[#5250]: https://github.com/prettier/prettier/pull/5250 -[#5251]: https://github.com/prettier/prettier/pull/5251 -[#5252]: https://github.com/prettier/prettier/pull/5252 -[#5259]: https://github.com/prettier/prettier/pull/5259 -[#5262]: https://github.com/prettier/prettier/pull/5262 -[#5272]: https://github.com/prettier/prettier/pull/5272 -[#5280]: https://github.com/prettier/prettier/pull/5280 -[#5290]: https://github.com/prettier/prettier/pull/5290 -[#5303]: https://github.com/prettier/prettier/pull/5303 -[#5304]: https://github.com/prettier/prettier/pull/5304 -[#5327]: https://github.com/prettier/prettier/pull/5327 -[#5330]: https://github.com/prettier/prettier/pull/5330 -[#5333]: https://github.com/prettier/prettier/pull/5333 -[#5334]: https://github.com/prettier/prettier/pull/5334 -[#5356]: https://github.com/prettier/prettier/pull/5356 diff --git a/website/blog/2019-01-20-1.16.0.md b/website/blog/2019-01-20-1.16.0.md deleted file mode 100644 index 1465ab0c3d..0000000000 --- a/website/blog/2019-01-20-1.16.0.md +++ /dev/null @@ -1,608 +0,0 @@ ---- -author: Ika (@ikatyang) -authorURL: https://github.com/ikatyang -title: "Prettier 1.16: HTML improvements and better CRLF handling" ---- - -This release improves HTML formatting and contains better CRLF handling, new -syntax features, and fixes several bugs. - - - -## Highlights - -### HTML - -#### Respect surrounding linebreaks ([#5596] by [@ikatyang]) - -Previously, Prettier always put elements in a single line if they didn’t -go past the `printWidth`, but this doesn’t work for elements that are used as -`if`-`else` blocks or are intended to contain several items. To solve this -problem, we’ll respect surrounding linebreaks for all elements since there is -no reliable way to determine if they’re being used in these ways. - - -```html - -
-
Jan
-
- - {{ i }} - - - - - - -
Jan
- {{ i }} - - - -
-
Jan
-
-
- {{ i }} - - - - -``` - -### General - -#### Better CRLF handling ([#5494] by [@ikatyang]) - -You might have noticed a few weird formatting issues that only occurred on Windows. -Many of these issues were caused by our handling of CR-LF line endings. -In this release, we were able to resolve these issues by normalizing linebreaks -both before and after formatting. - -### JavaScript - -#### Improve the pattern used by React hooks ([#5608] by [@j-f1]) - - -```js -// Input -function helloWorld() { - useEffect(() => { - // do something - }, [props.value]) -} - -// Output (Prettier 1.15) -function helloWorld() { - useEffect( - () => { - // do something - }, - [props.value] - ); -} - -// Output (Prettier 1.16) -function helloWorld() { - useEffect(() => { - // do something - }, [props.value]); -} -``` - -#### Rename `babylon` parser to `babel` ([#5647] by [@wuweiweiwu]) - -Babel’s parser, `babylon`, was renamed to `@babel/parser` in Babel 7. We’ve -renamed our `babylon` parser to `babel` as well to reduce confusion. - -The `babylon` parser name is now deprecated but it still works. - -If you need to change your config due to this change, please take a second to read -[our docs on the `parser` option], especially the note at the bottom. - -[our docs on the `parser` option]: https://prettier.io/docs/en/configuration.html#setting-the-parser-docs-en-optionshtml-parser-option - -### Flow - -#### Add `babel-flow` parser ([#5685] by [@ikatyang]) - -Both the `babel` and `flow` parsers support Flow syntax by default, but there are a few -edge cases where Flow syntax is ambiguous. By default, Babel’s Flow parser will parse the -ambiguous code as regular JS, while the native Flow parser will parse it as Flow syntax. -To address this issue, we added the `babel-flow` parser option, which uses Babel’s parser, -but prefers Flow syntax when ambiguities arise. - - -```js -// Input -const Theme = React.createContext<"light" | "dark">("light"); - -// Output (Prettier 1.15, --parser babylon) -const Theme = (React.createContext < "light") | ("dark" > "light"); - -// Output (Prettier 1.16, --parser babel-flow) -const Theme = React.createContext<"light" | "dark">("light"); -``` - -### CLI - -#### Add a `--check` flag ([#5629] by [@kachkaev]) - -Passing `--list-different` to the `prettier` CLI command will cause Prettier to -exit with an error code if one or more of the files passed to it has not been -formatted with Prettier. This works great, but it doesn’t provide any information -in the output except for the files which aren’t properly formatted. This isn’t -very friendly for new contributors and users in general, so we added a `--check` -option that produces more human-friendly output. - - -# Prettier 1.15
-$ prettier \*.js --list-different
-unformatted.js
-
-# Prettier 1.16
-$ prettier \*.js --check
-Checking formatting...
-unformatted.js
-Code style issues found in the above file(s). Forgot to run Prettier?
-
- -## Other changes - -### General - -#### Fix unexpected formatting caused by range format ([#5632] by [@lhchavez]) - - -```js -// Input -something("something", () => { - const something = { - something: [ - { - long1: "longlonglonglonglonglonglonglonglonglonglonglong", - long2: "longlonglonglonglonglonglonglonglonglonglonglong", - } - ] - }; -}); - -// Output (Prettier 1.15, --range-start 100 --range-end 120) -something("something", () => { - const something = { something: [{ long1: "longlonglonglonglonglonglonglonglonglonglonglong", long2: "longlonglonglonglonglonglonglonglonglonglonglong" }] }; -}); - -// Output (Prettier 1.16, --range-start 100 --range-end 120) -something("something", () => { - const something = { - something: [ - { - long1: "longlonglonglonglonglonglonglonglonglonglonglong", - long2: "longlonglonglonglonglonglonglonglonglonglonglong", - } - ] - }; -}); -``` - -### API - -#### Allow plugin instances to be passed in the `plugins` field of format options ([#5763] by [@Kingwl]) - -Previously, plugin instances were somehow disallowed to be passed in the -`plugins` field of format options but it should be allowed. We've fixed this -issue in Prettier 1.16. - -```js -const prettier = require("prettier"); -const fooPlugin = require("./path/to/foo-plugin"); -const formatted = prettier.format("foo-code", { - plugins: [fooPlugin], - parser: "foo-parser", -}); -// Prettier 1.15: Error -// Prettier 1.16: No error -``` - -### Standalone - -#### Remove the dynamic `require()` call in the standalone bundle ([#5612] by [@j-f1]) - -Previously, a dynamic `require()` call was present in the `standalone.js` file designed -for usage in browsers. It was used in a way where it wasn’t actually called, but -tools like webpack to throw a warning. We adjusted the build script to remove -this `require()` call in the standalone bundle in Prettier 1.16. - -### TypeScript - -#### Correctly handle `//` in TSX ([#5728] by [@JamesHenry]) - -Previously, putting `//` as a child of a JSX element in TypeScript led to an error -because it was interpreted as a comment. Prettier 1.16 fixes this issue. - - -```js -// Input -const link = http://example.com - -// Output (Prettier 1.15) -// Error: Comment location overlaps with node location - -// Output (Prettier 1.16) -const link = http://example.com; -``` - -#### Remove redundant parentheses around type annotations ([#5724] by [@flurmbo]) - - -```js -// Input -class Foo { - bar: (() => boolean); -} - -// Output (Prettier 1.15) -class Foo { - bar: (() => boolean); -} - -// Output (Prettier 1.16) -class Foo { - bar: () => boolean; -} -``` - -### JavaScript - -#### Do not treat `something.connect()` as functional composition ([#5739] by [@makepost]) - -A special format for `connect()` calls was introduced to improve formatting of Redux -several versions ago, but there are many other uses for functions named `connect` that -shouldn’t be formatted that way. Since most of these cases involved a `connect` method, -we no longer treat `foo.connect()` calls as functional composition. - - -```js -// Input -app.connect("activate", async () => { - await data.load(); - win.show_all(); -}); -const ConnectedComponent = connect( - bar, - baz -)(foo); - -// Output (Prettier 1.15) -app.connect( - "activate", - async () => { - await data.load(); - win.show_all(); - } -); -const ConnectedComponent = connect( - bar, - baz -)(foo); - -// Output (Prettier 1.16) -app.connect("activate", async () => { - await data.load(); - win.show_all(); -}); -const ConnectedComponent = connect( - bar, - baz -)(foo); -``` - -#### Add support for class private methods ([#5637] by [@existentialism]) - -```js -// Input -class Hello { - #world() {} -} - -// Output (Prettier 1.15) -// SyntaxError - -// Output (Prettier 1.16) -class Hello { - #world() {} -} -``` - -#### Correct indentation for expressions in root template ([#5607] by [@ikatyang]) - - -```js -// Input -if (a) { - return ` -hello -${foo({ - bar, - baz -})} -world -`; -} - -// Output (Prettier 1.15) -if (a) { - return ` -hello -${foo({ - bar, - baz - })} -world -`; -} - -// Output (Prettier 1.16) -if (a) { - return ` -hello -${foo({ - bar, - baz -})} -world -`; -} -``` - -#### Remove unnecessary linebreaks from HTML template literals ([#5771] by [@ikatyang]) - - -```js -// Input -function HelloWorld() { - return html` -

Bar List

- ${bars.map(bar => html` -

${bar}

- `)} - `; -} - -// Output (Prettier 1.15) -function HelloWorld() { - return html` -

Bar List

- ${ - bars.map( - bar => html` -

${bar}

- ` - ) - } - `; -} - -// Output (Prettier 1.16) -function HelloWorld() { - return html` -

Bar List

- ${bars.map( - bar => html` -

${bar}

- ` - )} - `; -} -``` - -### TypeScript/Flow - -#### Correctly recognize `/* HTML */` templates ([#5658] by [@ikatyang]) - -We [added support] for HTML template literal formatting using the `/* HTML */` pseudo-tag -in Prettier 1.15, but due to a bug, it only worked for JavaScript code. We’ve fixed this -issue in Prettier 1.16. - -[added support]: https://prettier.io/blog/2018/11/07/1.15.0.html#html-template-literal-in-javascript - -### CSS - -#### Fix broken output for lists caused by comments ([#5710] by [@jsnajdr]) - - -```scss -// Input -$my-list2: - a // a - b - c; - -// Output (Prettier 1.15) -$my-list2: a// a - bc; - -// Output (Prettier 1.16) -$my-list2: a // a - b c; -``` - -#### Correctly handle backslashes ([#5597] by [@sh7dm]) - - -```less -// Input -.figcaption { - .margin-top-1\/2; - .large\:none; -} - -// Output (Prettier 1.15) -.figcaption { - .margin-top-1\ / 2; - .large\: none; -} - -// Output (Prettier 1.16) -.figcaption { - .margin-top-1\/2; - .large\: none; -} -``` - -### MDX - -#### Correctly handle inline html ([#5704] by [@ikatyang]) - - -```md - -| Column 1 | Column 2 | -|---|---| -| Text | Text | - - - - - -| Column 1 | Column 2 | -| -------- | ------------------- | -| Text | Text | -``` - -### HTML - -#### Format script with type "application/ld+json" ([#5642] by [@ikatyang]) - - -```html - - - - - - - - -``` - -#### Treat `.mjml` files as HTML ([#5505] by [@n1ru4l]) - -MJML is a markup language that uses the same syntax as HTML. We added the `.mjml` -file extension to the list of extensions that are recognized as HTML, so Prettier -will format it. - -#### Smart quote for attributes ([#5590] by [@ikatyang]) - -Previously, the quotes around HTML attribute values were always printed as double -quotes. To improve readability, they are now printed as the quote type that results -in fewer escape characters being required in the string, like we do for other strings. - - -```html - -
-
- - -
-
- - -
-
-``` - -### Vue - -#### Tag names are case-sensitive ([#5606] by [@ikatyang]) - -Previously, we lowercased tag names before querying tag definition while -parsing, which caused `` component to be recognized as a native ``. -This would produce a syntax error when `` was encountered since `` -is a void element, and void elements can’t have closing elements. -We’ve fixed this issue in 1.16. - - -```vue - - - - - - - - -``` - -### Vue/Angular - -#### Add parentheses to avoid unexpected `}}` in interpolations ([#5657] by [@ikatyang]) - -`}}` is not allowed to be used in a interpolation since it’ll be recognized as the -end of the interpolation. Prettier 1.15 would sometimes output code that broke this -rule. Prettier 1.16 now adds parentheses to prevent `}}` from appearing in interpolations. - - -```html - -

{{ foo({ bar: {} }) }}

- - -

{{ foo({bar: {}}) }}

- - - - - -

{{ foo({bar: ({})}) }}

-``` - -[@existentialism]: https://github.com/existentialism -[@flurmbo]: https://github.com/flurmbo -[@ikatyang]: https://github.com/ikatyang -[@j-f1]: https://github.com/j-f1 -[@jameshenry]: https://github.com/JamesHenry -[@jsnajdr]: https://github.com/jsnajdr -[@kachkaev]: https://github.com/kachkaev -[@kingwl]: https://github.com/Kingwl -[@lhchavez]: https://github.com/lhchavez -[@makepost]: https://github.com/makepost -[@n1ru4l]: https://github.com/n1ru4l -[@sh7dm]: https://github.com/sh7dm -[@wuweiweiwu]: https://github.com/wuweiweiwu -[#5494]: https://github.com/prettier/prettier/pull/5494 -[#5505]: https://github.com/prettier/prettier/pull/5505 -[#5590]: https://github.com/prettier/prettier/pull/5590 -[#5596]: https://github.com/prettier/prettier/pull/5596 -[#5597]: https://github.com/prettier/prettier/pull/5597 -[#5606]: https://github.com/prettier/prettier/pull/5606 -[#5607]: https://github.com/prettier/prettier/pull/5607 -[#5608]: https://github.com/prettier/prettier/pull/5608 -[#5612]: https://github.com/prettier/prettier/pull/5612 -[#5629]: https://github.com/prettier/prettier/pull/5629 -[#5632]: https://github.com/prettier/prettier/pull/5632 -[#5637]: https://github.com/prettier/prettier/pull/5637 -[#5642]: https://github.com/prettier/prettier/pull/5642 -[#5647]: https://github.com/prettier/prettier/pull/5647 -[#5657]: https://github.com/prettier/prettier/pull/5657 -[#5658]: https://github.com/prettier/prettier/pull/5658 -[#5685]: https://github.com/prettier/prettier/pull/5685 -[#5704]: https://github.com/prettier/prettier/pull/5704 -[#5710]: https://github.com/prettier/prettier/pull/5710 -[#5724]: https://github.com/prettier/prettier/pull/5724 -[#5728]: https://github.com/prettier/prettier/pull/5728 -[#5739]: https://github.com/prettier/prettier/pull/5739 -[#5763]: https://github.com/prettier/prettier/pull/5763 -[#5771]: https://github.com/prettier/prettier/pull/5771 diff --git a/website/blog/2019-04-12-1.17.0.md b/website/blog/2019-04-12-1.17.0.md deleted file mode 100644 index f674cb1904..0000000000 --- a/website/blog/2019-04-12-1.17.0.md +++ /dev/null @@ -1,361 +0,0 @@ ---- -author: Lucas Duailibe (@duailibe) -authorURL: https://github.com/duailibe -title: "Prettier 1.17: More quotes options and support for shared configs" ---- - -This release brings long-requested flexibility to quotes around object properties, allows Prettier configuration to be shared in the form of packages, adds a [LWC] parser, adds support for new GraphQL syntax and fixes lots of formatting bugs. - -[lwc]: https://developer.salesforce.com/docs/component-library/documentation/lwc - - - -## Highlights - -### JavaScript - -#### Add an option to modify when Prettier quotes object properties ([#5934] by [@azz]) - -**`--quote-props `** - -`as-needed` **(default)** - Only add quotes around object properties where required. Current behaviour. -`preserve` - Respect the input. This is useful for users of Google's Closure Compiler in Advanced Mode, which treats quoted properties differently. -`consistent` - If _at least one_ property in an object requires quotes, quote all properties - this is like ESLint's [`consistent-as-needed`](https://eslint.org/docs/rules/quote-props) option. - - -```js -// Input -const headers = { - accept: "application/json", - "content-type": "application/json", - "origin": "prettier.io" -}; - -// Output (Prettier 1.16 or --quote-props=as-needed) -const headers = { - accept: "application/json", - "content-type": "application/json", - origin: "prettier.io" -}; - -// Output (--quote-props=consistent) -const headers = { - "accept": "application/json", - "content-type": "application/json", - "origin": "prettier.io" -}; - -// Output (--quote-props=preserve) -const headers = { - accept: "application/json", - "content-type": "application/json", - "origin": "prettier.io" -}; -``` - -### Config - -#### Support shared configurations ([#5963] by [@azz]) - -Sharing a Prettier configuration is simple: just publish a module that exports a configuration object, say `@company/prettier-config`, and reference it in your `package.json`: - -```json -{ - "name": "my-cool-library", - "version": "9000.0.1", - "prettier": "@company/prettier-config" -} -``` - -If you don't want to use `package.json`, you can use any of the supported extensions to export a string, e.g. `.prettierrc.json`: - -```json -"@company/prettier-config" -``` - -[@azz] has created an example configuration package. You can [see the source on GitHub](https://github.com/azz/prettier-config) or [install it via npm](https://www.npmjs.com/package/@azz/prettier-config). - -> Note: This method does **not** offer a way to _extend_ the configuration to overwrite some properties from the shared configuration. If you need to do that, import the file in a `.prettierrc.js` file and export the modifications, e.g: -> -> ```js -> module.exports = { -> ...require("@company/prettier-config"), -> semi: false, -> }; -> ``` - -## General - -### JavaScript - -#### Respect newlines between parameters ([#5836] by [@evilebottnawi]) - - -```js -// Input -function foo( - one, - - two, - three, - four, - - - five, - six, - seven, - eight, - nine, - ten, - - eleven - -) {} - -// Output (Prettier 1.16) -function foo( - one, - two, - three, - four, - five, - six, - seven, - eight, - nine, - ten, - eleven -) {} - -// Output (Prettier 1.17) -function foo( - one, - - two, - three, - four, - - five, - six, - seven, - eight, - nine, - ten, - - eleven -) {} -``` - -#### Fix multiline dynamic import comments ([#6025] by [@noahsug]) - - -```js -// Input -import( - /* Hello */ - 'something' - /* Hello */ -) -import( - 'myreallylongdynamicallyloadedmodulenamemyreallylongdynamicallyloadedmodulename' -) - -// Output (Prettier stable) -import(/* Hello */ -"something"); -/* Hello */ -import('myreallylongdynamicallyloadedmodulenamemyreallylongdynamicallyloadedmodulename'); - -// Output (Prettier master) -import( - /* Hello */ - 'something' - /* Hello */ -) -import( - 'myreallylongdynamicallyloadedmodulenamemyreallylongdynamicallyloadedmodulename' -); -``` - -#### Add parentheses for immediately-constructed functions and class ([#5996] by [@bakkot]) - - -```js -// Input -new class {}; -new function() {} - -// Output (Prettier stable) -new class {}(); -new function() {}(); - -// Output (Prettier master) -new (class {})(); -new (function() {})(); -``` - -#### Fix parens logic for optional chaining expressions and closure type casts ([#5843] by [@yangsu]) - -Logic introduced in #4542 will print parens in the wrong places and produce invalid code for optional chaining expressions (with more than 2 nodes) or closure type casts that end in function calls. - - -```js -// Input -(a?.b[c]).c(); -let value = /** @type {string} */ (this.members[0]).functionCall(); - -// Output (Prettier stable) -a(?.b[c]).c(); -let value = /** @type {string} */ this(.members[0]).functionCall(); - -// Output (Prettier master) -(a?.b[c]).c(); -let value = /** @type {string} */ (this.members[0]).functionCall(); -``` - -### Markdown - -#### Do not align table contents if it exceeds the print width and `--prose-wrap never` is set ([#5701] by [@chenshuai2144]) - -The aligned table is less readable than the compact one if it's particularly long and the word wrapping is not enabled in the editor so we now print them as compact tables in these situations. - - -```md - -| Property | Description | Type | Default | -| -------- | ----------- | ---- | ------- | -| bordered | Toggles rendering of the border around the list | boolean | false | -| itemLayout | The layout of list, default is `horizontal`, If a vertical list is desired, set the itemLayout property to `vertical` | string | - | - - -| Property | Description | Type | Default | -| ---------- | --------------------------------------------------------------------------------------------------------------------- | ------- | ------- | -| bordered | Toggles rendering of the border around the list | boolean | false | -| itemLayout | The layout of list, default is `horizontal`, If a vertical list is desired, set the itemLayout property to `vertical` | string | - | - - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| bordered | Toggles rendering of the border around the list | boolean | false | -| itemLayout | The layout of list, default is `horizontal`, If a vertical list is desired, set the itemLayout property to `vertical` | string | - | -``` - -### TypeScript - -#### Support `readonly` operator ([#6027] by [@ikatyang]) - - -```ts -// Input -declare const array: readonly number[]; - -// Output (Prettier stable) -// SyntaxError: ',' expected. - -// Output (Prettier master) -declare const array: readonly number[]; -``` - -### HTML - -#### Add support for Lightning Web Components ([#5800] by [@ntotten]) - -Supports [Lightning Web Components (LWC)][lwc] template format for HTML attributes by adding a new parser called `lwc`. - - -```html -// Input - - -// Output (Prettier stable) - - -// Output (Prettier master) - -``` - -#### Angular: Don't add unnecessary parentheses to pipes ([#5929] by [@voithos]) - -In some cases, wrapping parentheses were being added to certain pipes inside attributes, but they are no longer added when they don't affect the result of the expression. - - -```html -// Input -
- -// Output (Prettier stable) -
- -// Output (Prettier master) -
-``` - -### GraphQL - -#### Support variable directives ([#6020] by [@adek05]) - -Prettier now supports formatting variable directives. - - -``` -// Input -query Q($variable: Int @directive) {node} - -// Output (Prettier stable) -query Q($variable: Int) { - node -} - -// Output (Prettier master) -query Q($variable: Int @directive) { - node -} -``` - -#### Support GraphQL fragment variables ([#6016] by [@adek05]) - -Prettier now supports formatting fragment variables. - -``` -// Input -fragment F($var: Int) on Type { node } - -// Output (Prettier stable) -// Fails to parse - -// Output (Prettier master) -fragment F($var: Int) on Type { - node -} -``` - -### CLI - -#### Automatically discover scoped plugins ([#5945] by [@Kocal]) - -Prettier now supports automatically loading scoped plugins named `@scope-name/prettier-plugin-*`. - -[@adek05]: https://github.com/adek05 -[@azz]: https://github.com/azz -[@bakkot]: https://github.com/bakkot -[@chenshuai2144]: https://github.com/chenshuai2144 -[@evilebottnawi]: https://github.com/evilebottnawi -[@ikatyang]: https://github.com/ikatyang -[@kocal]: https://github.com/Kocal -[@noahsug]: https://github.com/noahsug -[@ntotten]: https://github.com/ntotten -[@voithos]: https://github.com/voithos -[@yangsu]: https://github.com/yangsu -[#5836]: https://github.com/prettier/prettier/pull/5836 -[#5701]: https://github.com/prettier/prettier/pull/5701 -[#5800]: https://github.com/prettier/prettier/pull/5800 -[#5843]: https://github.com/prettier/prettier/pull/5843 -[#5929]: https://github.com/prettier/prettier/pull/5929 -[#5934]: https://github.com/prettier/prettier/pull/5934 -[#5945]: https://github.com/prettier/prettier/pull/5945 -[#5963]: https://github.com/prettier/prettier/pull/5963 -[#5996]: https://github.com/prettier/prettier/pull/5996 -[#6016]: https://github.com/prettier/prettier/pull/6016 -[#6020]: https://github.com/prettier/prettier/pull/6020 -[#6025]: https://github.com/prettier/prettier/pull/6025 -[#6027]: https://github.com/prettier/prettier/pull/6027 diff --git a/website/blog/2019-06-06-1.18.0.md b/website/blog/2019-06-06-1.18.0.md deleted file mode 100644 index 1a782cfba5..0000000000 --- a/website/blog/2019-06-06-1.18.0.md +++ /dev/null @@ -1,541 +0,0 @@ ---- -author: Lucas Duailibe (@duailibe) -authorURL: https://github.com/duailibe -title: "Prettier 1.18: Lots of fixes and OpenCollective" ---- - -This release doesn't include shiny new features, but has lots of fixes for JavaScript, specially JSX and template literals, TypeScript and Markdown. - -It's also a good opportunity to remind that Prettier is now accepting donations! If you enjoy Prettier and would like to support our work, head to our [OpenCollective](https://opencollective.com/prettier). - - - -## Highlights - -### JavaScript - -#### Stop breaking simple template literals ([#5979] by [@jwbay]) - -This is one of the Prettier parts that get a lot of change requests: breaking simple expressions inside template literals. Previously Prettier would break the expressions in multiple lines if the whole literal exceeded the print width. Now, we'll prevent breaking if the expression is simple. - -This is an improvement to what we had before, but there's still work to be done in this area. - - -```js -// Input -console.log(chalk.white(`Covered Lines below threshold: ${coverageSettings.lines}%. Actual: ${coverageSummary.total.lines.pct}%`)) - -// Output (Prettier stable) -console.log( - chalk.white( - `Covered Lines below threshold: ${coverageSettings.lines}%. Actual: ${ - coverageSummary.total.lines.pct - }%` - ) -); - -// Output (Prettier master) -console.log( - chalk.white( - `Covered Lines below threshold: ${coverageSettings.lines}%. Actual: ${coverageSummary.total.lines.pct}%` - ) -); -``` - -#### Stop converting empty JSX elements to self-closing elements ([#6127] by [@duailibe]) - -Prettier has always converted empty JSX elements (`
`) to self-closing elements (`
`) because those are equivalent. - -We have received feedback that during development, one would like to type the opening and closing tags and leave them to add the children later, but Prettier would convert it to a self-closing element, forcing the developer to manually convert them back. This has changed in this release. - - -```js -// Input -function Foo() { - return
; -} - -// Output (Prettier stable) -function Foo() { - return
; -} - -// Output (Prettier master) -function Foo() { - return
; -} -``` - -## Other changes - -### JavaScript - -#### Fix closure compiler typecasts ([#5947] by [@jridgewell]) - -If a closing parenthesis follows after a typecast in an inner expression, the typecast would wrap everything to that following parenthesis. - - -```js -// Input -test(/** @type {!Array} */(arrOrString).length); -test(/** @type {!Array} */((arrOrString)).length + 1); -// Output (Prettier stable) -test(/** @type {!Array} */ (arrOrString.length)); -test(/** @type {!Array} */ (arrOrString.length + 1)); -// Output (Prettier master) -test(/** @type {!Array} */ (arrOrString).length); -test(/** @type {!Array} */ (arrOrString).length + 1); -``` - -#### Fix closure typecasts without spaces ([#6116] by [@jridgewell]) - -Previously, a space was required between the `@type` and opening `{` of a closure typecast, or else the enclosing parenthesis would be removed. Closure itself does not require a space. - - -```tsx -// Input -const v = /** @type{string} */(value); - -// Output (Prettier stable) -const v = /** @type{string} */ value; - -// Output (prettier master) -const v = /** @type{string} */ (value); -``` - -#### Prevent adding quotes when using `--quote-props=consistent` and objects had numbers or computed expressions as keys ([#6119] and [#6138] by [@duailibe]) - -Previously, Prettier added unnecessary quotes to keys of an object, or properties and methods of classes, if there was at least one computed key with a "complex" expression (e.g. a member expression) or a numeric literal. - - -```js -// Input -const obj = { - foo: "", - [foo.bar]: "", -}; - -const other = { - foo: "", - 1: "" -}; - -// Output (Prettier stable) -const obj = { - "foo": "", - [foo.bar]: "", -}; - -const other = { - "foo": "", - 1: "" -}; - -// Output (Prettier master) -const obj = { - foo: "", - [foo.bar]: "", -}; - -const other = { - foo: "", - 1: "" -}; -``` - -#### Add parenthesis in JSX spread element with logical expressions ([#6130] by [@duailibe]) - -Previously, Prettier didn't add parenthesis in JSX spread elements because they aren't necessary, but for the sake of consistency with spread operator in objects and arrays, we'll add to JSX as well. - - -```js -// Input -; - -// Output (Prettier stable) -; - -// Output (Prettier master) -; -``` - -#### Correctly handle comments in empty arrow function expressions ([#6086] by [@evilebottnawi]) - - -```js -// Input -const fn = (/*event, data*/) => doSomething(anything); - -// Output (Prettier stable) -const fn = () => /*event, data*/ doSomething(anything); - -// Output (Prettier master) -const fn = (/*event, data*/) => doSomething(anything); -``` - -#### Do not hug sequence expression in object properties ([#6088] by [@evilebottnawi]) - - -```js -// Input -const a = { - someKey: - (longLongLongLongLongLongLongLongLongLongLongLongLongLongName, shortName) -}; - -// Output (Prettier stable) -const a = { - someKey: (longLongLongLongLongLongLongLongLongLongLongLongLongLongName, - shortName) -}; - -// Output (Prettier master) -const a = { - someKey: - (longLongLongLongLongLongLongLongLongLongLongLongLongLongName, shortName) -}; -``` - -#### Add support for styled-jsx external styles ([#6089] by [@hongrich]) - -Add support for 2 external styles tags in `styled-jsx/css`: `css.global`, and `css.resolve`. https://github.com/zeit/styled-jsx/#external-css-and-styles-outside-of-the-component - -The `css` template tag is already supported by Prettier. - - -```js -// Input -const styles = css.resolve` -.box {background:black; -}`; - -// Output (Prettier stable) -const styles = css.resolve` -.box {background:black; -}`; - -// Output (prettier master) -const styles = css.resolve` - .box { - background: black; - } -`; -``` - -#### Keep parenthesis around functions and classes in `export default` declarations ([#6133] by [@duailibe]) - -Prettier was removing parenthesis from some expressions in `export default`, but if those are complex expressions that start with `function` or `class`, the parenthesis are required. - -See below some practical examples, including one affecting TypeScript. - - -```ts -// Input -export default (function log() {}).toString(); -export default (function log() {} as typeof console.log); - -// Output (Prettier stable) -export default function log() {}.toString(); -export default function log() {} as typeof console.log; // syntax error - -// Output (Prettier master) -export default (function log() {}).toString(); -export default (function log() {} as typeof console.log); -``` - -#### Address parentheses bugs for edge cases with call and `new` ([#6148] by [@bakkot]) - -Adding all and only the necessary parentheses when mixing `new` with function calls is tricky. This change fixes two issues where necessary parentheses were omitted and one when redundant parentheses were added. - - -```ts -// Input -new (x()``.y)(); -new (x()!.y)(); -new e[f().x].y() - -// Output (Prettier stable) -new x()``.y(); -new x()!.y(); -new e[(f()).x].y(); - -// Output (Prettier master) -new (x())``.y(); -new (x())!.y(); -new e[f().x].y(); -``` - -#### Fix nested embeds (JS in HTML in JS) ([#6038] by [@thorn0]) - -Previously, if JS code embedded in HTML (via ``; - -// Output (Prettier stable) -// SyntaxError: Expecting Unicode escape sequence \uXXXX (1:8) - -// Output (Prettier master) -const html = /* HTML */ ` - -`; -``` - -#### Keep necessary parentheses around bind expressions passed to `new` expressions ([#6152] by [@sosukesuzuki]) - -Previously, Prettier removed necessary parentheses around a bind expression if it was passed to a `new` expression. - - -```js -// Input -new (a::b)(); - -// Output (Prettier stable) -new a::b(); - -// Output (Prettier master) -new (a::b)(); -``` - -#### Prevent adding unnecessary parentheses around bind expressions in member expressions' properties ([#6159] by [@duailibe]) - - -```js -// Input -f[a::b]; - -// Output (Prettier stable) -f[(a::b)]; - -// Output (Prettier master); -f[a::b]; -``` - -### TypeScript - -#### Keep trailing comma in TSX type parameters ([#6115] by [@sosukesuzuki]) - -Previously, a trailing comma after single type parameter in arrow function was cleaned up. The formatted result is valid as TS, but is invalid as TSX. This is now fixed in 1.19. - - -```tsx -// Input -type G = any; -const myFunc = (arg1: G) => false; - -// Output (Prettier stable) -type G = any; -const myFunc = (arg1: G) => false; - -// Output (prettier master) -type G = any; -const myFunc = (arg1: G) => false; -``` - -#### Don’t breakup call expressions when the last argument is an arrow function with a simple return type ([#6106] by [@brainkim]) - -Fixes [an edge case][#6099] where we were splitting up call expressions containing arrow functions with simple return types. - - -```js -app.get("/", (req, res): void => { - res.send("Hello World!"); -}); - -// Output (Prettier stable) -app.get( - "/", - (req, res): void => { - res.send("Hello World!"); - }, -); - -// Output (Prettier master) -app.get("/", (req, res): void => { - res.send("Hello World!"); -}); -``` - -#### Keep a pair of parentheses when there are extra pairs ([#6131] by [@sosukesuzuki]) - -Previously, Prettier removed necessary parentheses when trying to remove unnecessary parentheses, in TypeScript. - - -```ts -// Input -type G = ((keyof T))[]; - -// Output (Prettier stable) -type G = keyof T[]; - -// Output (prettier master) -type G = (keyof T)[]; -``` - -#### Keep necessary parentheses around non-null assertions ([#6136] by [@sosukesuzuki], [#6140] by [@thorn0], [#6148] by [@bakkot]) - -Previously, Prettier removed necessary parentheses around non-null assertions if the result of the assertion expression was called as a constructor. - - -```ts -// Input -const b = new (c()!)(); - -// Output (Prettier stable) -const b = new c()!(); - -// Output (Prettier master) -const b = new (c())!(); -``` - -#### Keep line breaks within mapped types ([#6146] by [@sosukesuzuki]) - -Previously, Prettier removed line breaks within mapped types. To make it similar to how we treat object literals, we will keep the line breaks if they existed in the source. - - -```ts -// Input -type A = { - readonly [P in keyof T]: T[P]; -}; - -// Output (Prettier stable) -type A = { readonly [P in keyof T]: T[P] }; - -// Output (Prettier master) -type A = { - readonly [P in keyof T]: T[P]; -}; -``` - -#### Add trailing comma on tuple types with `--trailing-comma=all` ([#6172] by [@sosukesuzuki]) - -TypeScript supports a trailing comma on tuple types since version 3.3. - - -```ts -// Input -export type Foo = [ - number, - number, // comment -]; - -// Output (Prettier stable) -export type Foo = [ - number, - number // comment -]; - -// Output (Prettier master); -export type Foo = [ - number, - number, // comment -]; -``` - -### Markdown - -#### Determine correctly the count of backticks in inline code ([#6110] by [@belochub]) - -By the CommonMark spec, it is required to 'choose a string of `n` backtick characters as delimiters, where the code does not contain any strings of exactly `n` backtick characters.' - -This changes the method of finding the required count of backticks from using 2 backticks, when there is a backtick string of length 1 inside the inline code block, and using 1 backtick in all other cases, to finding a minimum length backtick string that can correctly be used as a delimiter. - - -````md - -``` 3 ``22`` `1` ``` - -`` 2 ```123``` `1` `` - - -` 3 ``22`` `1` ` - -` 2 ```123``` `1` ` - - -``` 3 ``22`` `1` ``` - -`` 2 ```123``` `1` `` -```` - -### Handlebars - -While the Handlebars support is still in beta, [@GavinJoyce] is putting out some fixes so we can finally get to a stable release! - -#### Avoid adding unwanted whitespace after components ([#6178] by [@GavinJoyce]) - -Previously, Prettier added a space before `/>` and a line break after, even when at the start of a line. Now, that extra space and line break is no longer present. - - -```hbs -// Input -
- -
- -// Output (Prettier stable) -
- - -
- -// Output (Prettier master) -
- -
-``` - -### API - -#### Prettier now works in Atom again ([#6129] by [@duailibe]) - -Atom has a security feature where code containing `eval` is not allowed to be run. One of Prettier's dependencies uses `eval` to prevent bundlers from including debug code. We've now made sure that this `eval` does not end up in the code we ship to npm, making Prettier play nice with Atom again. - -[#5947]: https://github.com/prettier/prettier/pull/5947 -[#5979]: https://github.com/prettier/prettier/pull/5979 -[#6038]: https://github.com/prettier/prettier/pull/6038 -[#6086]: https://github.com/prettier/prettier/pull/6086 -[#6088]: https://github.com/prettier/prettier/pull/6088 -[#6089]: https://github.com/prettier/prettier/pull/6089 -[#6099]: https://github.com/prettier/prettier/pull/6099 -[#6106]: https://github.com/prettier/prettier/pull/6106 -[#6110]: https://github.com/prettier/prettier/pull/6110 -[#6115]: https://github.com/prettier/prettier/pull/6115 -[#6116]: https://github.com/prettier/prettier/pull/6116 -[#6119]: https://github.com/prettier/prettier/pull/6119 -[#6127]: https://github.com/prettier/prettier/pull/6127 -[#6129]: https://github.com/prettier/prettier/pull/6129 -[#6130]: https://github.com/prettier/prettier/pull/6130 -[#6131]: https://github.com/prettier/prettier/pull/6131 -[#6133]: https://github.com/prettier/prettier/pull/6133 -[#6136]: https://github.com/prettier/prettier/pull/6136 -[#6138]: https://github.com/prettier/prettier/pull/6138 -[#6140]: https://github.com/prettier/prettier/pull/6140 -[#6146]: https://github.com/prettier/prettier/pull/6146 -[#6148]: https://github.com/prettier/prettier/pull/6148 -[#6152]: https://github.com/prettier/prettier/pull/6152 -[#6159]: https://github.com/prettier/prettier/pull/6159 -[#6172]: https://github.com/prettier/prettier/pull/6172 -[#6178]: https://github.com/prettier/prettier/pull/6178 -[@belochub]: https://github.com/belochub -[@brainkim]: https://github.com/brainkim -[@duailibe]: https://github.com/duailibe -[@evilebottnawi]: https://github.com/evilebottnawi -[@hongrich]: https://github.com/hongrich -[@jridgewell]: https://github.com/jridgewell -[@jwbay]: https://github.com/jwbay -[@sosukesuzuki]: https://github.com/sosukesuzuki -[@thorn0]: https://github.com/thorn0 -[@bakkot]: https://github.com/bakkot -[@gavinjoyce]: https://github.com/GavinJoyce diff --git a/website/blog/2019-11-09-1.19.0.md b/website/blog/2019-11-09-1.19.0.md deleted file mode 100644 index d66c706fef..0000000000 --- a/website/blog/2019-11-09-1.19.0.md +++ /dev/null @@ -1,1705 +0,0 @@ ---- -author: Simon Lydell (@lydell) -authorURL: https://github.com/lydell -title: "Prettier 1.19: Long awaited Vue option, TypeScript 3.7 and new JavaScript features" ---- - -This release adds the long awaited `--vue-indent-script-and-style` option, support for TypeScript 3.7 and some cutting edge JavaScript syntax. Not to mention a whole bunch of bug fixes and improvements! - - - -## Highlights - -### Vue - -#### Add `--vue-indent-script-and-style` ([#6157] by [@kamilic]) - -The new [`--vue-indent-script-and-style`](https://prettier.io/docs/en/options.html#vue-files-script-and-style-tags-indentation) option controls whether or not to indent the code inside ` - - - - - - - -``` - -#### Add support for `!` and other entities ([#6785] by [@lydell] and [@ikatyang]) - -Previously, Prettier only supported the most common HTML entities, such as ` ` and `"`. Now, Prettier supports every HTML entity in the HTML spec, such as `!` and `⋔`. - - -```html - -

Hi!

- - - - -

Hi!

-``` - -#### Add JSON script types ([#6293] by [@ascorbic]) - - -```html - - - - - - - - - - - - - - - - -``` - -### Angular - -#### Put a closing parenthesis onto a new line after ternaries passed to pipes ([#5682] by [@selvazhagan]) - - -```html - -{{ (isCustomDiscount ? 'DISCOUNTS__DISCOUNT_TRAINING_HEADER__CUSTOM_DISCOUNT' : 'DISCOUNTS__DISCOUNT_TRAINING_HEADER__DISCOUNT') | translate }} - - -{{ - (isCustomDiscount - ? "DISCOUNTS__DISCOUNT_TRAINING_HEADER__CUSTOM_DISCOUNT" - : "DISCOUNTS__DISCOUNT_TRAINING_HEADER__DISCOUNT") | translate -}} - - -{{ - (isCustomDiscount - ? "DISCOUNTS__DISCOUNT_TRAINING_HEADER__CUSTOM_DISCOUNT" - : "DISCOUNTS__DISCOUNT_TRAINING_HEADER__DISCOUNT" - ) | translate -}} -``` - -#### Add formatting for `i18n` attributes ([#6695] by [@voithos]) - -Prettier will auto-wrap the contents of `i18n` attributes once they exceed the line length. - - -```html - -

- Hello! -

- - -

- Hello! -

- - -

- Hello! -

-``` - -### Handlebars - -#### Fix handling of whitespace and line breaks ([#6354] by [@chadian]) - -This fixes a variety of whitespace and line break use cases within Handlebars and Glimmer templates. - - -```hbs - -{{name}} - -Some sentence with {{dynamic}} expressions. - - - -sometimes{{nogaps}}areimportant -{{name}} is your name - - - -{{name}} -Some sentence with -{{dynamic}} -expressions. - - - -sometimes -{{nogaps}} -areimportant - -{{name}} -is your name - - -{{name}} - -Some sentence with {{dynamic}} expressions. - - - -sometimes{{nogaps}}areimportant - -{{name}} is your name -``` - -#### Avoid adding unwanted line breaks between text and mustaches ([#6186] by [@gavinjoyce]) - -Previously, Prettier added line breaks between text and mustaches which resulted in unwanted whitespace in rendered output. - - -```hbs - -

Your username is @{{name}}

-

Hi {{firstName}} {{lastName}}

- - -

- Your username is @ - {{name}} -

-

- Hi - {{firstName}} - {{lastName}} -

- - -

- Your username is @{{name}} -

-

- Hi {{firstName}} {{lastName}} -

-``` - -#### Improve comment formatting ([#6206] by [@gavinjoyce]) - - -```hbs - -
- {{! Foo }} - {{#if @foo}} - Foo - {{/if}} - - {{! Bar }} - {{#if @bar}} - Bar - {{/if}} -
- - -
- {{! Foo }} - {{#if @foo}} - Foo - {{/if}}{{! Bar }}{{#if @bar}} - Bar - {{/if}} -
- - -
- {{! Foo }} - {{#if @foo}} - Foo - {{/if}} - {{! Bar }} - {{#if @bar}} - Bar - {{/if}} -
-``` - -#### Preserve HTML entities ([#6234] by [@gavinjoyce]) - - -```hbs - -

- Some escaped characters: < > & -

- - -

- Some escaped characters: < > & -

- - -

- Some escaped characters: < > & -

-``` - -#### Fix `--single-quote` option on HTML attributes ([#6377] by [@dcyriller]) - -Previously, the flag was not applied on HTML attributes. - - -```hbs - -
- - -
- - -
-``` - -#### Break long interpolations ([#6249] by [@jjaffeux]) - - -```hbs - -{{my-component foo="bar" bar="baz" action=(action "almostTheMaximumLengthxxxx") -}} - - -{{my-component foo="bar" bar="baz" action=(action "almostTheMaximumLengthxxxx") -}} - - -{{my-component - foo="bar" - bar="baz" - action=(action "almostTheMaximumLengthxxxx") -}} -``` - -### MDX - -#### Text following JSX was trimmed incorrectly ([#6340] by [@JounQin]) - - -```md - - - test test - 123 - - - - test test -123 - - - - test test - 123 -``` - -#### Adjacent JSX elements should be allowed ([#6332] by [@JounQin]) - - -```jsx -// Input - - test test -123 - -// Prettier 1.18 -SyntaxError: Unexpected token (3:9) - 1 | - 2 | test test -> 3 | 123 - | ^ - -// Prettier 1.19 - - test test -123 - - -// Input - - test test - - - test test -123 - -// Prettier 1.18 -SyntaxError: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...? (4:1) - 2 | test test - 3 |
-> 4 | - | ^ - 5 | test test - 6 | 123 - -// Prettier 1.19 - - test test - - - test test -123 -``` - -### Vue - -#### Format `style[lang="css"]` ([#6875] by [@fisker]) - -Previously, ` - - - - - - -``` - -### Less - -#### Don't lowercase variable names and remove whitespace between variable and colon ([#6778] by [@fisker]) - - -```less -// Input -@FoO : bar; - -// Prettier 1.18 -@foo : bar; - -// Prettier 1.19 -@FoO: bar; -``` - -### API - -#### Add `resolveConfig` option to `getFileInfo()` ([#6666] by [@kaicataldo]) - -Add a `resolveConfig: boolean` option to `prettier.getFileInfo()` that, when set to `true`, will resolve the configuration for the given file path. This allows consumers to take any overridden parsers into account. - -### CLI - -#### Handle errors when reading stdin ([#6708] by [@andersk] and [@lydell]) - -If you had an error in your `.prettierrc` Prettier used to crash when formatting stdin. Such errors are now handled properly. - -``` -# Prettier 1.18 -$ prettier --parser babel < test.js -(node:21531) UnhandledPromiseRejectionWarning: Error: Invalid printWidth value. Expected an integer, but received "nope". - at _loop (/home/you/project/node_modules/prettier/bin-prettier.js:7887:63) - at Normalizer._applyNormalization (/home/you/project/node_modules/prettier/bin-prettier.js:8000:13) - at applyNormalization (/home/you/project/node_modules/prettier/bin-prettier.js:7817:49) - at Normalizer.normalize (/home/you/project/node_modules/prettier/bin-prettier.js:7823:9) - at normalizeOptions$1 (/home/you/project/node_modules/prettier/bin-prettier.js:8760:31) - at Object.normalizeApiOptions (/home/you/project/node_modules/prettier/bin-prettier.js:8918:10) - at getOptionsForFile (/home/you/project/node_modules/prettier/bin-prettier.js:44160:69) - at /home/you/project/node_modules/prettier/bin-prettier.js:44214:22 - at process._tickCallback (internal/process/next_tick.js:68:7) -(node:21531) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1) -(node:21531) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. - -# Prettier 1.19 -$ prettier --parser babel < test.js -[error] Invalid printWidth value. Expected an integer, but received "nope". -``` - -#### Gracefully handle nonexistent paths passed to `--stdin-filepath` ([#6687] by [@voithos] and [@lydell]) - -Previously, if you passed a nonexistent subdirectory to `--stdin-filepath`, Prettier would throw an error. Now, Prettier gracefully handles this. - -``` -# Prettier 1.18 -$ prettier --stdin-filepath does/not/exist.js < test.js -[error] Invalid configuration file: ENOENT: no such file or directory, scandir '/home/you/project/does/not' - -# Prettier 1.19 -$ prettier --stdin-filepath does/not/exist.js < test.js -test; -``` - -#### Config should not be evaluated for ignored files ([#6233] by [@jamesreggio]) - -Prior to this change, the CLI would resolve the config for a file before checking it against the ignored list. If the config was invalid, the CLI would report a failure. - -This change relocates the config-resolution phase until after the file is confirmed to not be ignored. - -#### Display invalid config filename in error message ([#6865] by [@fisker]) - - -``` -# Input -$ prettier filename.js --config .invalid-config - -# Prettier 1.18 -Invalid configuration file: ... - -# Prettier 1.19 -Invalid configuration file `.invalid-config`: ... -``` - -### Other - -Thanks to [@fisker] for updating lots of Prettier’s dependencies! - -#### VS Code: add support for .mongo files ([#6848] by [@aymericbouzy]) - -When using the Azure Cosmos DB extension for VS Code, you can create .mongo files to write MongoDB queries, which use Javascript syntax. This change allows VS Code to format your file using Prettier. - -```js -db.users.find({ someField: { $exists: true } }); -``` - -[#5682]: https://github.com/prettier/prettier/pull/5682 -[#5910]: https://github.com/prettier/prettier/pull/5910 -[#6033]: https://github.com/prettier/prettier/pull/6033 -[#6157]: https://github.com/prettier/prettier/pull/6157 -[#6186]: https://github.com/prettier/prettier/pull/6186 -[#6206]: https://github.com/prettier/prettier/pull/6206 -[#6209]: https://github.com/prettier/prettier/pull/6209 -[#6217]: https://github.com/prettier/prettier/pull/6217 -[#6233]: https://github.com/prettier/prettier/pull/6233 -[#6234]: https://github.com/prettier/prettier/pull/6234 -[#6236]: https://github.com/prettier/prettier/pull/6236 -[#6249]: https://github.com/prettier/prettier/pull/6249 -[#6270]: https://github.com/prettier/prettier/pull/6270 -[#6284]: https://github.com/prettier/prettier/pull/6284 -[#6289]: https://github.com/prettier/prettier/pull/6289 -[#6293]: https://github.com/prettier/prettier/pull/6293 -[#6301]: https://github.com/prettier/prettier/pull/6301 -[#6307]: https://github.com/prettier/prettier/pull/6307 -[#6332]: https://github.com/prettier/prettier/pull/6332 -[#6340]: https://github.com/prettier/prettier/pull/6340 -[#6354]: https://github.com/prettier/prettier/pull/6354 -[#6377]: https://github.com/prettier/prettier/pull/6377 -[#6381]: https://github.com/prettier/prettier/pull/6381 -[#6382]: https://github.com/prettier/prettier/pull/6382 -[#6397]: https://github.com/prettier/prettier/pull/6397 -[#6404]: https://github.com/prettier/prettier/pull/6404 -[#6411]: https://github.com/prettier/prettier/pull/6411 -[#6412]: https://github.com/prettier/prettier/pull/6412 -[#6420]: https://github.com/prettier/prettier/pull/6420 -[#6423]: https://github.com/prettier/prettier/pull/6423 -[#6438]: https://github.com/prettier/prettier/pull/6438 -[#6441]: https://github.com/prettier/prettier/pull/6441 -[#6446]: https://github.com/prettier/prettier/pull/6446 -[#6467]: https://github.com/prettier/prettier/pull/6467 -[#6471]: https://github.com/prettier/prettier/pull/6471 -[#6496]: https://github.com/prettier/prettier/pull/6496 -[#6506]: https://github.com/prettier/prettier/pull/6506 -[#6514]: https://github.com/prettier/prettier/pull/6514 -[#6604]: https://github.com/prettier/prettier/pull/6604 -[#6605]: https://github.com/prettier/prettier/pull/6605 -[#6640]: https://github.com/prettier/prettier/pull/6640 -[#6646]: https://github.com/prettier/prettier/pull/6646 -[#6657]: https://github.com/prettier/prettier/pull/6657 -[#6666]: https://github.com/prettier/prettier/pull/6666 -[#6673]: https://github.com/prettier/prettier/pull/6673 -[#6687]: https://github.com/prettier/prettier/pull/6687 -[#6694]: https://github.com/prettier/prettier/pull/6694 -[#6695]: https://github.com/prettier/prettier/pull/6695 -[#6708]: https://github.com/prettier/prettier/pull/6708 -[#6717]: https://github.com/prettier/prettier/pull/6717 -[#6728]: https://github.com/prettier/prettier/pull/6728 -[#6778]: https://github.com/prettier/prettier/pull/6778 -[#6785]: https://github.com/prettier/prettier/pull/6785 -[#6796]: https://github.com/prettier/prettier/pull/6796 -[#6816]: https://github.com/prettier/prettier/pull/6816 -[#6833]: https://github.com/prettier/prettier/pull/6833 -[#6848]: https://github.com/prettier/prettier/pull/6848 -[#6856]: https://github.com/prettier/prettier/pull/6856 -[#6863]: https://github.com/prettier/prettier/pull/6863 -[#6864]: https://github.com/prettier/prettier/pull/6864 -[#6865]: https://github.com/prettier/prettier/pull/6865 -[#6875]: https://github.com/prettier/prettier/pull/6875 -[@andersk]: https://github.com/andersk -[@ascorbic]: https://github.com/ascorbic -[@aymericbouzy]: https://github.com/aymericbouzy -[@bakkot]: https://gibhub.com/bakkot -[@brainkim]: https://github.com/brainkim -[@chadian]: https://github.com/chadian -[@cryrivers]: https://github.com/Cryrivers -[@dcyriller]: https://github.com/dcyriller -[@duailibe]: https://github.com/duailibe -[@ericsakmar]: https://github.com/ericsakmar -[@fisker]: https://github.com/fisker -[@g-harel]: https://github.com/g-harel -[@gavinjoyce]: https://github.com/gavinjoyce -[@gkz]: https://github.com/gkz -[@ikatyang]: https://github.com/ikatyang/ -[@jamesreggio]: https://github.com/jamesreggio -[@jjaffeux]: https://github.com/jjaffeux -[@jounqin]: https://github.com/JounQin -[@jridgewell]: https://github.com/jridgewell -[@kaicataldo]: https://github.com/kaicataldo -[@kamilic]: https://github.com/kamilic -[@lydell]: https://github.com/lydell -[@mattleff]: https://github.com/mattleff -[@rreverser]: https://github.com/RReverser -[@selvazhagan]: https://github.com/selvazhagan -[@sosukesuzuki]: https://github.com/sosukesuzuki -[@squidfunk]: https://github.com/squidfunk -[@thorn0]: https://github.com/thorn0 -[@vjeux]: https://github.com/vjeux -[@voithos]: https://github.com/voithos diff --git a/website/blog/2021-05-09-2.3.0.md b/website/blog/2021-05-09-2.3.0.md new file mode 100644 index 0000000000..b2494ae1ef --- /dev/null +++ b/website/blog/2021-05-09-2.3.0.md @@ -0,0 +1,1854 @@ +--- +author: "Georgii Dolzhykov (@thorn0)" +authorURL: "https://github.com/thorn0" +title: "Prettier 2.3. In which assignments are consistent, short keys non-breaking, and Handlebars official" +--- + +This release focuses on fixing long-standing issues in the JavaScript printer. Be warned that, unfortunately, reformatting a project with the new version might result in quite a big diff. If you don’t use [`ignoreRevsFile`](https://git-scm.com/docs/git-blame#Documentation/git-blame.txt---ignore-revs-fileltfilegt) to hide such wholesale changes from `git blame`, it might be about time. + +A remarkable milestone is the long-awaited release of the Ember / Handlebars formatter. It’s supposed to be the last formatter included directly in the core library. In the future, for sustainability, languages should be added only by plugins. + +We are grateful to our financial contributors: [Salesforce](https://engineering.salesforce.com/foss-fund-brings-more-than-just-financial-contributions-7b0664067b1e), [Indeed](https://engineering.indeedblog.com/blog/2019/07/foss-fund-six-months-in/), [Frontend Masters](https://blog.opencollective.com/frontend-masters/), Airbnb, Shogun Labs, Skyscanner, Konstantin Pschera, and [many others](https://opencollective.com/prettier#section-contributors) who help us keep going. If you enjoy Prettier and would like to support our work, head to our [OpenCollective](https://opencollective.com/prettier). Please consider also supporting the projects Prettier depends on, such as [typescript-eslint](https://opencollective.com/typescript-eslint), [remark](https://opencollective.com/unified), and [Babel](https://opencollective.com/babel). + +Most of the changes in this release are thanks to the hard work of [Fisker Cheung](https://github.com/fisker), [Georgii Dolzhykov](https://github.com/thorn0), and [Sosuke Suzuki](https://github.com/sosukesuzuki), along with many other contributors. + +And just a reminder, when Prettier is installed or updated, it’s [strongly recommended](https://prettier.io/docs/en/install.html#summary) to specify the exact version in `package.json`: `"2.3.0"`, not `"^2.3.0"`. + + + +## Highlights + +### JavaScript + +#### Format assignments more consistently ([#10222](https://github.com/prettier/prettier/pull/10222), [#10643](https://github.com/prettier/prettier/pull/10643), [#10672](https://github.com/prettier/prettier/pull/10672) by [@thorn0](https://github.com/thorn0); [#10158](https://github.com/prettier/prettier/pull/10158) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + +Previously, Prettier had a lot of trouble with figuring out how to break lines in assignments. E.g., long right-hand sides often stayed unbroken. Not anymore. + + +```ts +// Prettier 2.2 +aParticularlyLongAndObnoxiousNameForIllustrativePurposes = anotherVeryLongNameForIllustrativePurposes; + +aParticularlyLongAndObnoxiousNameForIllustrativePurposes = "a very long string for illustrative purposes" + .length; + +someReallyLongThingStoredInAMapWithAReallyBigName[ + pageletID +] = _someVariableThatWeAreCheckingForFalsiness + ? Date.now() - _someVariableThatWeAreCheckingForFalsiness + : 0; + +class x { + private readonly rawConfigFromFile$: BehaviorSubject = new BehaviorSubject( + notRead + ); +} + +// Prettier 2.3 +aParticularlyLongAndObnoxiousNameForIllustrativePurposes = + anotherVeryLongNameForIllustrativePurposes; + +aParticularlyLongAndObnoxiousNameForIllustrativePurposes = + "a very long string for illustrative purposes".length; + +someReallyLongThingStoredInAMapWithAReallyBigName[pageletID] = + _someVariableThatWeAreCheckingForFalsiness + ? Date.now() - _someVariableThatWeAreCheckingForFalsiness + : 0; + +class x { + private readonly rawConfigFromFile$: BehaviorSubject = + new BehaviorSubject(notRead); +} +``` + +#### Prevent wrapping object properties with short keys ([#10335](https://github.com/prettier/prettier/pull/10335) by [@thorn0](https://github.com/thorn0)) + +Line breaks after short property names in object literals often look unnatural. Even when such a line break yields a line length benefit of 1 or 2 characters, it rarely looks justified. Prettier 2.3 avoids line breaks after property names shorter than `tabWidth + 3` – for example, 5 characters in the default configuration, or 7 characters with `tabWidth: 4`. This heuristic may be revised in future versions. + + +```js +// Prettier 2.2 +const importantLink = { + url: + "https://prettier.io/docs/en/rationale.html#what-prettier-is-concerned-about", + gitHubUrl: + "https://github.com/prettier/prettier/blob/main/docs/rationale.md#what-prettier-is-concerned-about", +}; + +// Prettier 2.3 +const importantLink = { + url: "https://prettier.io/docs/en/rationale.html#what-prettier-is-concerned-about", + gitHubUrl: + "https://github.com/prettier/prettier/blob/main/docs/rationale.md#what-prettier-is-concerned-about", +}; +``` + +### Ember / Handlebars + +#### Move Handlebars support out of alpha to release ([#10290](https://github.com/prettier/prettier/pull/10290) by [@dcyriller](https://github.com/dcyriller) & [@thorn0](https://github.com/thorn0)) + +This started in 2017. Handlebars support has been in Prettier for a while, but it wasn’t released officially as it wasn’t really ready. Its status went from “alpha” to “experimental” to “beta” and then, if you checked older release notes, you can see that after “beta” somehow it was “alpha” again… + +Well, anyway, it finally is happening: Prettier can now officially format HTML templates with Handlebars! 🎉 + +It uses [Glimmer], [Ember]’s Handlebars parser, so it should be compliant with the HTML spec thanks to the Ember team. + +The [`--html-whitespace-sensitivity`][hws-option] option is supported and defaults to `strict`, which means that Prettier will always respect the presence or absence of whitespace around tags and consider it unsafe to add whitespace where there were none and vice versa as this can affect how the document is rendered in the browser. The `css` value is not yet supported (treated as `strict` for now). + +The feature is called “Ember / Handlebars” and not just “Handlebars” because Glimmer doesn’t support some syntax and use cases of Handlebars. This is mostly due to the fact that [Handlebars], being a template engine (a preprocessor), doesn’t care about the underlying syntax of the content it processes whereas Glimmer parses two syntaxes – HTML and Handlebars – at the same time and combines the result into a single tree, which Prettier can print. This means Prettier won’t format Handlebars files that can’t be parsed into such a tree, either because the underlying syntax isn’t HTML or because template directives and tags overlap in a way that can’t be represented in a tree (e.g., `{{#if foo}}
{{/if}`). Even with these restrictions, the formatter still seems to be useful enough to non-Ember Handlebars users. As for the syntax unsupported by Ember, there is a good chance to see support for it in future versions of Prettier as Glimmer uses a full-fledged Handlebars parser under the hood. + +Files with the extensions `.hbs` and `.handlebars` are recognized as Handlebars by default. For other extensions, the [`--parser`](parser-option) option with the value `glimmer` has to be specified – for example, using command line or, better yet, [configuration overrides]. + +See the formatter in action on the [playground][playground-glimmer]! + +[glimmer]: https://www.npmjs.com/package/@glimmer/syntax +[ember]: https://emberjs.com +[hws-option]: https://prettier.io/docs/en/options.html#html-whitespace-sensitivity +[handlebars]: https://handlebarsjs.com/ +[parser-option]: https://prettier.io/docs/en/options.html#parser +[configuration overrides]: https://prettier.io/docs/en/configuration.html#configuration-overrides +[playground-glimmer]: https://prettier.io/playground/#N4Igxg9gdgLgprEAuEACVAeAJgSwG7qFgA2AhgM7kC8AOiAjAE4CedhqAfDVOhgBYBGDsGDoYOGMTjsAvjIwB6QVx6ZcBdCQrU6AIwhZWIFe1OERhfYbOE53Reo6YFjkABoQEAA7jo5ZKCkjIwQAO4ACkEI-iikxKGkzP4euoykYADWcDAAyl7pOFAA5shMAK5wHnAAtrpwWFj1ADKkxWWkRXAAYhCM1aQw4sXIIKRlMBDuIHww1cQA6nwScOT5YHA50RL4Eswj5Ew4YDBTheRwjDDhaUX9yABmceceAFbkAB4AQmmZ2Tmk1TgTUKcAeT0qIDe7xyhSKUgAimUIPAwcRniB8oxzowRnCcNVATiPF5GIUYPMcFgYHxkAAOAAMxJC53maS8IxJKwueFBHgAjkj4NdvDFRuQALRQOD1epTRhwAU4eXXDp3JCPNEQ87VHClRgVDzkWEIwWg9XgjwwUi6ClUmlIABMlrSOGIsIAwhACaQRisAKxTMrnAAq1piGvReAqAEkoI1YDkwKSfABBOM5GDMKSo85yIA + +## Formatting Improvements + +### JavaScript + +#### Refine formatting of curried arrow functions ([#9992](https://github.com/prettier/prettier/pull/9992), [#10543](https://github.com/prettier/prettier/pull/10543) by [@sosukesuzuki](https://github.com/sosukesuzuki) & [@thorn0](https://github.com/thorn0)) + + +```js +// Prettier 2.2 +const currying = (argument1) => (argument2) => (argument3) => (argument4) => ( + argument5 +) => (argument6) => foo; + +// Prettier 2.3 +const currying = + (argument1) => + (argument2) => + (argument3) => + (argument4) => + (argument5) => + (argument6) => + foo; +``` + +#### Improve formatting for React Hooks calls ([#10238](https://github.com/prettier/prettier/pull/10238) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + + +```js +// Prettier 2.2 +const { firstName, lastName } = useMemo(() => parseFullName(fullName), [ + fullName, +]); + +// Prettier 2.3 +const { firstName, lastName } = useMemo( + () => parseFullName(fullName), + [fullName] +); +``` + +#### Improve visual separation between header and body in classes with multiline headers ([#10085](https://github.com/prettier/prettier/pull/10085) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + + +```ts +// Prettier 2.2 +class loooooooooooooooooooong + extends looooooooooooooooooong + implements loooooooooooooooooooong { + property: string; +} + +// Prettier 2.3 +class loooooooooooooooooooong + extends looooooooooooooooooong + implements loooooooooooooooooooong +{ + property: string; +} +``` + +#### Concise formatting of number-only arrays ([#10106](https://github.com/prettier/prettier/pull/10106), [#10160](https://github.com/prettier/prettier/pull/10160) by [@thorn0](https://github.com/thorn0)) + +While in general, Prettier avoids this kind of formatting because it's not diff-friendly, in this special case we decided that the benefits outweigh the risks. + +If at least one element has a trailing single-line (`// ...`) comment on the same line, the concise formatting isn't applied. On the other hand, single-line comments placed on separate lines don't have such an effect and – as well as empty lines – can be used for logical grouping. + + +```jsx +// Input +const lazyCatererNumbers = [1, 2, 4, 7, 11, 16, 22, 29, 37, 46, + +// n > 10 +56, 67, 79, 92, 106, 121, 137, 154, 172, 191, 211, 232, 254, 277, 301, 326, 352, 379, 407, 436, 466, +497, 529, 562, 596, 631, 667, 704, 742, 781, +// n > 40 +821, 862, 904, 947, 991, 1036, 1082, 1129, 1177, 1226, 1276, 1327, 1379]; + +// Prettier 2.2 +const lazyCatererNumbers = [ + 1, + 2, + 4, + 7, + 11, + 16, + 22, + 29, + 37, + // ... ✂ 46 lines ✂ ... + 1379, +]; + +// Prettier 2.3 +const lazyCatererNumbers = [ + 1, 2, 4, 7, 11, 16, 22, 29, 37, 46, + + // n > 10 + 56, 67, 79, 92, 106, 121, 137, 154, 172, 191, 211, 232, 254, 277, 301, 326, + 352, 379, 407, 436, 466, 497, 529, 562, 596, 631, 667, 704, 742, 781, + // n > 40 + 821, 862, 904, 947, 991, 1036, 1082, 1129, 1177, 1226, 1276, 1327, 1379, +]; +``` + +#### Improve formatting for nested await expressions in heads of member and call expressions ([#10342](https://github.com/prettier/prettier/pull/10342) by [@thorn0](https://github.com/thorn0)) + +Even though Prettier tries to be helpful here, please don't write code like this. Have mercy upon your teammates and use intermediate variables. + + +```jsx +// Input +const getAccountCount = async () => + (await + (await ( + await focusOnSection(BOOKMARKED_PROJECTS_SECTION_NAME) + ).findItem("My bookmarks")).getChildren() + ).length + +// Prettier 2.2 +const getAccountCount = async () => + ( + await ( + await (await focusOnSection(BOOKMARKED_PROJECTS_SECTION_NAME)).findItem( + "My bookmarks" + ) + ).getChildren() + ).length; + +// Prettier 2.3 +const getAccountCount = async () => + ( + await ( + await ( + await focusOnSection(BOOKMARKED_PROJECTS_SECTION_NAME) + ).findItem("My bookmarks") + ).getChildren() + ).length; +``` + +#### Improve formatting for `do` expressions in function calls ([#10693](https://github.com/prettier/prettier/pull/10693) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + +“`do` expressions” are a [stage 1 ECMAScript proposal](https://github.com/tc39/proposal-do-expressions). + + +```js +// Prettier 2.2 +expect( + do { + var bar = "foo"; + bar; + } +).toBe("foo"); + +// Prettier 2.3 +expect(do { + var bar = "foo"; + bar; +}).toBe("foo"); +``` + +#### Consistent indentation for conditional operators ([#10187](https://github.com/prettier/prettier/pull/10187), [#10266](https://github.com/prettier/prettier/pull/10266) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + + +```ts +// Prettier 2.2 +const dotNotationMemberExpression = (callNode.parent?.type === +AST_NODE_TYPES.ChainExpression + ? callNode.parent.parent + : callNode.parent +).TSESTree.BinaryExpression; + +const computedMemberExpression = (callNode.parent?.type === +AST_NODE_TYPES.ChainExpression + ? callNode.parent.parent + : callNode.parent)[TSESTree.BinaryExpression]; + +const callExpressionCallee = (callNode.parent?.type === + AST_NODE_TYPES.ChainExpression + ? callNode.parent.parent + : callNode.parent)(TSESTree.BinaryExpression); + +const typeScriptAsExpression = (callNode.parent?.type === +AST_NODE_TYPES.ChainExpression + ? callNode.parent.parent + : callNode.parent) as TSESTree.BinaryExpression; + +// Prettier 2.3 +const dotNotationMemberExpression = ( + callNode.parent?.type === AST_NODE_TYPES.ChainExpression + ? callNode.parent.parent + : callNode.parent +).TSESTree.BinaryExpression; + +const computedMemberExpression = ( + callNode.parent?.type === AST_NODE_TYPES.ChainExpression + ? callNode.parent.parent + : callNode.parent +)[TSESTree.BinaryExpression]; + +const callExpressionCallee = ( + callNode.parent?.type === AST_NODE_TYPES.ChainExpression + ? callNode.parent.parent + : callNode.parent +)(TSESTree.BinaryExpression); + +const typeScriptAsExpression = ( + callNode.parent?.type === AST_NODE_TYPES.ChainExpression + ? callNode.parent.parent + : callNode.parent +) as TSESTree.BinaryExpression; +``` + +### HTML + +#### Prefix-based multiline formatting for the `class` attribute ([#7865](https://github.com/prettier/prettier/pull/7865) by [@thorn0](https://github.com/thorn0)) + +Formatting of HTML class names will now keep classes on one line until the line length limit is reached; at that point, consecutive classes with the same prefix will be grouped together on each line. For layout frameworks such as Bootstrap and Tailwind CSS, which add many classes to an element, this is important for readability and maintainability vs. the previous behavior (keeping all classes on one line) or e.g. putting each class on its own line. + + +```html + +
+ + +
+``` + +## Other Changes + +### JavaScript + +#### Fix unstable multiple comments on the same line ([#9672](https://github.com/prettier/prettier/pull/9672) by [@fisker](https://github.com/fisker)) + + +```js +// Input +a; +/*1*//*2*/ +/*3*/ +b; + +// Prettier 2.2 +a; /*2*/ +/*1*/ /*3*/ +b; + +// Prettier 2.2 (second format) +a; /*2*/ /*3*/ +/*1*/ b; + +// Prettier 2.3 +a; +/*1*/ /*2*/ +/*3*/ +b; +``` + +#### Don’t format nodes that end just before `rangeStart` ([#9704](https://github.com/prettier/prettier/pull/9704) by [@fisker](https://github.com/fisker)) + +Previously, when [range formatting](https://prettier.io/docs/en/options.html#range) was performed, such nodes were considered part of the range, now they're excluded. This affects other languages that the range formatting feature supports, not only JavaScript. + + +```js +// Input +foo = 1.0000;bar = 1.0000;baz=1.0000; + ^^^^^^^^^^^^^ Range + +// Prettier 2.2 +foo = 1.0; +bar = 1.0;baz=1.0000; + +// Prettier 2.3 +foo = 1.0000;bar = 1.0;baz=1.0000; +``` + +#### Fix comments inside JSX end tag ([#9711](https://github.com/prettier/prettier/pull/9711) by [@fisker](https://github.com/fisker)) + + +```jsx +// Input +; + +// Prettier 2.2 +; + +// Prettier 2.3 +; +``` + +#### Fix inconsistent language comment detection ([#9743](https://github.com/prettier/prettier/pull/9743) by [@fisker](https://github.com/fisker)) + +An `/* HTML */` comment should directly precede a template literal for the latter to be recognized as HTML-in-JS. Previously, the comment was erroneously recognized is some other locations. + + +```jsx +// Input +foo /* HTML */ = `
+
`; + +// Prettier 2.2 (--parser=babel) +foo /* HTML */ = `
`; + +// Prettier 2.2 (--parser=meriyah) +foo /* HTML */ = `
+
`; + +// Prettier 2.3 (All JavaScript parsers) +foo /* HTML */ = `
+
`; +``` + +#### Fix extra semicolon added to ignored directives ([#9850](https://github.com/prettier/prettier/pull/9850) by [@fisker](https://github.com/fisker)) + + +```js +// Input +// prettier-ignore +'use strict'; + +function foo() { +// prettier-ignore +"use strict";; +} + +// Prettier 2.2 +// prettier-ignore +'use strict';; + +function foo() { + // prettier-ignore + "use strict";; +} + +// Prettier 2.3 +// prettier-ignore +'use strict'; + +function foo() { + // prettier-ignore + "use strict"; +} +``` + +#### Fix unstable JSX formatting with U+3000 ([#9866](https://github.com/prettier/prettier/pull/9866) by [@fisker](https://github.com/fisker)) + + +```js +// Input +

+  {this.props.data.title}  + //----- ^ U+3000 --------------- ^ U+3000 +

+ +// Prettier 2.2 +

+ +  {this.props.data.title}  + //----- ^ U+3000 --------------- ^ U+3000 +

; + +// Prettier 2.2 (second format) +

+  {this.props.data.title}  + //----- ^ U+3000 --------------- ^ U+3000 +

; + +// Prettier 2.3 +

+  {this.props.data.title}  + //----- ^ U+3000 --------------- ^ U+3000 +

; +``` + +#### Fix error thrown on expressions like `a(b => c => function (){})` ([#10278](https://github.com/prettier/prettier/pull/10278) by [@thorn0](https://github.com/thorn0)) + +Regression from v2.2.0. + + +```jsx +// Input +a(b => c => function (){}) + +// Prettier 2.2 +TypeError: Cannot read property 'length' of undefined + +// Prettier 2.3 +a((b) => (c) => function () {}); +``` + +#### Improve formatting for inline decorators ([#10296](https://github.com/prettier/prettier/pull/10296) by [@fisker](https://github.com/fisker)) + + +```jsx +// Input +class Foo { + @decorator([]) bar() {} + @decorator( + [] + ) baz() {} +} + +// Prettier 2.2 +class Foo { + @decorator([]) bar() {} + @decorator([]) + baz() {} +} + +// Prettier 2.3 +class Foo { + @decorator([]) bar() {} + @decorator([]) baz() {} +} +``` + +#### Fix ASI protection for private fields ([#10334](https://github.com/prettier/prettier/pull/10334) by [@thorn0](https://github.com/thorn0)) + + +```jsx +// Input +class C { + #field = 'value'; + ["method"]() {} +} + +// Prettier 2.2 (with --no-semi) +class C { + #field = "value" + ["method"]() {} +} + +// Prettier 2.3 (with --no-semi) +class C { + #field = "value"; + ["method"]() {} +} +``` + +#### Support Module Blocks proposal ([#10417](https://github.com/prettier/prettier/pull/10417) by [@sosukesuzuki](https://github.com/sosukesuzuki), [@thorn0](https://github.com/thorn0)) + +Support formatting for [Module Blocks Stage 2 proposal](https://github.com/tc39/proposal-js-module-blocks). + + +```js +// Input +module { export let foo = "foo"; }; + +// Prettier 2.2 +SyntaxError: Unexpected token, expected ";" + +// Prettier 2.3 +module { + export let foo = "foo"; +}; +``` + +#### Fix missing parentheses for `yield` in a pipeline ([#10446](https://github.com/prettier/prettier/pull/10446) by [@fisker](https://github.com/fisker)) + + +```jsx +// Input +function* f() { + return x |> (yield #); +} + +// Prettier 2.2 +function* f() { + return x |> yield #; +} + +// Prettier 2.3 +function* f() { + return x |> (yield #); +} +``` + +#### Make Babel’s error recovery more selective ([#10495](https://github.com/prettier/prettier/pull/10495) by [@fisker](https://github.com/fisker), [#9787](https://github.com/prettier/prettier/pull/9787) by [@sosukesuzuki](https://github.com/sosukesuzuki), [#10065](https://github.com/prettier/prettier/pull/10065), [#10322](https://github.com/prettier/prettier/pull/10322) by [@thorn0](https://github.com/thorn0)) + +Previously, because of the [error recovery](https://babeljs.io/blog/2019/11/05/7.7.0#parser-error-recovery-10363httpsgithubcombabelbabelpull10363), the Babel parser was too permissive, which lead to all kinds of AST shapes that Prettier couldn’t print. Prettier 2.3 lets Babel recover only from a few harmless types of errors – for example, multiple `const` declarations with the same name. Anything else is reported as syntax errors. + + +```js +// Input +foo("a", , "b"); + +// Prettier 2.2 +TypeError: Cannot read property 'type' of null + +// Prettier 2.3 +[error] stdin: SyntaxError: Argument expression expected. (1:10) +[error] > 1 | foo("a", , "b"); +[error] | ^ +``` + + +```js +// Input +const \u{20} = 1 + +// Prettier 2.2 +const = 1; + +// Prettier 2.3 +[error] stdin: SyntaxError: Invalid Unicode escape (1:7) +[error] > 1 | const \u{20} = 1 +[error] | ^ ^ +``` + +#### Avoid last-argument hugging for number-only arrays ([#10517](https://github.com/prettier/prettier/pull/10517) by [@thorn0](https://github.com/thorn0)) + +Another special case for number-only arrays. + + +```jsx +// Input +instantiate(game, [ + transform([-0.7, 0.5, 0]), + render_colored_diffuse(game.MaterialDiffuse, game.Meshes["monkey_flat"], [1, 1, 0.3, 1]), +]); + +// Prettier 2.2 +instantiate(game, [ + transform([-0.7, 0.5, 0]), + render_colored_diffuse(game.MaterialDiffuse, game.Meshes["monkey_flat"], [ + 1, + 1, + 0.3, + 1, + ]), +]); + +// Prettier 2.3 +instantiate(game, [ + transform([-0.7, 0.5, 0]), + render_colored_diffuse( + game.MaterialDiffuse, + game.Meshes["monkey_flat"], + [1, 1, 0.3, 1] + ), +]); +``` + +#### Improve detection of AMD `define` ([#10528](https://github.com/prettier/prettier/pull/10528) by [@thorn0](https://github.com/thorn0)) + +Prettier special-cases AMD `define` calls to avoid unexpected line breaks in them. We now only format `define` calls if they are at the top level of a function or program and are passed arguments in the way AMD expects. + + +```jsx +// Prettier 2.2 +const someVariable = define("some string literal", anotherVariable, yetAnotherVariable); + +// Prettier 2.3 +const someVariable = define( + "some string literal", + anotherVariable, + yetAnotherVariable +); +``` + +#### Fix duplicated `prettier-ignore` comments ([#10666](https://github.com/prettier/prettier/pull/10666) by [@fisker](https://github.com/fisker)) + + +```jsx +// Input +foo = a. + // prettier-ignore + b; + +// Prettier 2.2 +foo = + // prettier-ignore + a. + // prettier-ignore + b; + +// Prettier 2.3 +foo = a. + // prettier-ignore + b; +``` + +#### Process conditional groups in `mapDoc` ([#10695](https://github.com/prettier/prettier/pull/10695) by [@thorn0](https://github.com/thorn0)) + +In particular, this fixes broken substitutions in HTML-in-JS. + + +```jsx +// Input +export default function include_photoswipe( + gallery_selector = ".my-gallery" +): string { + return /* HTML */ ` + `; +} + +// Prettier 2.2 +export default function include_photoswipe( + gallery_selector = ".my-gallery" +): string { + return /* HTML */ ` `; +} + +// Prettier 2.3 +export default function include_photoswipe( + gallery_selector = ".my-gallery" +): string { + return /* HTML */ ` `; +} +``` + +#### Avoid arg expansion that leads to broken code ([#10712](https://github.com/prettier/prettier/pull/10712) by [@thorn0](https://github.com/thorn0)) + + +```jsx +// Input +glimseGlyphsHazardNoopsTieTie(({ a, b = () => { + console.log(); +}}) => averredBathersBoxroomBuggyNurl()); + +// Prettier 2.2 +glimseGlyphsHazardNoopsTieTie(({ a, b = () => { + console.log(); + } }) => averredBathersBoxroomBuggyNurl()); + +// Prettier 2.3 +glimseGlyphsHazardNoopsTieTie( + ({ + a, + b = () => { + console.log(); + }, + }) => averredBathersBoxroomBuggyNurl() +); +``` + +#### Fix missing parentheses around `async` in `for-of` ([#10781](https://github.com/prettier/prettier/pull/10781) by [@fisker](https://github.com/fisker)) + +See https://github.com/tc39/ecma262/issues/2034 + + +```jsx +// Input +for ((async) of []); + +// Prettier 2.2 +for (async of []); + +// Prettier 2.2 (second format) +SyntaxError: Unexpected token, expected "=>" (1:15) +> 1 | for (async of []); + +// Prettier 2.3 +for ((async) of []); +``` + +#### Support `async do` expressions proposal ([#10813](https://github.com/prettier/prettier/pull/10813) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + +See https://github.com/tc39/proposal-async-do-expressions + + +```js +// Input +const x = async do { + await requestAPI().json(); +}; + +// Prettier 2.2 +SyntaxError: Unexpected token, expected ";" (1:17) + +// Prettier 2.3 +const x = async do { + await requestAPI().json(); +}; +``` + +### TypeScript + +#### Fix missing comments in `MethodDefinition` ([#9872](https://github.com/prettier/prettier/pull/9872) by [@fisker](https://github.com/fisker)) + +`typescript` parser only, `babel-ts` doesn't have this issue. + + +```typescript +// Input +class Foo { + bar() /* bat */; +} + +// Prettier 2.2 +Error: Comment "bat" was not printed. Please report this error! + +// Prettier 2.3 +class Foo { + bar /* bat */(); +} +``` + +#### Fix unnecessary line breaks in method type declaration parameters ([#10024](https://github.com/prettier/prettier/pull/10024) by [@sosukesuzuki](https://github.com/sosukesuzuki), [#10357](https://github.com/prettier/prettier/pull/10357) by [@thorn0](https://github.com/thorn0)) + + +```js +// Input +type Foo = { + method(foo: "foo"): ` + ` +}; + +// Prettier 2.2 +type Foo = { + method( + foo: "foo" + ): ` + `; +}; + +// Prettier 2.3 +type Foo = { + method(foo: "foo"): ` + `; +}; + +``` + +#### Print trailing commas in type parameters ([#10109](https://github.com/prettier/prettier/pull/10109) by [@sosukesuzuki](https://github.com/sosukesuzuki), [#10353](https://github.com/prettier/prettier/pull/10353) by [@thorn0](https://github.com/thorn0)) + +TypeScript has been supporting trailing commas in type parameters since TypeScript 2.7 released in January 2018. Prettier 2.3 prints them if the `trailingComma` option is set to `all`. Keep this option at the more conservative default value `es5` if compatibility with TypeScript 2.7 or older is needed. Note that TypeScript [still doesn't support][ts-issue-21984] trailing commas in type arguments (type parameter instantiations). + +[ts-issue-21984]: https://github.com/microsoft/TypeScript/issues/21984 + + +```ts +// Input +export class BaseSingleLevelProfileTargeting< + T extends ValidSingleLevelProfileNode, +> { + // ... +} + +// Prettier 2.2 +export class BaseSingleLevelProfileTargeting< + T extends ValidSingleLevelProfileNode +> { + // ... +} + +// Prettier 2.3 with --trailling-comma=all +export class BaseSingleLevelProfileTargeting< + T extends ValidSingleLevelProfileNode, +> { + // ... +} +``` + +#### Allow hugging arguments that are non-concise arrow functions with return type annotations ([#10316](https://github.com/prettier/prettier/pull/10316) by [@thorn0](https://github.com/thorn0)) + + +```ts +// Prettier 2.2 +users.map( + (user: User): User => { + return user; + } +); + +// Prettier 2.3 +users.map((user: User): User => { + return user; +}) +``` + +#### Correct parentheses for non-null assertions ([#10337](https://github.com/prettier/prettier/pull/10337) by [@thorn0](https://github.com/thorn0)) + +Necessary parentheses sometimes weren't printed in expressions containing non-null assertions. This has been fixed. + + +```ts +// Input +const myFunction2 = (key: string): number => + ({ + a: 42, + b: 42, + }[key]!) + +// Prettier 2.2 (invalid syntax) +const myFunction2 = (key: string): number => + { + a: 42, + b: 42, + }[key]!; + +// Prettier 2.3 +const myFunction2 = (key: string): number => + ({ + a: 42, + b: 42, + }[key]!); +``` + +#### Indent type assertions in heads of member and call expressions ([#10341](https://github.com/prettier/prettier/pull/10341) by [@thorn0](https://github.com/thorn0)) + + +```ts +// Input +const accountCount = (findItemInSection(BOOKMARKED_PROJECTS_SECTION_NAME, + "My bookmarks") as TreeItem).getChildren().length; + +// Prettier 2.2 +const accountCount = (findItemInSection( + BOOKMARKED_PROJECTS_SECTION_NAME, + "My bookmarks" +) as TreeItem).getChildren().length; + +// Prettier 2.3 +const accountCount = ( + findItemInSection( + BOOKMARKED_PROJECTS_SECTION_NAME, + "My bookmarks" + ) as TreeItem +).getChildren().length; +``` + +#### Support intrinsic keyword ([#10390](https://github.com/prettier/prettier/pull/10390) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + + +```ts +// Input +type Uppercase = intrinsic; + +// Prettier 2.2 +Error: unknown type: "TSIntrinsicKeyword" + +// Prettier 2.3 +type Uppercase = intrinsic; + +``` + +#### Support TypeScript 4.2 ([#10418](https://github.com/prettier/prettier/pull/10418), [#10466](https://github.com/prettier/prettier/pull/10466), [#10546](https://github.com/prettier/prettier/pull/10546), [#10589](https://github.com/prettier/prettier/pull/10589) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + +##### [`abstract` Construct Signatures](https://devblogs.microsoft.com/typescript/announcing-typescript-4-2/#abstract-construct-signatures) + + +```ts +// Input +type T = abstract new () => void; + +// Prettier 2.2 +SyntaxError: Unexpected token, expected ";" (1:19) + +// Prettier 2.3 +type T = abstract new () => void; + +``` + +##### [Type imports in import require declaration](https://github.com/microsoft/TypeScript/pull/41573) + + +```ts +// Input +import type A = require("A"); + +// Prettier 2.2 +SyntaxError: Only ECMAScript imports may use 'import type'. + +// Prettier 2.3 +import type A = require("A"); + +``` + +#### Fix misplaced comments in unions and intersections ([#10457](https://github.com/prettier/prettier/pull/10457) by [@thorn0](https://github.com/thorn0)) + + +```ts +// Input +type Foo = "1" | "2" /* two */ | "3"; + +// Prettier 2.2 +type Foo = "1" | "2" | /* two */ "3"; + +// Prettier 2.3 +type Foo = "1" | "2" /* two */ | "3"; +``` + +#### Don’t print parens around nested type assertions ([#10702](https://github.com/prettier/prettier/pull/10702) by [@thorn0](https://github.com/thorn0)) + + +```ts +// Input +foo as unknown as Bar + +// Prettier 2.2 +(foo as unknown) as Bar; + +// Prettier 2.3 +foo as unknown as Bar; +``` + +#### Support TypeScript 4.3 via `babel-ts` ([#10811](https://github.com/prettier/prettier/pull/10811) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + +##### [`override` modifiers in class elements](https://devblogs.microsoft.com/typescript/announcing-typescript-4-3-beta/#override-and-the-noimplicitoverride-flag) + +```ts +class Foo extends { + override method() {} +} +``` + +##### [static index signatures (`[key: KeyType]: ValueType`) in classes](https://devblogs.microsoft.com/typescript/announcing-typescript-4-3-beta/#static-index-signatures) + +```ts +class Foo { + static [key: string]: Bar; +} +``` + +##### [`get` / `set` in type declarations](https://devblogs.microsoft.com/typescript/announcing-typescript-4-3-beta/#separate-write-types-on-properties) + +```ts +interface Foo { + set foo(value); + get foo(): string; +} +``` + +### Flow + +#### Fix missing semicolon in `declare export * from …` ([#9767](https://github.com/prettier/prettier/pull/9767) by [@fisker](https://github.com/fisker)) + + + + +```jsx +// Input +declare export * from "ES6_ExportAllFrom_Source2"; + +// Prettier 2.2 +declare export * from "ES6_ExportAllFrom_Source2" + +// Prettier 2.3 +declare export * from "ES6_ExportAllFrom_Source2"; +``` + +#### Support `this` type annotation in functions via `babel-flow` ([#10397](https://github.com/prettier/prettier/pull/10397) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + +`this` type annotation is supported since [Babel 7.13](https://babeljs.io/blog/2021/02/22/7.13.0#new-flow-features-12193httpsgithubcombabelbabelpull12193-12234httpsgithubcombabelbabelpull12234). + +```js +// Input +var foo: (this: boolean) => void; + +// Prettier 2.2 +SyntaxError: Unexpected token, expected ")" (1:15) + +// Prettier 2.3 +var foo: (this: boolean) => void; + +``` + +#### Fix range formatting issues ([#10505](https://github.com/prettier/prettier/pull/10505) by [@thorn0](https://github.com/thorn0)) + +Prettier had trouble formatting some ranges in function declarations. `SyntaxError` was thrown. Prettier 2.3 formats these cases without errors. Examples of problematic ranges are shown below: + + +```jsx +declare export function graphql> + // ^^^^^ range 1 + (query: GQLDocument, config?: Config>): + (Component: Component) => React$ComponentType<$Diff, { + data: Object|void, + // ^^^^ range 2 + mutate: Function|void + }>> +``` + +#### Support for Flow's indexed access type ([#10594](https://github.com/prettier/prettier/pull/10594) by [@gkz](https://github.com/gkz)) + + +```js +// Input +const x: Obj['foo'] = 1; + +// Prettier 2.2 +// Error: unsupported node type "IndexedAccessType" + +// Prettier 2.3 +const x: Obj["foo"] = 1; +``` + +#### Support for Flow's optional indexed access type ([#10788](https://github.com/prettier/prettier/pull/10788) by [@gkz](https://github.com/gkz)) + + +```js +// Input +type T = Obj?.['foo']; + +// Prettier 2.2 +// Error: unsupported node type "OptionalIndexedAccessType" + +// Prettier 2.3 +type T = Obj?.['foo']; +``` + +### JSON + +#### Don't use smart quotes for JSON5 with `--quote-props=preserve` ([#10323](https://github.com/prettier/prettier/pull/10323) by [@thorn0](https://github.com/thorn0)) + +With the `quoteProps` option set to `preserve` and `singleQuotes` to `false` (default), double quotes are always used for printing strings, including situations like `"bla\"bla"`. This effectively allows using `--parser json5` for "JSON with comments and trailing commas". + + +```js +// Input +{ + "char": "\"", +} + +// Prettier 2.2 +{ + "char": '"', +} + +// Prettier 2.3 +{ + "char": "\"", +} +``` + +#### Stricter JSON parser ([#10346](https://github.com/prettier/prettier/pull/10346), [#10443](https://github.com/prettier/prettier/pull/10443), [#10456](https://github.com/prettier/prettier/pull/10456), [#10434](https://github.com/prettier/prettier/pull/10434) by [@fisker](https://github.com/fisker)) + +Prettier internally uses a JavaScript expression parser to parse JSON. That's why the `json` and `json5` parsers used to be very forgiving and allowed all kinds of JavaScript expressions. Now they are much stricter, although some simple non-standard syntax is still allowed (e.g., [JSON6](https://github.com/d3x0r/JSON6) is supported, except for multiple minus signs: `----123`). + + +```js +// Input +[1, 2, 1 + 2] + +// Prettier 2.2 +[1, 2, 1 + 2] + +// Prettier 2.3 +SyntaxError: BinaryExpression is not allowed in JSON. (1:8) +> 1 | [1, 2, 1 + 2] + | ^ +``` + +#### Improve error message ([#10433](https://github.com/prettier/prettier/pull/10433) by [@fisker](https://github.com/fisker)) + + +```js +// Input +{key: "foo" + "bar"} + +// Prettier 2.2 (--parser=json-stringify) +SyntaxError: BinaryExpression is not allowed in JSON. (1:7) +> 1 | {key: "foo" + "bar"} + | ^ + +// Prettier 2.3 +SyntaxError: BinaryExpression is not allowed in JSON. (1:7) +> 1 | {key: "foo" + "bar"} + | ^^^^^^^^^^^^^ +``` + +#### Fix syntax error on JSON range formatting ([#10497](https://github.com/prettier/prettier/pull/10497) by [@fisker](https://github.com/fisker)) + + +```js +// Input +[{ a: 1.0000}, {"b": 2.0000 }] +// ^^^^^^^^^^^ range + +// Prettier 2.2 +SyntaxError: Unexpected token (1:4) +> 1 | "b": 2.0000 + | ^ + +// Prettier 2.3 +[{ a: 1.0000}, { "b": 2.0 }] +``` + +### CSS + +#### Fix absolute path in custom CSS `-custom-url()` calls ([#9966](https://github.com/prettier/prettier/pull/9966) by [@vjeux](https://github.com/vjeux)) + +The CSS parser is parsing this as `["division", "absolute/path"]` instead of a single `"/absolute/path"` token unless you are in a `url()` call. Because we put space after division, it results in an incorrect path. The fix was to avoid printing a space if a division is the first token of a call, which hopefully should be safe. + + +```css +/* Input */ +-custom-url(/absolute/path) + +/* Prettier 2.2 */ +-custom-url(/ absolute/path) + +/* Prettier 2.3 */ +-custom-url(/absolute/path) +``` + +#### Exclude `@keyframes` params from being parsed as a Less variable ([#10773](https://github.com/prettier/prettier/pull/10773) by [@tmazeika](https://github.com/tmazeika)) + + +```css +/* Input */ +@keyframes :global(spin) { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +/* Prettier 2.2 */ +@keyframes: global(spin){ + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +}; + +/* Prettier 2.3 */ +@keyframes :global(spin) { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} +``` + +### SCSS + +#### Fix broken comment inside parens ([#9710](https://github.com/prettier/prettier/pull/9710) by [@fisker](https://github.com/fisker)) + + +```scss +// Input +.simplification { + foo: ( + calc() // not a comment anymore + ); +} + +// Prettier 2.2 +.simplification { + foo: (calc() // not a comment anymore); +} + +// Prettier 2.3 +.simplification { + foo: ( + calc() // not a comment anymore + ); +} +``` + +#### Fix maps with keys that are lists or maps ([#10005](https://github.com/prettier/prettier/pull/10005) by [@fisker](https://github.com/fisker)) + + +```scss +// Input +$map: ( + ('my list'): 'hello world', +); + +// Prettier 2.2 +TypeError: Cannot read property 'length' of undefined + +// Prettier 2.3 +$map: ( + ("my list"): "hello world", +); +``` + +### Ember / Handlebars + +#### Preserve tilde comments ([#9082](https://github.com/prettier/prettier/pull/9082) by [@kangax](https://github.com/kangax), [@fisker](https://github.com/fisker)) + + +```hbs +{{!-- Input --}} +{{~! Comment }} +{{! Comment ~}} +{{~! Comment ~}} + +{{!-- Prettier 2.2 --}} +{{! Comment }} +{{! Comment }} +{{! Comment }} + +{{!-- Prettier 2.3 --}} +{{~! Comment }} +{{! Comment ~}} +{{~! Comment ~}} +``` + +#### Add a whitespace sensitive mode ([#9885](https://github.com/prettier/prettier/pull/9885) by [@dcyriller](https://github.com/dcyriller)) + +```sh +--html-whitespace-sensitivity strict +``` + + +```hbs +{{!-- Input --}} +123 {{mustache}} + +123 {{mustache}} +123 {{mustache}} + + +123 {{mustache}} + + +{{!-- Prettier 2.2 --}} + + 123 {{mustache}} + + + 123 {{mustache}} + + + 123 {{mustache}} + + + 123 {{mustache}} + + +{{!-- Prettier 2.3 --}} +123 {{mustache}} + + 123 + {{mustache}} +123 + {{mustache}} + + + 123 + {{mustache}} + +``` + +#### Print final `blockParam` on its own line ([#9978](https://github.com/prettier/prettier/pull/9978) by [@dcyriller](https://github.com/dcyriller)) + + +```hbs +{{!-- Input --}} + +{{#block param hashKey=hashValue hashKey=hashValue hashKey=hashValue as |blockParam|}} + Hello +{{/block}} + +{{!-- Prettier 2.2 --}} + +{{#block + param + hashKey=hashValue + hashKey=hashValue + hashKey=hashValue as |blockParam| +}} + Hello +{{/block}} + +{{!-- Prettier 2.3 --}} + +{{#block + param + hashKey=hashValue + hashKey=hashValue + hashKey=hashValue + as |blockParam| +}} + Hello +{{/block}} +``` + +#### Fix formatting of attributes ([#10145](https://github.com/prettier/prettier/pull/10145) by [@thorn0](https://github.com/thorn0)) + +- fix escaping of `{{` in attributes and text +- fix the choice between `'` and `"` for attributes with interpolations +- fix the bug with `[object Object]` printed in the `class` attribute +- implement simple formatting for the `class` attribute, like Prettier formatted it in HTML before v2.3.0 + + +```hbs +{{!-- Input --}} +
+
+
+ +{{!-- Prettier 2.2 --}} +
+
+
+ +{{!-- Prettier 2.3 --}} +
+
+
+``` + +#### Split text content on multiple lines ([#10179](https://github.com/prettier/prettier/pull/10179) by [@dcyriller](https://github.com/dcyriller)) + + +```handlebars +{{!-- Input --}} +
+ A long enough string to trigger a line break that would prevent wrapping more and more. +
+ +{{!-- Prettier 2.2 --}} +
+ A long enough string to trigger a line break that would prevent wrapping more and more. +
+ +{{!-- Prettier 2.3 --}} +
+ A long enough string to trigger a line break that would prevent wrapping more + and more. +
+``` + +#### Preserve numeric character references ([#10550](https://github.com/prettier/prettier/pull/10550) by [@rwjblue](https://github.com/rwjblue) and [@thorn0](https://github.com/thorn0)) + + +```hbs +{{! Input }} + + +{{! Prettier 2.2 }} + + +{{! Prettier 2.3 }} + +``` + +#### Do not break opening mustache and path ([#10586](https://github.com/prettier/prettier/pull/10586) by [@dcyriller](https://github.com/dcyriller)) + + +```handlebars +{{!-- Input --}} + + + +{{!-- Prettier 2.2 --}} + + + +{{!-- Prettier 2.3 --}} + + +``` + +### GraphQL + +#### Fix missing space after keyword in anonymous operations ([#10689](https://github.com/prettier/prettier/pull/10689) by [@patriscus](https://github.com/patriscus)) + + +```graphql +# Input +query ($unnamed: String) { + id +} + +# Prettier 2.2 +query($unnamed: String) { + id +} + +# Prettier 2.3 +query ($unnamed: String) { + id +} +``` + +### Markdown + +#### Fix extra newline at the end of JavaScript fenced code block with string literal ([#9736](https://github.com/prettier/prettier/pull/9736) by [@fisker](https://github.com/fisker)) + + +````markdown + +Markdown + +```js +"· " +``` + + +Markdown + +```js +"· "; + +``` + + +Markdown + +```js +"· "; +``` +```` + +#### Fix empty front matter formatting ([#9791](https://github.com/prettier/prettier/pull/9791) by [@fisker](https://github.com/fisker)) + + +```markdown + +--- +--- + +# Title + +a|b|c| +|:--|:-:|--:| +|d|e|f| + +--- + +text + + +--- +--- +# Title + +a|b|c| +|:--|:-:|--:| +|d|e|f| +--- + +text + + +--- +--- + +# Title + +| a | b | c | +| :-- | :-: | --: | +| d | e | f | + +--- + +text +``` + +#### Support YAML document end marker in front matter ([#9878](https://github.com/prettier/prettier/pull/9878) by [@michaelbeaumont](https://github.com/michaelbeaumont)) + +Add the ability to delimit the end of front matter with `...`. + + +```markdown + +--- +title: Hello +slug: home +... + +Markdown + + +--- + +title: Hello +slug: home +... + +Markdown + + +--- +title: Hello +slug: home +... + +Markdown +``` + +### YAML + +#### Fix SyntaxError incorrectly thrown on anchors followed by empty lines ([#10516](https://github.com/prettier/prettier/pull/10516) by [@eemeli](https://github.com/eemeli) & [@thorn0](https://github.com/thorn0)) + +Prettier couldn't parse this valid YAML. Thanks to Eemeli Aro for fixing this bug in the underlying parser. + + +```yaml +# Input +key1: &default + + subkey1: value1 + +key2: + <<: *default + +# Prettier 2.2 +SyntaxError: Nested mappings are not allowed in compact mappings (1:7) + +# Prettier 2.3 +key1: &default + subkey1: value1 + +key2: + <<: *default +``` + +### API + +#### Treat `.prettierrc` as YAML when formatting it ([#8105](https://github.com/prettier/prettier/pull/8105) by [@fisker](https://github.com/fisker)) + +The `.prettierrc` file can be written in either JSON or YAML. Previously, when Prettier formatted it, the parser was inferred to be `json`, which lead to a `SyntaxError` thrown if the content was YAML. Now it’s treated as a YAML file. However, if it's JSON, it will be formatted as JSON (not as JSON-like YAML). + +#### Use arrays instead of `concat` ([#9733](https://github.com/prettier/prettier/pull/9733) by [@fisker](https://github.com/fisker), [@thorn0](https://github.com/thorn0)) + +To simplify the code of AST printers, the data structure for the concatenation command has been changed from `{ type: 'concat', parts: Doc[] }` to `Doc[]`. The old format is deprecated, but for compatibility, the doc printer still supports it, and `doc.builders.concat` (as well as some other builder functions) will keep using it until the next major version of Prettier. + +If you're a plugin author, this change should only concern you if your plugin introspects or modifies composed docs. If it happens to be the case, please make your plugin compatible with future versions of Prettier by tweaking the introspecting code to support the new format. There also is an off-chance where this change can break things, namely if a plugin calls another plugin to [print an embedded language](https://prettier.io/docs/en/plugins.html#optional-embed) and then introspects the returned doc. There seems to be no reason for plugins to do that though. + +To replace `concat(…)` calls in your plugins, you can try auto-fix by this ESLint rule [`prettier-doc/no-concat`](https://github.com/fisker/eslint-plugin-prettier-doc#no-concat). + +```jsx +// Prettier 2.2 +myDoc = group(concat(["foo", line, "bar"])); + +// Prettier 2.3 +myDoc = group(["foo", line, "bar"]); +``` + +#### Fix `lineSuffixBoundary` IR command ([#10122](https://github.com/prettier/prettier/pull/10122) by [@thorn0](https://github.com/thorn0)) + +There was a bug in the implementation of the [`lineSuffixBoundary`][lsb] command that significantly limited its usefulness: the printer algorithm didn't correctly consider it a potential line break. Now that the bug has been fixed, we urge plugin authors to give this command another try and see if it can help them simplify printing of trailing comments. + +[lsb]: https://github.com/prettier/prettier/blob/main/commands.md#linesuffixboundary + + +```jsx +// Input +group([ + "let foo = [", + indent([ + softline, + [lineSuffixBoundary, "item1,"], + line, + [lineSuffixBoundary, "item2,", lineSuffix(" // comment")], + line, + [lineSuffixBoundary, "item3"], + ]), + softline, + "];", +]) + +// Prettier 2.2 +let foo = [item1, item2, // comment + item3]; + +// Prettier 2.3 +let foo = [ + item1, + item2, // comment + item3 +]; +``` + +#### Add `indentIfBreak` IR command ([#10221](https://github.com/prettier/prettier/pull/10221) by [@thorn](https://github.com/thorn)) + +`indentIfBreak(doc, { groupId })` is an optimized version of `ifBreak(indent(doc), doc, { groupId })`. + +#### Simplified `print` callback ([#10557](https://github.com/prettier/prettier/pull/10557) by [@fisker](https://github.com/fisker)) + +The third argument of the `print` method of plugin printers (the `print` callback) has been updated. Its first argument can be a string or an array of strings now. + +To print the current node, call `print` without arguments: + +```diff + function print(path, options, print) { + const parts = []; + path.each((childPath) => { +- parts.push(print(childPath)); ++ parts.push(print()); + }, "children"); + return parts; + } +``` + +To print a property of the current node, use `"property"` or `["property"]`: + +```diff + function print(path, options, print) { +- return path.call(print, "property"); ++ return print("property"); + } +``` + +To print a sub-property of the current node, use `["property1", "property2"]`: + +```diff + function print(path, options, print) { + // print `node.child.child` +- return path.call(print, "child", "child"); ++ return print(["child", "child"]); + } +``` + +See also an example in the [docs](https://prettier.io/docs/en/plugins.html#print). + +### CLI + +#### Add CLI option to prevent errors on unmatched pattern ([#10058](https://github.com/prettier/prettier/pull/10058) by [@daronmcintosh](https://github.com/daronmcintosh)) + +The Prettier CLI will no longer display an error when no files match the glob pattern passed as input. + +```sh +# Prettier 2.2 +$ npx prettier --check "prettier/docs/*.yaml" +Checking formatting... +[error] No files matching the pattern were found: "prettier/docs/*.yaml". +All matched files use Prettier code style! + +# Prettier 2.3 +$ npx prettier --check --no-error-on-unmatched-pattern "prettier/docs/*.yaml" +Checking formatting... +All matched files use Prettier code style! +``` + +#### Add CLI flag for debugging comment attachment issues ([#10124](https://github.com/prettier/prettier/pull/10124) by [@thorn0](https://github.com/thorn0)) + +A new `--debug-print-comments` CLI flag and corresponding functionality for the Playground. + +#### Round-trippable `--debug-print-doc` ([#10169](https://github.com/prettier/prettier/pull/10169), [#10177](https://github.com/prettier/prettier/pull/10177) by [@thorn0](https://github.com/thorn0)) + +The idea is to make the output of `--debug-print-doc` closer to actual code for generating docs (Prettier's intermediate representation). Ideally, it should be possible for it to work without modification after copy-pasting into a JS file. That ideal hasn't probably been reached by this PR, but it's pretty close. This is going to make `--debug-print-doc` and the corresponding part of the Playground a bit more useful. + +#### Print an error message when `--find-config-path` can't find config file ([#10208](https://github.com/prettier/prettier/pull/10208) by [@fisker](https://github.com/fisker)) + +```console +# Prettier 2.2 +$ prettier --find-config-path /prettier.js +# Silently failed + +# Prettier 2.3 +$ prettier --find-config-path /prettier.js +[error] Can not find configure file for "/prettier.js" +``` + +#### Clear printed long filenames of formatting file ([#10217](https://github.com/prettier/prettier/pull/10217) by [@fisker](https://github.com/fisker)) + + +```console +# Prettier 2.2 +$ prettier tests/flow-repo/config_module_system_node_resolve_dirname --check +Checking formatting... +tests\flow-repo\config_module_system_node_resolve_dirname\custom_resolve_dir\tes +tests\flow-repo\config_module_system_node_resolve_dirname\custom_resolve_dir\tes +tests\flow-repo\config_module_system_node_resolve_dirname\subdir\custom_resolve_ +All matched files use Prettier code style! + +# Prettier 2.3 +$ prettier tests/flow-repo/config_module_system_node_resolve_dirname --check +Checking formatting... +All matched files use Prettier code style! +``` + +#### Don't skip file paths containing special words like `constructor` ([#10256](https://github.com/prettier/prettier/pull/10256) by [@ashlkv](https://github.com/ashlkv)) + +Directories whose names happened to coincide with the properties of `Object.prototype` were ignored by Prettier CLI because of a classic bug (introduced in Prettier 2.0.0) with object properties not being checked for being own. + + +```console +# Prettier 2.2 +$ prettier "js/constructor/*.js" --write +[error] No matching files. Patterns: js/constructor/*.js + +# Prettier 2.3 +$ prettier "js/constructor/*.js" --write +js/constructor/test.js 42ms +``` diff --git a/website/blog/assets/github-diff-ternary-in-jsx.png b/website/blog/assets/github-diff-ternary-in-jsx.png deleted file mode 100644 index d96837f9ba..0000000000 Binary files a/website/blog/assets/github-diff-ternary-in-jsx.png and /dev/null differ diff --git a/website/blog/assets/markdown-list-indent.gif b/website/blog/assets/markdown-list-indent.gif deleted file mode 100644 index b995fc55f2..0000000000 Binary files a/website/blog/assets/markdown-list-indent.gif and /dev/null differ diff --git a/website/blog/assets/markdown-lists.gif b/website/blog/assets/markdown-lists.gif deleted file mode 100644 index 2136137034..0000000000 Binary files a/website/blog/assets/markdown-lists.gif and /dev/null differ diff --git a/website/blog/assets/markdown-tables.gif b/website/blog/assets/markdown-tables.gif deleted file mode 100644 index 3d5296a984..0000000000 Binary files a/website/blog/assets/markdown-tables.gif and /dev/null differ diff --git a/website/blog/assets/prettier-revolution-conf.png b/website/blog/assets/prettier-revolution-conf.png deleted file mode 100644 index 3ed6cc3d38..0000000000 Binary files a/website/blog/assets/prettier-revolution-conf.png and /dev/null differ diff --git a/website/core/Footer.js b/website/core/Footer.js deleted file mode 100644 index 32a4f5abdb..0000000000 --- a/website/core/Footer.js +++ /dev/null @@ -1,96 +0,0 @@ -"use strict"; - -const React = require("react"); -const PropTypes = require("prop-types"); - -const GithubButton = (props) => ( -
- Star - -); - -GithubButton.propTypes = { - config: PropTypes.object, -}; - -class Footer extends React.Component { - url(path) { - const language = this.props.language || "en"; - return `${this.props.config.baseUrl}docs/${language}${path}`; - } - - usersUrl() { - const language = this.props.language || "en"; - return `${this.props.config.baseUrl}${language}/users`; - } - - render() { - return ( -
- ); - } -} - -Footer.propTypes = { - language: PropTypes.string, - config: PropTypes.object, -}; - -module.exports = Footer; diff --git a/website/package.json b/website/package.json index c775bb3f6b..22d9a40cea 100644 --- a/website/package.json +++ b/website/package.json @@ -7,7 +7,7 @@ }, "dependencies": { "clipboard": "2.0.8", - "codemirror-graphql": "1.0.1", + "codemirror-graphql": "1.0.2", "lz-string": "1.4.4", "prop-types": "15.7.2", "react": "17.0.2", @@ -17,10 +17,10 @@ "@babel/preset-react": "7.13.13", "@sandhose/prettier-animated-logo": "1.0.3", "babel-loader": "8.2.2", - "concurrently": "6.1.0", + "concurrently": "6.2.0", "docusaurus": "1.14.7", "js-yaml": "4.1.0", - "webpack": "5.36.2", + "webpack": "5.38.1", "webpack-cli": "4.7.0" } } diff --git a/website/pages/en/help/index.js b/website/pages/en/help/index.js deleted file mode 100755 index ce9059eda8..0000000000 --- a/website/pages/en/help/index.js +++ /dev/null @@ -1,46 +0,0 @@ -"use strict"; - -const React = require("react"); -const { Container, GridBlock } = require("../../../core/CompLibrary.js"); - -class Help extends React.Component { - render() { - const supportLinks = [ - { - content: - "Learn more using the [documentation on this site.](/docs/en/why-prettier.html)\n", - title: "Browse Docs", - }, - { - content: "Ask questions about the documentation and project\n", - title: "Join the community", - }, - { - content: "Find out what's new with this project\n", - title: "Stay up to date", - }, - ]; - - return ( -
-
- -
-
-

Need help?

-
-

This project is maintained by a dedicated group of people;

- -
-
-
-
- ); - } -} - -Help.defaultProps = { - language: "en", -}; - -module.exports = Help; diff --git a/website/pages/en/index.js b/website/pages/en/index.js old mode 100755 new mode 100644 index 61af4cde7e..8b28b18f64 --- a/website/pages/en/index.js +++ b/website/pages/en/index.js @@ -312,7 +312,7 @@ const UsersSection = ({ language }) => {

More than{" "} - 2.3 million{" "} + 2.8 million{" "} dependent repositories on GitHub