Repository: prettier/prettier (JavaScript)
Date: 2018-02-15 10:12:56+00:00
Task type: Bug Fix

Issue:
PostCSS @nest wrong output
**Prettier 1.10.2**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEA6GBLGAbOACYAHSjzwAEo4BnGPJAc2wgCMBDbACgAsBGASgBkBYqVJswAa3oAnCAFcoAEyR5pcRQG4ReAL7EdIADQgIAB0zQqyUK2myA7gAVbCKylYA3CBkVGQrGmQAM3YqOGNmaVZJOBgAZVNojCh6ZBhpOXCQRQgwYNCs5LDpGEco+gBbVnzsMOMAKyoADwAhKJj41gq4ABlkuBq6kzkYUxGAJkGsxOli5BAqMCorY1NpZJgAdR8YLmQADgAGVdkwzajTebXqOGkPAeM1AEc5DDUy1krqpBDarLCKhg0hl-slGHAAIpyCDwKbGGCsZjbRS7ZDjeFRDDYMEAYQgFSq8yg0AeIDkYQAKoi3L8wjodEA)
```sh
--parser scss
```

**Input:**
```scss
.title {
  @nest :global(h1)& {
    background: red;
  }
}
```

**Output:**
```scss
.title {
  @nest :global(h1) & {
    background: red;
  }
}

```

**Expected behavior:**
```scss
div {
  @nest :global(h1)& {
    background: red;
  }
}
```

This is crucial because without the extra space the result is:
```css
h1.title {}
```
With the extra space the result is:
```css
h1 .title {}
```
http://cssnext.io/features/#nesting


Issue discussion:
For now I'm using `prettier-ignore`.
@igor-ribeiro Thanks for issue, WIP

Solution patch:
diff --git a/src/language-css/parser-postcss.js b/src/language-css/parser-postcss.js
index df8d250a4b18..570fc1f61e27 100644
--- a/src/language-css/parser-postcss.js
+++ b/src/language-css/parser-postcss.js
@@ -314,7 +314,7 @@ function parseNestedCSS(node) {
         return node;
       }
 
-      if (node.name === "extend") {
+      if (node.name === "extend" || node.name === "nest") {
         node.selector = parseSelector(node.params);
         delete node.params;
 


Test patch:
diff --git a/tests/css_modules/__snapshots__/jsfmt.spec.js.snap b/tests/css_modules/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
index 000000000000..8f399af54da6
--- /dev/null
+++ b/tests/css_modules/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,16 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`modules.css 1`] = `
+.title {
+  @nest :global(h1)& {
+    background: red;
+  }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.title {
+  @nest :global(h1)& {
+    background: red;
+  }
+}
+
+`;
diff --git a/tests/css_modules/jsfmt.spec.js b/tests/css_modules/jsfmt.spec.js
new file mode 100644
index 000000000000..7d3726c81147
--- /dev/null
+++ b/tests/css_modules/jsfmt.spec.js
@@ -0,0 +1,1 @@
+run_spec(__dirname, ["css"]);
diff --git a/tests/css_modules/modules.css b/tests/css_modules/modules.css
new file mode 100644
index 000000000000..d8152fccddcf
--- /dev/null
+++ b/tests/css_modules/modules.css
@@ -0,0 +1,5 @@
+.title {
+  @nest :global(h1)& {
+    background: red;
+  }
+}
diff --git a/tests/css_postcss_plugins/__snapshots__/jsfmt.spec.js.snap b/tests/css_postcss_plugins/__snapshots__/jsfmt.spec.js.snap
index c6952830c719..2a376b4acbe5 100644
--- a/tests/css_postcss_plugins/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/css_postcss_plugins/__snapshots__/jsfmt.spec.js.snap
@@ -132,3 +132,402 @@ exports[`postcss-nested-props.css 1`] = `
 }
 
 `;
+
+exports[`postcss-nesting.css 1`] = `
+a {
+  order: 1;
+  @nest b & {
+    order: 2;
+  }
+  @nest c & {
+    order: 3;
+  }
+  @nest d & {
+    order: 4;
+  }
+  @nest e & {
+    order: 5;
+  }
+}
+a {
+  order: 1;
+  @nest & b {
+    order: 2;
+  }
+  @nest & c {
+    order: 3;
+  }
+  @nest & d {
+    order: 4;
+  }
+  @nest & e {
+    order: 5;
+  }
+}
+
+.rule-1 {
+  order: 1;
+  @media screen, print {
+    order: 2;
+    &.rule-2 {
+      order: 3;
+      @media (max-width: 30em) {
+        order: 4;
+        @nest .rule-prefix & {
+          order: 5;
+        }
+        order: 6;
+      }
+      order: 7;
+    }
+    order: 8;
+  }
+  order: 9;
+}
+
+a, b {
+  order: 1;
+  & c, & d {
+    order: 2;
+    & e, & f {
+      order: 3;
+    }
+    order: 4;
+  }
+  order: 5;
+}
+a, b {
+  order: 1;
+  @nest & c, & d {
+    order: 2;
+    @nest & e, & f {
+      order: 3;
+    }
+    order: 4;
+  }
+  order: 5;
+}
+
+a {
+  & b {
+    & c {
+      order: 1;
+    }
+  }
+}
+d {
+  order: 2;
+  & e {
+    order: 3;
+  }
+}
+f {
+  & g {
+    order: 4;
+  }
+  order: 5;
+}
+a {
+  @nest & b {
+    @nest & c {
+      order: 1;
+    }
+  }
+}
+d {
+  order: 2;
+  @nest & e {
+    order: 3;
+  }
+}
+f {
+  @nest & g {
+    order: 4;
+  }
+  order: 5;
+}
+
+a, b {
+  order: 1;
+  c, d {
+    order: 2;
+  }
+}
+& e {
+  order: 3;
+}
+f {
+  & g & {
+    order: 4;
+  }
+  &h {
+    order: 5;
+  }
+}
+a, b {
+  order: 1;
+  @nest c, d {
+    order: 2;
+  }
+}
+@nest & e {
+  order: 3;
+}
+f {
+  @nest & g & {
+    order: 4;
+  }
+  @nest &h {
+    order: 5;
+  }
+}
+
+a {
+  order: 1;
+  @media (min-width: 100px) {
+    order: 2;
+    @media (max-width: 200px) {
+      order: 3;
+    }
+    & b {
+      @media (max-width: 200px) {
+        order: 4;
+      }
+    }
+  }
+  @media screen, print and speech {
+    @media (max-width: 300px), (min-aspect-ratio: 16/9) {
+      order: 5;
+      & c {
+        order: 6;
+      }
+    }
+  }
+}
+a {
+  order: 1;
+  @media (min-width: 100px) {
+    order: 2;
+    @media (max-width: 200px) {
+      order: 3;
+    }
+    @nest & b {
+      @media (max-width: 200px) {
+        order: 4;
+      }
+    }
+  }
+  @media screen, print and speech {
+    @media (max-width: 300px), (min-aspect-ratio: 16/9) {
+      order: 5;
+      @nest & c {
+        order: 6;
+      }
+    }
+  }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+a {
+  order: 1;
+  @nest b & {
+    order: 2;
+  }
+  @nest c & {
+    order: 3;
+  }
+  @nest d & {
+    order: 4;
+  }
+  @nest e & {
+    order: 5;
+  }
+}
+a {
+  order: 1;
+  @nest & b {
+    order: 2;
+  }
+  @nest & c {
+    order: 3;
+  }
+  @nest & d {
+    order: 4;
+  }
+  @nest & e {
+    order: 5;
+  }
+}
+
+.rule-1 {
+  order: 1;
+  @media screen, print {
+    order: 2;
+    &.rule-2 {
+      order: 3;
+      @media (max-width: 30em) {
+        order: 4;
+        @nest .rule-prefix & {
+          order: 5;
+        }
+        order: 6;
+      }
+      order: 7;
+    }
+    order: 8;
+  }
+  order: 9;
+}
+
+a,
+b {
+  order: 1;
+  & c,
+  & d {
+    order: 2;
+    & e,
+    & f {
+      order: 3;
+    }
+    order: 4;
+  }
+  order: 5;
+}
+a,
+b {
+  order: 1;
+  @nest & c,
+    & d {
+    order: 2;
+    @nest & e,
+      & f {
+      order: 3;
+    }
+    order: 4;
+  }
+  order: 5;
+}
+
+a {
+  & b {
+    & c {
+      order: 1;
+    }
+  }
+}
+d {
+  order: 2;
+  & e {
+    order: 3;
+  }
+}
+f {
+  & g {
+    order: 4;
+  }
+  order: 5;
+}
+a {
+  @nest & b {
+    @nest & c {
+      order: 1;
+    }
+  }
+}
+d {
+  order: 2;
+  @nest & e {
+    order: 3;
+  }
+}
+f {
+  @nest & g {
+    order: 4;
+  }
+  order: 5;
+}
+
+a,
+b {
+  order: 1;
+  c,
+  d {
+    order: 2;
+  }
+}
+& e {
+  order: 3;
+}
+f {
+  & g & {
+    order: 4;
+  }
+  &h {
+    order: 5;
+  }
+}
+a,
+b {
+  order: 1;
+  @nest c,
+    d {
+    order: 2;
+  }
+}
+@nest & e {
+  order: 3;
+}
+f {
+  @nest & g & {
+    order: 4;
+  }
+  @nest &h {
+    order: 5;
+  }
+}
+
+a {
+  order: 1;
+  @media (min-width: 100px) {
+    order: 2;
+    @media (max-width: 200px) {
+      order: 3;
+    }
+    & b {
+      @media (max-width: 200px) {
+        order: 4;
+      }
+    }
+  }
+  @media screen, print and speech {
+    @media (max-width: 300px), (min-aspect-ratio: 16/9) {
+      order: 5;
+      & c {
+        order: 6;
+      }
+    }
+  }
+}
+a {
+  order: 1;
+  @media (min-width: 100px) {
+    order: 2;
+    @media (max-width: 200px) {
+      order: 3;
+    }
+    @nest & b {
+      @media (max-width: 200px) {
+        order: 4;
+      }
+    }
+  }
+  @media screen, print and speech {
+    @media (max-width: 300px), (min-aspect-ratio: 16/9) {
+      order: 5;
+      @nest & c {
+        order: 6;
+      }
+    }
+  }
+}
+
+`;
diff --git a/tests/css_postcss_plugins/postcss-nesting.css b/tests/css_postcss_plugins/postcss-nesting.css
new file mode 100644
index 000000000000..f2c278d42674
--- /dev/null
+++ b/tests/css_postcss_plugins/postcss-nesting.css
@@ -0,0 +1,192 @@
+a {
+  order: 1;
+  @nest b & {
+    order: 2;
+  }
+  @nest c & {
+    order: 3;
+  }
+  @nest d & {
+    order: 4;
+  }
+  @nest e & {
+    order: 5;
+  }
+}
+a {
+  order: 1;
+  @nest & b {
+    order: 2;
+  }
+  @nest & c {
+    order: 3;
+  }
+  @nest & d {
+    order: 4;
+  }
+  @nest & e {
+    order: 5;
+  }
+}
+
+.rule-1 {
+  order: 1;
+  @media screen, print {
+    order: 2;
+    &.rule-2 {
+      order: 3;
+      @media (max-width: 30em) {
+        order: 4;
+        @nest .rule-prefix & {
+          order: 5;
+        }
+        order: 6;
+      }
+      order: 7;
+    }
+    order: 8;
+  }
+  order: 9;
+}
+
+a, b {
+  order: 1;
+  & c, & d {
+    order: 2;
+    & e, & f {
+      order: 3;
+    }
+    order: 4;
+  }
+  order: 5;
+}
+a, b {
+  order: 1;
+  @nest & c, & d {
+    order: 2;
+    @nest & e, & f {
+      order: 3;
+    }
+    order: 4;
+  }
+  order: 5;
+}
+
+a {
+  & b {
+    & c {
+      order: 1;
+    }
+  }
+}
+d {
+  order: 2;
+  & e {
+    order: 3;
+  }
+}
+f {
+  & g {
+    order: 4;
+  }
+  order: 5;
+}
+a {
+  @nest & b {
+    @nest & c {
+      order: 1;
+    }
+  }
+}
+d {
+  order: 2;
+  @nest & e {
+    order: 3;
+  }
+}
+f {
+  @nest & g {
+    order: 4;
+  }
+  order: 5;
+}
+
+a, b {
+  order: 1;
+  c, d {
+    order: 2;
+  }
+}
+& e {
+  order: 3;
+}
+f {
+  & g & {
+    order: 4;
+  }
+  &h {
+    order: 5;
+  }
+}
+a, b {
+  order: 1;
+  @nest c, d {
+    order: 2;
+  }
+}
+@nest & e {
+  order: 3;
+}
+f {
+  @nest & g & {
+    order: 4;
+  }
+  @nest &h {
+    order: 5;
+  }
+}
+
+a {
+  order: 1;
+  @media (min-width: 100px) {
+    order: 2;
+    @media (max-width: 200px) {
+      order: 3;
+    }
+    & b {
+      @media (max-width: 200px) {
+        order: 4;
+      }
+    }
+  }
+  @media screen, print and speech {
+    @media (max-width: 300px), (min-aspect-ratio: 16/9) {
+      order: 5;
+      & c {
+        order: 6;
+      }
+    }
+  }
+}
+a {
+  order: 1;
+  @media (min-width: 100px) {
+    order: 2;
+    @media (max-width: 200px) {
+      order: 3;
+    }
+    @nest & b {
+      @media (max-width: 200px) {
+        order: 4;
+      }
+    }
+  }
+  @media screen, print and speech {
+    @media (max-width: 300px), (min-aspect-ratio: 16/9) {
+      order: 5;
+      @nest & c {
+        order: 6;
+      }
+    }
+  }
+}