Repository: prettier/prettier (JavaScript)
Date: 2020-04-22 03:09:59+00:00
Task type: Bug Fix

Issue:
Comma Dangle error if prettier ignore is set to ignore last property in object
**Prettier 1.15.3**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuc0DOMAEAnOAzXNACwBUIBrBABQEMBPAGwhoBNMBeTYAHSk38ww6ABzhJMAclwE4xMpSgSANLwGY0AVwBG4mEQCWaAHQB9fSxV8B2CAzGCDxm3cv9uMAPQfMw3DBj6cNgAtPoA5lAQuKoCcAAewuKRAO6YANSYABQAbAAMmABUmHmFmABMACylAJy5AJRKmF5ZtZgs9Gh1MQC+ANwgSiAQwgHoyKA02DbJtLhQaMggNABuEOYDIFrYNGCUMADKwjv6UGHIMNgacINEMAC2DADqBvBoR2Bw+who+gHLv3RFmA0AtBic0EEYFRtmE7jRkHgaAwIYMAFZoOIAIW2uzgBxodzgABkTnAEUiUSB0XF9icwnYAIoaCDwcnI64gI7YCHYRZaGhaRjQDa+E4wR7mPTIAAcuUGvggEMe22Ei18siCyzJg1wAEcNPpcNCaLD4UhEezBhC7vpzpcOT9TozmazzRSOTABRKWFKkGVBhcaPoGHSAMIQO5wxaRKDakAaCEkAULN3s7rdIA)
```sh
--parser babylon
```

**Input:**
```jsx
const refreshTokenPayload = {
    type: 'refreshToken',
    sub: this._id,
    role: this.role,
  	// prettier-ignore
    exp: now + (60 * 60 * 24 * 90), // (90 days)
  };
```

**Output:**
```jsx
const refreshTokenPayload = {
  type: "refreshToken",
  sub: this._id,
  role: this.role,
  // prettier-ignore
  exp: now + (60 * 60 * 24 * 90)
};

```

**Expected behavior:**
```jsx
const refreshTokenPayload = {
  type: "refreshToken",
  sub: this._id,
  role: this.role,
  // prettier-ignore
  exp: now + (60 * 60 * 24 * 90), // <-- prettier removes the comma and then the linter blows up
};

```

FYI, I used prettier ignore so I could keep my parentheses https://github.com/prettier/prettier/issues/187


Issue discussion:
Also fails with trailing commas enabled:

**Prettier 1.15.3**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuc0DOMAEAnOAzXNACwBUIBrBABQEMBPAGwhoBNMBeTYAHSk38ww6ABzhJMAclwE4xMpSgSANLwGY0AVwBG4mEQCWaAHQB9fSxV8B2CAzGCDxm3cv9uMAPQfMw3DBj6cNgAtPoA5lAQuKoCcAAewuKRAO6YANSYABQAbAAMmABUmHmFmABMACylAJy5AJRKmF5ZtZgs9Gh1MQC+ANwgSiAQwgHoyKA02DbJtLhQaMggNABuEOYDIFrYNGCUMADKwjv6UGHIMNgacINEMAC2DADqBvBoR2Bw+who+gHLv3RFmA0AtBic0EEYFRtmE7jRkHgaAwIYMAFZoOIAIW2uzgBxodzgABkTnAEUiUSB0XF9icwnYAIoaCDwcnI64gI7YCHYRZaGhaRjQDa+E4wR7mPTIAAcuUGvggEMe22Ei18siCyzJg1wAEcNPpcNCaLD4UhEezBhC7vpzpcOT9TozmazzRSOTABRKWFKkGVBhcaPoGHSAMIQO5wxayACsGw0EJIAoWbvZ3W6QA)
```sh
--parser babylon
--trailing-comma es5
```

**Input:**
```jsx
const refreshTokenPayload = {
    type: 'refreshToken',
    sub: this._id,
    role: this.role,
  	// prettier-ignore
    exp: now + (60 * 60 * 24 * 90), // (90 days)
  };
```

**Output:**
```jsx
const refreshTokenPayload = {
  type: "refreshToken",
  sub: this._id,
  role: this.role,
  // prettier-ignore
  exp: now + (60 * 60 * 24 * 90) // (90 days)
};

```
Maybe related, but when an javascript/typescipt array is formatted, the closing bracket is placed on another line, by itself, and the linter then wants a comma after the last entry.   The linter is actually expecting the closing bracket to be on the same line as the last element.

Personally, I think this is an issue with the linter.   I like the closing bracket on its own line and prefer not to have a comma since there is nothing to separate/delineate after the last element.   But that probably gets into a battle of personal preferences.

Still, it would be nice to be able to tell prettier where closing delimiters should be placed, after last line/element/property, etc or on a line of its own.
@rcollette That seems unrelated to this issue. Regarding linters, we recommend turning all conflicting rules off. See https://prettier.io/docs/en/eslint.html. 
I'm seeing this bug too, in a file with this content:

    export default {
      // prettier-ignore
      protagonist: "  0\r\n" +
                   "0 00\r\n" +
                   "00000\r\n" +
                   "0 0\r\n" +
                   "0 0",

      // prettier-ignore
      wall: "00000\r\n" +
            "00000\r\n" +
            "00000\r\n" +
            "00000\r\n" +
            "00000",

      // prettier-ignore
      cheese: "0\r\n" +
              " 0\r\n" +
              "000\r\n" +
              "00 0\r\n" +
              "00000",

      // prettier-ignore
      enemy: "0   0\r\n" +
             "00 00\r\n" +
             "00000\r\n" +
             "0 0 0\r\n" +
             "00000",

      // prettier-ignore
      home: "00000\r\n" +
            "0   0\r\n" +
            "0   0\r\n" +
            "0   0\r\n" +
            "00000",

      // prettier-ignore
      dog: "00 00\r\n" +
           "00000\r\n" +
           "0   0\r\n" +
           "0 0 0\r\n" +
           " 000 "
    }

I have `trailingComma: true` in my `.prettierrc` file, and it works correctly for every other file in the project. In fact, it even works in this file, as long as I do one of two things that I don't want to do and shouldn't need to do.

1) Add another, non-`prettier-ignore` property, before the end of the item, like this:

        export default {
          // ...

          // prettier-ignore
          dog: "00 00\r\n" +
               "00000\r\n" +
               "0   0\r\n" +
               "0 0 0\r\n" +
               " 000 ",

          foo: "bar",
        }

In this case, since the last item does not have `prettier-ignore` on it, the bug is avoided. This is not acceptable because it should not be necessary to pollute the code with dummy variables in order to get normalized formatting.

2) Remove `prettier-ignore` from the last item, like this:

        export default {
          // ...

          dog: "00 00\r\n" + "00000\r\n" + "0   0\r\n" + "0 0 0\r\n" + " 000 ",
        }

In this case, since the last item does not have `prettier-ignore` on it, the bug is avoided. This is not acceptable because it destroys the intentionally weird formatting that `prettier-ignore` should preserve.
I am facing the same problem......

Solution patch:
diff --git a/changelog_unreleased/javascript/pr-8111.md b/changelog_unreleased/javascript/pr-8111.md
new file mode 100644
index 000000000000..6f41418c00e2
--- /dev/null
+++ b/changelog_unreleased/javascript/pr-8111.md
@@ -0,0 +1,22 @@
+#### Fix object trailing commas that last property is ignored ([#8111](https://github.com/prettier/prettier/pull/8111) by [@fisker](https://github.com/fisker))
+
+<!-- prettier-ignore -->
+```js
+// Input
+const foo = {
+  // prettier-ignore
+  bar: "baz"
+}
+
+// Prettier stable
+const foo = {
+  // prettier-ignore
+  bar: "baz"
+};
+
+// Prettier master
+const foo = {
+  // prettier-ignore
+  bar: "baz",
+};
+```
diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js
index 04cd50234150..ac716a767dd5 100644
--- a/src/language-js/printer-estree.js
+++ b/src/language-js/printer-estree.js
@@ -1399,8 +1399,7 @@ function printPathNoParens(path, options, print, args) {
 
       const canHaveTrailingSeparator = !(
         n.inexact ||
-        (lastElem &&
-          (lastElem.type === "RestElement" || hasNodeIgnoreComment(lastElem)))
+        (lastElem && lastElem.type === "RestElement")
       );
 
       let content;


Test patch:
diff --git a/tests/object_property_ignore/__snapshots__/jsfmt.spec.js.snap b/tests/object_property_ignore/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
index 000000000000..4a6fa71e98a6
--- /dev/null
+++ b/tests/object_property_ignore/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,665 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`ignore.js - {"trailingComma":"all"} format 1`] = `
+====================================options=====================================
+parsers: ["babel", "flow", "typescript"]
+printWidth: 80
+trailingComma: "all"
+                                                                                | printWidth
+=====================================input======================================
+foo = {
+  // prettier-ignore
+  bar:            1,
+}
+
+foo = {
+  _: '',
+  // prettier-ignore
+  bar:            1,
+}
+
+/* comments */
+foo = {
+  _: '',
+  // prettier-ignore
+  bar:            1,         // comment
+}
+
+foo = {
+  _: '',
+  // prettier-ignore
+  bar:            1,         /* comment */
+}
+
+foo = {
+  _: '',
+  // prettier-ignore
+  bar:            /* comment */          1,
+}
+
+/* RestElement */
+foo = {
+  _: '',
+  // prettier-ignore
+  ...bar,
+}
+
+// Nested
+foo = {
+  baz: {
+  // prettier-ignore
+  foo: [1, 2,    3]
+},
+  // prettier-ignore
+  bar:            1,
+}
+
+=====================================output=====================================
+foo = {
+  // prettier-ignore
+  bar:            1,
+};
+
+foo = {
+  _: "",
+  // prettier-ignore
+  bar:            1,
+};
+
+/* comments */
+foo = {
+  _: "",
+  // prettier-ignore
+  bar:            1, // comment
+};
+
+foo = {
+  _: "",
+  // prettier-ignore
+  bar:            1 /* comment */,
+};
+
+foo = {
+  _: "",
+  // prettier-ignore
+  bar:            /* comment */          1,
+};
+
+/* RestElement */
+foo = {
+  _: "",
+  // prettier-ignore
+  ...bar,
+};
+
+// Nested
+foo = {
+  baz: {
+    // prettier-ignore
+    foo: [1, 2,    3],
+  },
+  // prettier-ignore
+  bar:            1,
+};
+
+================================================================================
+`;
+
+exports[`ignore.js - {"trailingComma":"none"} format 1`] = `
+====================================options=====================================
+parsers: ["babel", "flow", "typescript"]
+printWidth: 80
+trailingComma: "none"
+                                                                                | printWidth
+=====================================input======================================
+foo = {
+  // prettier-ignore
+  bar:            1,
+}
+
+foo = {
+  _: '',
+  // prettier-ignore
+  bar:            1,
+}
+
+/* comments */
+foo = {
+  _: '',
+  // prettier-ignore
+  bar:            1,         // comment
+}
+
+foo = {
+  _: '',
+  // prettier-ignore
+  bar:            1,         /* comment */
+}
+
+foo = {
+  _: '',
+  // prettier-ignore
+  bar:            /* comment */          1,
+}
+
+/* RestElement */
+foo = {
+  _: '',
+  // prettier-ignore
+  ...bar,
+}
+
+// Nested
+foo = {
+  baz: {
+  // prettier-ignore
+  foo: [1, 2,    3]
+},
+  // prettier-ignore
+  bar:            1,
+}
+
+=====================================output=====================================
+foo = {
+  // prettier-ignore
+  bar:            1
+};
+
+foo = {
+  _: "",
+  // prettier-ignore
+  bar:            1
+};
+
+/* comments */
+foo = {
+  _: "",
+  // prettier-ignore
+  bar:            1 // comment
+};
+
+foo = {
+  _: "",
+  // prettier-ignore
+  bar:            1 /* comment */
+};
+
+foo = {
+  _: "",
+  // prettier-ignore
+  bar:            /* comment */          1
+};
+
+/* RestElement */
+foo = {
+  _: "",
+  // prettier-ignore
+  ...bar
+};
+
+// Nested
+foo = {
+  baz: {
+    // prettier-ignore
+    foo: [1, 2,    3]
+  },
+  // prettier-ignore
+  bar:            1
+};
+
+================================================================================
+`;
+
+exports[`ignore.js format 1`] = `
+====================================options=====================================
+parsers: ["babel", "flow", "typescript"]
+printWidth: 80
+                                                                                | printWidth
+=====================================input======================================
+foo = {
+  // prettier-ignore
+  bar:            1,
+}
+
+foo = {
+  _: '',
+  // prettier-ignore
+  bar:            1,
+}
+
+/* comments */
+foo = {
+  _: '',
+  // prettier-ignore
+  bar:            1,         // comment
+}
+
+foo = {
+  _: '',
+  // prettier-ignore
+  bar:            1,         /* comment */
+}
+
+foo = {
+  _: '',
+  // prettier-ignore
+  bar:            /* comment */          1,
+}
+
+/* RestElement */
+foo = {
+  _: '',
+  // prettier-ignore
+  ...bar,
+}
+
+// Nested
+foo = {
+  baz: {
+  // prettier-ignore
+  foo: [1, 2,    3]
+},
+  // prettier-ignore
+  bar:            1,
+}
+
+=====================================output=====================================
+foo = {
+  // prettier-ignore
+  bar:            1,
+};
+
+foo = {
+  _: "",
+  // prettier-ignore
+  bar:            1,
+};
+
+/* comments */
+foo = {
+  _: "",
+  // prettier-ignore
+  bar:            1, // comment
+};
+
+foo = {
+  _: "",
+  // prettier-ignore
+  bar:            1 /* comment */,
+};
+
+foo = {
+  _: "",
+  // prettier-ignore
+  bar:            /* comment */          1,
+};
+
+/* RestElement */
+foo = {
+  _: "",
+  // prettier-ignore
+  ...bar,
+};
+
+// Nested
+foo = {
+  baz: {
+    // prettier-ignore
+    foo: [1, 2,    3],
+  },
+  // prettier-ignore
+  bar:            1,
+};
+
+================================================================================
+`;
+
+exports[`issue-5678.js - {"trailingComma":"all"} format 1`] = `
+====================================options=====================================
+parsers: ["babel", "flow", "typescript"]
+printWidth: 80
+trailingComma: "all"
+                                                                                | printWidth
+=====================================input======================================
+// #5678
+const refreshTokenPayload = {
+    type: 'refreshToken',
+    sub: this._id,
+    role: this.role,
+  	// prettier-ignore
+    exp: now + (60 * 60 * 24 * 90), // (90 days)
+  };
+
+export default {
+  // prettier-ignore
+  protagonist: "  0\\r\\n" +
+               "0 00\\r\\n" +
+               "00000\\r\\n" +
+               "0 0\\r\\n" +
+               "0 0",
+
+  // prettier-ignore
+  wall: "00000\\r\\n" +
+        "00000\\r\\n" +
+        "00000\\r\\n" +
+        "00000\\r\\n" +
+        "00000",
+
+  // prettier-ignore
+  cheese: "0\\r\\n" +
+          " 0\\r\\n" +
+          "000\\r\\n" +
+          "00 0\\r\\n" +
+          "00000",
+
+  // prettier-ignore
+  enemy: "0   0\\r\\n" +
+         "00 00\\r\\n" +
+         "00000\\r\\n" +
+         "0 0 0\\r\\n" +
+         "00000",
+
+  // prettier-ignore
+  home: "00000\\r\\n" +
+        "0   0\\r\\n" +
+        "0   0\\r\\n" +
+        "0   0\\r\\n" +
+        "00000",
+
+  // prettier-ignore
+  dog: "00 00\\r\\n" +
+       "00000\\r\\n" +
+       "0   0\\r\\n" +
+       "0 0 0\\r\\n" +
+       " 000 "
+}
+
+=====================================output=====================================
+// #5678
+const refreshTokenPayload = {
+  type: "refreshToken",
+  sub: this._id,
+  role: this.role,
+  // prettier-ignore
+  exp: now + (60 * 60 * 24 * 90), // (90 days)
+};
+
+export default {
+  // prettier-ignore
+  protagonist: "  0\\r\\n" +
+               "0 00\\r\\n" +
+               "00000\\r\\n" +
+               "0 0\\r\\n" +
+               "0 0",
+
+  // prettier-ignore
+  wall: "00000\\r\\n" +
+        "00000\\r\\n" +
+        "00000\\r\\n" +
+        "00000\\r\\n" +
+        "00000",
+
+  // prettier-ignore
+  cheese: "0\\r\\n" +
+          " 0\\r\\n" +
+          "000\\r\\n" +
+          "00 0\\r\\n" +
+          "00000",
+
+  // prettier-ignore
+  enemy: "0   0\\r\\n" +
+         "00 00\\r\\n" +
+         "00000\\r\\n" +
+         "0 0 0\\r\\n" +
+         "00000",
+
+  // prettier-ignore
+  home: "00000\\r\\n" +
+        "0   0\\r\\n" +
+        "0   0\\r\\n" +
+        "0   0\\r\\n" +
+        "00000",
+
+  // prettier-ignore
+  dog: "00 00\\r\\n" +
+       "00000\\r\\n" +
+       "0   0\\r\\n" +
+       "0 0 0\\r\\n" +
+       " 000 ",
+};
+
+================================================================================
+`;
+
+exports[`issue-5678.js - {"trailingComma":"none"} format 1`] = `
+====================================options=====================================
+parsers: ["babel", "flow", "typescript"]
+printWidth: 80
+trailingComma: "none"
+                                                                                | printWidth
+=====================================input======================================
+// #5678
+const refreshTokenPayload = {
+    type: 'refreshToken',
+    sub: this._id,
+    role: this.role,
+  	// prettier-ignore
+    exp: now + (60 * 60 * 24 * 90), // (90 days)
+  };
+
+export default {
+  // prettier-ignore
+  protagonist: "  0\\r\\n" +
+               "0 00\\r\\n" +
+               "00000\\r\\n" +
+               "0 0\\r\\n" +
+               "0 0",
+
+  // prettier-ignore
+  wall: "00000\\r\\n" +
+        "00000\\r\\n" +
+        "00000\\r\\n" +
+        "00000\\r\\n" +
+        "00000",
+
+  // prettier-ignore
+  cheese: "0\\r\\n" +
+          " 0\\r\\n" +
+          "000\\r\\n" +
+          "00 0\\r\\n" +
+          "00000",
+
+  // prettier-ignore
+  enemy: "0   0\\r\\n" +
+         "00 00\\r\\n" +
+         "00000\\r\\n" +
+         "0 0 0\\r\\n" +
+         "00000",
+
+  // prettier-ignore
+  home: "00000\\r\\n" +
+        "0   0\\r\\n" +
+        "0   0\\r\\n" +
+        "0   0\\r\\n" +
+        "00000",
+
+  // prettier-ignore
+  dog: "00 00\\r\\n" +
+       "00000\\r\\n" +
+       "0   0\\r\\n" +
+       "0 0 0\\r\\n" +
+       " 000 "
+}
+
+=====================================output=====================================
+// #5678
+const refreshTokenPayload = {
+  type: "refreshToken",
+  sub: this._id,
+  role: this.role,
+  // prettier-ignore
+  exp: now + (60 * 60 * 24 * 90) // (90 days)
+};
+
+export default {
+  // prettier-ignore
+  protagonist: "  0\\r\\n" +
+               "0 00\\r\\n" +
+               "00000\\r\\n" +
+               "0 0\\r\\n" +
+               "0 0",
+
+  // prettier-ignore
+  wall: "00000\\r\\n" +
+        "00000\\r\\n" +
+        "00000\\r\\n" +
+        "00000\\r\\n" +
+        "00000",
+
+  // prettier-ignore
+  cheese: "0\\r\\n" +
+          " 0\\r\\n" +
+          "000\\r\\n" +
+          "00 0\\r\\n" +
+          "00000",
+
+  // prettier-ignore
+  enemy: "0   0\\r\\n" +
+         "00 00\\r\\n" +
+         "00000\\r\\n" +
+         "0 0 0\\r\\n" +
+         "00000",
+
+  // prettier-ignore
+  home: "00000\\r\\n" +
+        "0   0\\r\\n" +
+        "0   0\\r\\n" +
+        "0   0\\r\\n" +
+        "00000",
+
+  // prettier-ignore
+  dog: "00 00\\r\\n" +
+       "00000\\r\\n" +
+       "0   0\\r\\n" +
+       "0 0 0\\r\\n" +
+       " 000 "
+};
+
+================================================================================
+`;
+
+exports[`issue-5678.js format 1`] = `
+====================================options=====================================
+parsers: ["babel", "flow", "typescript"]
+printWidth: 80
+                                                                                | printWidth
+=====================================input======================================
+// #5678
+const refreshTokenPayload = {
+    type: 'refreshToken',
+    sub: this._id,
+    role: this.role,
+  	// prettier-ignore
+    exp: now + (60 * 60 * 24 * 90), // (90 days)
+  };
+
+export default {
+  // prettier-ignore
+  protagonist: "  0\\r\\n" +
+               "0 00\\r\\n" +
+               "00000\\r\\n" +
+               "0 0\\r\\n" +
+               "0 0",
+
+  // prettier-ignore
+  wall: "00000\\r\\n" +
+        "00000\\r\\n" +
+        "00000\\r\\n" +
+        "00000\\r\\n" +
+        "00000",
+
+  // prettier-ignore
+  cheese: "0\\r\\n" +
+          " 0\\r\\n" +
+          "000\\r\\n" +
+          "00 0\\r\\n" +
+          "00000",
+
+  // prettier-ignore
+  enemy: "0   0\\r\\n" +
+         "00 00\\r\\n" +
+         "00000\\r\\n" +
+         "0 0 0\\r\\n" +
+         "00000",
+
+  // prettier-ignore
+  home: "00000\\r\\n" +
+        "0   0\\r\\n" +
+        "0   0\\r\\n" +
+        "0   0\\r\\n" +
+        "00000",
+
+  // prettier-ignore
+  dog: "00 00\\r\\n" +
+       "00000\\r\\n" +
+       "0   0\\r\\n" +
+       "0 0 0\\r\\n" +
+       " 000 "
+}
+
+=====================================output=====================================
+// #5678
+const refreshTokenPayload = {
+  type: "refreshToken",
+  sub: this._id,
+  role: this.role,
+  // prettier-ignore
+  exp: now + (60 * 60 * 24 * 90), // (90 days)
+};
+
+export default {
+  // prettier-ignore
+  protagonist: "  0\\r\\n" +
+               "0 00\\r\\n" +
+               "00000\\r\\n" +
+               "0 0\\r\\n" +
+               "0 0",
+
+  // prettier-ignore
+  wall: "00000\\r\\n" +
+        "00000\\r\\n" +
+        "00000\\r\\n" +
+        "00000\\r\\n" +
+        "00000",
+
+  // prettier-ignore
+  cheese: "0\\r\\n" +
+          " 0\\r\\n" +
+          "000\\r\\n" +
+          "00 0\\r\\n" +
+          "00000",
+
+  // prettier-ignore
+  enemy: "0   0\\r\\n" +
+         "00 00\\r\\n" +
+         "00000\\r\\n" +
+         "0 0 0\\r\\n" +
+         "00000",
+
+  // prettier-ignore
+  home: "00000\\r\\n" +
+        "0   0\\r\\n" +
+        "0   0\\r\\n" +
+        "0   0\\r\\n" +
+        "00000",
+
+  // prettier-ignore
+  dog: "00 00\\r\\n" +
+       "00000\\r\\n" +
+       "0   0\\r\\n" +
+       "0 0 0\\r\\n" +
+       " 000 ",
+};
+
+================================================================================
+`;
diff --git a/tests/object_property_ignore/ignore.js b/tests/object_property_ignore/ignore.js
new file mode 100644
index 000000000000..7c0a535f97c7
--- /dev/null
+++ b/tests/object_property_ignore/ignore.js
@@ -0,0 +1,46 @@
+foo = {
+  // prettier-ignore
+  bar:            1,
+}
+
+foo = {
+  _: '',
+  // prettier-ignore
+  bar:            1,
+}
+
+/* comments */
+foo = {
+  _: '',
+  // prettier-ignore
+  bar:            1,         // comment
+}
+
+foo = {
+  _: '',
+  // prettier-ignore
+  bar:            1,         /* comment */
+}
+
+foo = {
+  _: '',
+  // prettier-ignore
+  bar:            /* comment */          1,
+}
+
+/* RestElement */
+foo = {
+  _: '',
+  // prettier-ignore
+  ...bar,
+}
+
+// Nested
+foo = {
+  baz: {
+  // prettier-ignore
+  foo: [1, 2,    3]
+},
+  // prettier-ignore
+  bar:            1,
+}
diff --git a/tests/object_property_ignore/issue-5678.js b/tests/object_property_ignore/issue-5678.js
new file mode 100644
index 000000000000..f39b4f32730a
--- /dev/null
+++ b/tests/object_property_ignore/issue-5678.js
@@ -0,0 +1,52 @@
+// #5678
+const refreshTokenPayload = {
+    type: 'refreshToken',
+    sub: this._id,
+    role: this.role,
+  	// prettier-ignore
+    exp: now + (60 * 60 * 24 * 90), // (90 days)
+  };
+
+export default {
+  // prettier-ignore
+  protagonist: "  0\r\n" +
+               "0 00\r\n" +
+               "00000\r\n" +
+               "0 0\r\n" +
+               "0 0",
+
+  // prettier-ignore
+  wall: "00000\r\n" +
+        "00000\r\n" +
+        "00000\r\n" +
+        "00000\r\n" +
+        "00000",
+
+  // prettier-ignore
+  cheese: "0\r\n" +
+          " 0\r\n" +
+          "000\r\n" +
+          "00 0\r\n" +
+          "00000",
+
+  // prettier-ignore
+  enemy: "0   0\r\n" +
+         "00 00\r\n" +
+         "00000\r\n" +
+         "0 0 0\r\n" +
+         "00000",
+
+  // prettier-ignore
+  home: "00000\r\n" +
+        "0   0\r\n" +
+        "0   0\r\n" +
+        "0   0\r\n" +
+        "00000",
+
+  // prettier-ignore
+  dog: "00 00\r\n" +
+       "00000\r\n" +
+       "0   0\r\n" +
+       "0 0 0\r\n" +
+       " 000 "
+}
diff --git a/tests/object_property_ignore/jsfmt.spec.js b/tests/object_property_ignore/jsfmt.spec.js
new file mode 100644
index 000000000000..67d7fda657b9
--- /dev/null
+++ b/tests/object_property_ignore/jsfmt.spec.js
@@ -0,0 +1,5 @@
+const parser = ["babel", "flow", "typescript"];
+
+run_spec(__dirname, parser /*, { trailingComma: "es5" }*/);
+run_spec(__dirname, parser, { trailingComma: "none" });
+run_spec(__dirname, parser, { trailingComma: "all" });