+
+
+
+ >
+/>;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/binary-expressions/relational-operators.js b/crates/rome_js_formatter/tests/specs/prettier/jsx/binary-expressions/relational-operators.js
new file mode 100644
index 00000000000..41d6bcc8b72
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/binary-expressions/relational-operators.js
@@ -0,0 +1,19 @@
+(
) < 5;
+
> 5;
+(
) < 5;
+
> 5;
+
+
<= 5;
+
>= 5;
+
<= 5;
+
>= 5;
+
+(
) <
;
+
>
;
+(
) <
;
+
>
;
+
+
<=
;
+
>=
;
+
<=
;
+
>=
;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/binary-expressions/relational-operators.js.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/binary-expressions/relational-operators.js.prettier-snap
new file mode 100644
index 00000000000..41d6bcc8b72
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/binary-expressions/relational-operators.js.prettier-snap
@@ -0,0 +1,19 @@
+(
) < 5;
+
> 5;
+(
) < 5;
+
> 5;
+
+
<= 5;
+
>= 5;
+
<= 5;
+
>= 5;
+
+(
) <
;
+
>
;
+(
) <
;
+
>
;
+
+
<=
;
+
>=
;
+
<=
;
+
>=
;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/do/do.js b/crates/rome_js_formatter/tests/specs/prettier/jsx/do/do.js
new file mode 100644
index 00000000000..7890763ee5b
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/do/do.js
@@ -0,0 +1,5 @@
+
+ {do {
+ 1
+ }}
+
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/do/do.js.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/do/do.js.prettier-snap
new file mode 100644
index 00000000000..e3b5f2b7896
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/do/do.js.prettier-snap
@@ -0,0 +1,5 @@
+
+ {do {
+ 1;
+ }}
+
;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/do/do.js.snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/do/do.js.snap
new file mode 100644
index 00000000000..b08a2e5f23a
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/do/do.js.snap
@@ -0,0 +1,61 @@
+---
+source: crates/rome_js_formatter/tests/prettier_tests.rs
+info:
+ test_file: jsx/do/do.js
+---
+
+# Input
+
+```js
+
+ {do {
+ 1
+ }}
+
+```
+
+
+# Prettier differences
+
+```diff
+--- Prettier
++++ Rome
+@@ -1,5 +1,5 @@
+
+ {do {
+- 1;
++ 1
+ }}
+-
;
++
+```
+
+# Output
+
+```js
+
+ {do {
+ 1
+ }}
+
+```
+
+
+# Errors
+```
+error[SyntaxError]: expected `}` but instead found `do`
+ ┌─ do.js:2:4
+ │
+2 │ {do {
+ │ ^^ unexpected
+
+error: Unexpected token. Did you mean `{'}'}` or `}`?
+ ┌─ do.js:4:4
+ │
+4 │ }}
+ │ ^
+
+
+```
+
+
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/escape/escape.js b/crates/rome_js_formatter/tests/specs/prettier/jsx/escape/escape.js
new file mode 100644
index 00000000000..db12ce51b7a
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/escape/escape.js
@@ -0,0 +1 @@
+<
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/escape/escape.js.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/escape/escape.js.prettier-snap
new file mode 100644
index 00000000000..167cd46e48d
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/escape/escape.js.prettier-snap
@@ -0,0 +1 @@
+<
;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/escape/nbsp.js b/crates/rome_js_formatter/tests/specs/prettier/jsx/escape/nbsp.js
new file mode 100644
index 00000000000..87d434f5f84
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/escape/nbsp.js
@@ -0,0 +1,13 @@
+many_nbsp =
+single_nbsp =
+nbsp_with_newline =
+
+
+
+
+many_raw_nbsp =
+many_raw_spaces =
+
+
+amp = foo & bar
+raw_amp = foo & bar
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/escape/nbsp.js.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/escape/nbsp.js.prettier-snap
new file mode 100644
index 00000000000..af7aed664c7
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/escape/nbsp.js.prettier-snap
@@ -0,0 +1,9 @@
+many_nbsp =
;
+single_nbsp =
;
+nbsp_with_newline =
;
+
+many_raw_nbsp =
;
+many_raw_spaces =
;
+
+amp = foo & bar ;
+raw_amp = foo & bar ;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/fbt/test.js b/crates/rome_js_formatter/tests/specs/prettier/jsx/fbt/test.js
new file mode 100644
index 00000000000..1cc594b1957
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/fbt/test.js
@@ -0,0 +1,115 @@
+x =
+
+
+ First
+ ,
+
+ Second
+
+
+
+x =
+
+
+ First
+
+ ,
+
+ Second
+
+
+
+x =
+
+ First ,Second
+
+
+x =
+
+
+ First
+ ,
+ Second
+
+
+
+x =
+
+ Prefix comes before
+
+
+ suffix
+
+
+
+
+x =
+
+ Prefix comes before
+
+
+ suffix
+
+
+
+
+ suffix
+
+
+
+
+x =
+
+ Count Chocula knows the the number
+
+ is awesome
+
+
+x = (
+
+ {hour}:{minute}:{second}
+
+);
+
+x = (
+
+ {hour}
+ :
+ {minute}
+ :
+ {second}
+
+);
+
+x = (
+
+ {hour}:
+ {minute}:
+ {second}
+
+);
+
+first = (
+
+ Text
+ More text
+ And more
+
+);
+
+second = (
+
+ Text More text And more
+
+);
+
+third = (
+
+ Text
+
+ More text
+
+ And more
+
+
+);
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/fbt/test.js.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/fbt/test.js.prettier-snap
new file mode 100644
index 00000000000..cf87039fe74
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/fbt/test.js.prettier-snap
@@ -0,0 +1,104 @@
+x = (
+
+ First ,
+ Second
+
+);
+
+x = (
+
+ First
+ ,
+ Second
+
+);
+
+x = (
+
+ First ,Second
+
+);
+
+x = (
+
+ First ,Second
+
+);
+
+x = (
+
+ Prefix comes before
+
+ suffix
+
+
+);
+
+x = (
+
+ Prefix comes before
+
+ suffix
+
+
+ suffix
+
+
+);
+
+x = (
+
+ Count Chocula knows the the number
+
+ is awesome
+
+);
+
+x = (
+
+ {hour}:{minute}:{second}
+
+);
+
+x = (
+
+ {hour}
+ :
+ {minute}
+ :
+ {second}
+
+);
+
+x = (
+
+ {hour}:
+ {minute}:
+ {second}
+
+);
+
+first = (
+
+ Text
+ More text
+ And more
+
+);
+
+second = (
+
+ Text More text And more
+
+);
+
+third = (
+
+ Text
+
+ More text
+
+ And more
+
+
+);
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/fbt/test.js.snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/fbt/test.js.snap
new file mode 100644
index 00000000000..ca247636882
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/fbt/test.js.snap
@@ -0,0 +1,281 @@
+---
+source: crates/rome_js_formatter/tests/prettier_tests.rs
+info:
+ test_file: jsx/fbt/test.js
+---
+
+# Input
+
+```js
+x =
+
+
+ First
+ ,
+
+ Second
+
+
+
+x =
+
+
+ First
+
+ ,
+
+ Second
+
+
+
+x =
+
+ First ,Second
+
+
+x =
+
+
+ First
+ ,
+ Second
+
+
+
+x =
+
+ Prefix comes before
+
+
+ suffix
+
+
+
+
+x =
+
+ Prefix comes before
+
+
+ suffix
+
+
+
+
+ suffix
+
+
+
+
+x =
+
+ Count Chocula knows the the number
+
+ is awesome
+
+
+x = (
+
+ {hour}:{minute}:{second}
+
+);
+
+x = (
+
+ {hour}
+ :
+ {minute}
+ :
+ {second}
+
+);
+
+x = (
+
+ {hour}:
+ {minute}:
+ {second}
+
+);
+
+first = (
+
+ Text
+ More text
+ And more
+
+);
+
+second = (
+
+ Text More text And more
+
+);
+
+third = (
+
+ Text
+
+ More text
+
+ And more
+
+
+);
+```
+
+
+# Prettier differences
+
+```diff
+--- Prettier
++++ Rome
+@@ -80,15 +80,23 @@
+
+ first = (
+
+- Text
+- More text
+- And more
++ Text
++
++ More text
++
++ And more
++
+
+ );
+
+ second = (
+
+- Text More text And more
++ Text
++
++ More text
++
++ And more
++
+
+ );
+
+```
+
+# Output
+
+```js
+x = (
+
+ First ,
+ Second
+
+);
+
+x = (
+
+ First
+ ,
+ Second
+
+);
+
+x = (
+
+ First ,Second
+
+);
+
+x = (
+
+ First ,Second
+
+);
+
+x = (
+
+ Prefix comes before
+
+ suffix
+
+
+);
+
+x = (
+
+ Prefix comes before
+
+ suffix
+
+
+ suffix
+
+
+);
+
+x = (
+
+ Count Chocula knows the the number
+
+ is awesome
+
+);
+
+x = (
+
+ {hour}:{minute}:{second}
+
+);
+
+x = (
+
+ {hour}
+ :
+ {minute}
+ :
+ {second}
+
+);
+
+x = (
+
+ {hour}:
+ {minute}:
+ {second}
+
+);
+
+first = (
+
+ Text
+
+ More text
+
+ And more
+
+
+);
+
+second = (
+
+ Text
+
+ More text
+
+ And more
+
+
+);
+
+third = (
+
+ Text
+
+ More text
+
+ And more
+
+
+);
+```
+
+
+
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/fragment/fragment.js b/crates/rome_js_formatter/tests/specs/prettier/jsx/fragment/fragment.js
new file mode 100644
index 00000000000..c8c4657fd90
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/fragment/fragment.js
@@ -0,0 +1,72 @@
+<>>;
+
+<>
+ text
+>;
+
+<>
+
+
+>;
+
+<>
+ text
+ heading
+ text
+ heading
+ text
+>;
+
+
+ <>
+ <>
+ Hello
+ world
+ >
+ <>
+ Goodbye
+ world
+ >
+ >
+
;
+
+foo = (
+ // comment
+ <>>
+);
+
+* open fragment */>
+
+
+ /* close fragment */>;
+
+< // open fragment
+>
+
+
+ // close fragment
+>;
+
+[<>>, <>>];
+const fun1 = () => <>>;
+x = <>>
+function fun2(param = <>>) {}
+1 + <>>;
+1 || <>>;
+fun2(<>>);
+test ? <>> : x;
+<>>;
+
+ <>>
+ ;
+const obj = {
+ foo: <>>
+};
+const fragmentVar = <>>;
+function fun3() {
+ return <>>;
+}
+(<>>).toString();
+(<>>).props;
+(<>>)["computed"];
+(<>>)["computed"]();
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/fragment/fragment.js.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/fragment/fragment.js.prettier-snap
new file mode 100644
index 00000000000..6c2f55893d6
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/fragment/fragment.js.prettier-snap
@@ -0,0 +1,72 @@
+<>>;
+
+<>text>;
+
+<>
+
+
+>;
+
+<>
+ text
+ heading
+ text
+ heading
+ text
+>;
+
+
+ <>
+ <>
+ Hello
+ world
+ >
+ <>
+ Goodbye
+ world
+ >
+ >
+
;
+
+foo = (
+ // comment
+ <>>
+);
+
+* open fragment */>
+
+
+ /* close fragment */>;
+
+<
+ // open fragment
+>
+
+
+
+ // close fragment
+>;
+
+[<>>, <>>];
+const fun1 = () => <>>;
+x = <>>;
+function fun2(param = <>>) {}
+1 + <>>;
+1 || <>>;
+fun2(<>>);
+test ? <>> : x;
+<>>;
+
+ <>>
+ ;
+const obj = {
+ foo: <>>,
+};
+const fragmentVar = <>>;
+function fun3() {
+ return <>>;
+}
+(<>>).toString();
+(<>>).props;
+(<>>)["computed"];
+(<>>)["computed"]();
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/fragment/fragment.js.snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/fragment/fragment.js.snap
new file mode 100644
index 00000000000..24a6be4d5ab
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/fragment/fragment.js.snap
@@ -0,0 +1,202 @@
+---
+source: crates/rome_js_formatter/tests/prettier_tests.rs
+info:
+ test_file: jsx/fragment/fragment.js
+---
+
+# Input
+
+```js
+<>>;
+
+<>
+ text
+>;
+
+<>
+
+
+>;
+
+<>
+ text
+ heading
+ text
+ heading
+ text
+>;
+
+
+ <>
+ <>
+ Hello
+ world
+ >
+ <>
+ Goodbye
+ world
+ >
+ >
+
;
+
+foo = (
+ // comment
+ <>>
+);
+
+* open fragment */>
+
+
+ /* close fragment */>;
+
+< // open fragment
+>
+
+
+ // close fragment
+>;
+
+[<>>, <>>];
+const fun1 = () => <>>;
+x = <>>
+function fun2(param = <>>) {}
+1 + <>>;
+1 || <>>;
+fun2(<>>);
+test ? <>> : x;
+<>>;
+
+ <>>
+ ;
+const obj = {
+ foo: <>>
+};
+const fragmentVar = <>>;
+function fun3() {
+ return <>>;
+}
+(<>>).toString();
+(<>>).props;
+(<>>)["computed"];
+(<>>)["computed"]();
+```
+
+
+# Prettier differences
+
+```diff
+--- Prettier
++++ Rome
+@@ -28,24 +28,22 @@
+ >
+ ;
+
+-foo = (
+- // comment
+- <>>
+-);
++foo =
++ (
++ // comment
++ <>>
++ );
+
+-* open fragment */>
++< /* open fragment */ >
+
+
+- /* close fragment */>;
++ /* close fragment */ >;
+
+-<
++<>
+ // open fragment
+->
+
+
+-
+- // close fragment
+->;
++>; // close fragment
+
+ [<>>, <>>];
+ const fun1 = () => <>>;
+```
+
+# Output
+
+```js
+<>>;
+
+<>text>;
+
+<>
+
+
+>;
+
+<>
+ text
+ heading
+ text
+ heading
+ text
+>;
+
+
+ <>
+ <>
+ Hello
+ world
+ >
+ <>
+ Goodbye
+ world
+ >
+ >
+
;
+
+foo =
+ (
+ // comment
+ <>>
+ );
+
+< /* open fragment */ >
+
+
+ /* close fragment */ >;
+
+<>
+ // open fragment
+
+
+>; // close fragment
+
+[<>>, <>>];
+const fun1 = () => <>>;
+x = <>>;
+function fun2(param = <>>) {}
+1 + <>>;
+1 || <>>;
+fun2(<>>);
+test ? <>> : x;
+<>>;
+
+ <>>
+ ;
+const obj = {
+ foo: <>>,
+};
+const fragmentVar = <>>;
+function fun3() {
+ return <>>;
+}
+(<>>).toString();
+(<>>).props;
+(<>>)["computed"];
+(<>>)["computed"]();
+```
+
+
+
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/ignore/jsx_ignore.js b/crates/rome_js_formatter/tests/specs/prettier/jsx/ignore/jsx_ignore.js
new file mode 100644
index 00000000000..f540cd8b2a8
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/ignore/jsx_ignore.js
@@ -0,0 +1,56 @@
+// this should remain as-is
+
+ {/* prettier-ignore */}
+
+
;
+
+// this should remain as-is
+
+ {/* prettier-ignore */}
+
+
;
+
+// this should remain as-is
+f(
+
+ {/*prettier-ignore*/}
+
+
+);
+
+// this be formatted
+
+ {/* prettier-ignore */} foo
+
+
;
+
+// this should remain as-is
+
+{
+ /* prettier-ignore */
+ foo ( )
+}
+
;
+
+// this should remain as-is
+
+{
+ /* prettier-ignore */
+ x ? :
+}
+
;
+
+push(
+ // prettier-ignore
+ :)
+ ,
+);
+
+function f() {
+ // rome-ignore format: Instability issue
+ return (
+ // prettier-ignore
+ /* $FlowFixMe(>=0.53.0) */
+
+ );
+}
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/ignore/jsx_ignore.js.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/ignore/jsx_ignore.js.prettier-snap
new file mode 100644
index 00000000000..d90e35e6e80
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/ignore/jsx_ignore.js.prettier-snap
@@ -0,0 +1,55 @@
+// this should remain as-is
+
+ {/* prettier-ignore */}
+
+
;
+
+// this should remain as-is
+
+ {/* prettier-ignore */}
+
+
;
+
+// this should remain as-is
+f(
+
+ {/*prettier-ignore*/}
+
+ ,
+);
+
+// this be formatted
+
+ {/* prettier-ignore */} foo
+
+
;
+
+// this should remain as-is
+
+ {
+ /* prettier-ignore */
+ foo ( )
+ }
+
;
+
+// this should remain as-is
+
+ {
+ /* prettier-ignore */
+ x ? :
+ }
+
;
+
+push(
+ // prettier-ignore
+ :)
+ ,
+);
+
+function f() {
+ return (
+ // prettier-ignore
+ /* $FlowFixMe(>=0.53.0) */
+
+ );
+}
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/ignore/jsx_ignore.js.snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/ignore/jsx_ignore.js.snap
new file mode 100644
index 00000000000..7d74b6711bf
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/ignore/jsx_ignore.js.snap
@@ -0,0 +1,193 @@
+---
+source: crates/rome_js_formatter/tests/prettier_tests.rs
+info:
+ test_file: jsx/ignore/jsx_ignore.js
+---
+
+# Input
+
+```js
+// this should remain as-is
+
+ {/* prettier-ignore */}
+
+
;
+
+// this should remain as-is
+
+ {/* prettier-ignore */}
+
+
;
+
+// this should remain as-is
+f(
+
+ {/*prettier-ignore*/}
+
+
+);
+
+// this be formatted
+
+ {/* prettier-ignore */} foo
+
+
;
+
+// this should remain as-is
+
+{
+ /* prettier-ignore */
+ foo ( )
+}
+
;
+
+// this should remain as-is
+
+{
+ /* prettier-ignore */
+ x ? :
+}
+
;
+
+push(
+ // prettier-ignore
+ :)
+ ,
+);
+
+function f() {
+ // rome-ignore format: Instability issue
+ return (
+ // prettier-ignore
+ /* $FlowFixMe(>=0.53.0) */
+
+ );
+}
+```
+
+
+# Prettier differences
+
+```diff
+--- Prettier
++++ Rome
+@@ -1,20 +1,22 @@
+ // this should remain as-is
+
+ {/* prettier-ignore */}
+-
++
+
;
+
+ // this should remain as-is
+
+ {/* prettier-ignore */}
+-
++
+
;
+
+ // this should remain as-is
+ f(
+
+ {/*prettier-ignore*/}
+-
++
+ ,
+ );
+
+@@ -28,16 +30,15 @@
+
+ {
+ /* prettier-ignore */
+- foo ( )
++ foo ( )
+ }
+
;
+
+ // this should remain as-is
+
+ {
+- /* prettier-ignore */
+- x ? :
+- }
++ /* prettier-ignore */
++ x ? : }
+
;
+
+ push(
+@@ -47,6 +48,7 @@
+ );
+
+ function f() {
++ // rome-ignore format: Instability issue
+ return (
+ // prettier-ignore
+ /* $FlowFixMe(>=0.53.0) */
+```
+
+# Output
+
+```js
+// this should remain as-is
+
+ {/* prettier-ignore */}
+
+
;
+
+// this should remain as-is
+
+ {/* prettier-ignore */}
+
+
;
+
+// this should remain as-is
+f(
+
+ {/*prettier-ignore*/}
+
+ ,
+);
+
+// this be formatted
+
+ {/* prettier-ignore */} foo
+
+
;
+
+// this should remain as-is
+
+ {
+ /* prettier-ignore */
+ foo ( )
+ }
+
;
+
+// this should remain as-is
+
+ {
+ /* prettier-ignore */
+ x ? : }
+
;
+
+push(
+ // prettier-ignore
+ :)
+ ,
+);
+
+function f() {
+ // rome-ignore format: Instability issue
+ return (
+ // prettier-ignore
+ /* $FlowFixMe(>=0.53.0) */
+
+ );
+}
+```
+
+
+
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/multiline-assign/test.js b/crates/rome_js_formatter/tests/specs/prettier/jsx/multiline-assign/test.js
new file mode 100644
index 00000000000..7c3649a6e7c
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/multiline-assign/test.js
@@ -0,0 +1,19 @@
+const comp1 = (
+
+ Keep the wrapping parens.
+
+);
+
+const comp2 =
+ Create wrapping parens.
+
;
+
+comp2A =
+ Create wrapping parens.
+
;
+
+const comp3 = Bump to next line without parens
;
+
+const comp4 = Create wrapping parens and indent all the things .
;
+
+const comp5 = Keep it on one line.
;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/multiline-assign/test.js.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/multiline-assign/test.js.prettier-snap
new file mode 100644
index 00000000000..810b627f7c3
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/multiline-assign/test.js.prettier-snap
@@ -0,0 +1,31 @@
+const comp1 = (
+
+ Keep the wrapping parens.
+
+);
+
+const comp2 = (
+
+ Create wrapping parens.
+
+);
+
+comp2A = (
+
+ Create wrapping parens.
+
+);
+
+const comp3 = (
+
+ Bump to next line without parens
+
+);
+
+const comp4 = (
+
+ Create wrapping parens and indent all the things .
+
+);
+
+const comp5 = Keep it on one line.
;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/namespace/jsx_namespaced_name.js b/crates/rome_js_formatter/tests/specs/prettier/jsx/namespace/jsx_namespaced_name.js
new file mode 100644
index 00000000000..7f4591ee043
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/namespace/jsx_namespaced_name.js
@@ -0,0 +1,3 @@
+ ;
+
+1 ;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/namespace/jsx_namespaced_name.js.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/namespace/jsx_namespaced_name.js.prettier-snap
new file mode 100644
index 00000000000..7f4591ee043
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/namespace/jsx_namespaced_name.js.prettier-snap
@@ -0,0 +1,3 @@
+ ;
+
+1 ;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/newlines/test.js b/crates/rome_js_formatter/tests/specs/prettier/jsx/newlines/test.js
new file mode 100644
index 00000000000..d5fedf9e3ab
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/newlines/test.js
@@ -0,0 +1,94 @@
+keep =
+ Welcome to the Universal React Starter-kyt .
+ This starter kyt should serve as the base for an advanced,
+ server-rendered React app.
+
+
+newlines_text =
+
+ hi
+ there
+ how
+
+ are you
+
+
+ are you fine today?
+
+
+newlines_text_spaced =
+
+
+ space above
+
+ space below
+
+
+
+newlines_elems_spaced =
+
+
+ space above
+
+ space below
+
+
+
+newlines_mixed =
+
+ hi
+ there
+
+ how
+
+ are you
+
+
+ are you fine today?
+
+
+newlines_elems =
+
+
+
+
+ hi
+
+
+
+
+
+
+
+
+
+
+
+
+
+regression_extra_newline = (
+
+
+ New Messages
+
+);
+
+
+regression_extra_newline_2 = (
+
+ (
+
+ )
+
+);
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/newlines/test.js.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/newlines/test.js.prettier-snap
new file mode 100644
index 00000000000..19d48412ee7
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/newlines/test.js.prettier-snap
@@ -0,0 +1,57 @@
+keep = (
+
+ Welcome to the Universal React Starter-kyt . This starter
+ kyt should serve as the base for an advanced, server-rendered React app.
+
+);
+
+newlines_text = hi there how are you are you fine today?
;
+
+newlines_text_spaced = space above space below
;
+
+newlines_elems_spaced = (
+
+ space above
+
+ space below
+
+);
+
+newlines_mixed = (
+
+ hi
+ there
+ how are you
+ are you fine today?
+
+);
+
+newlines_elems = (
+
+);
+
+regression_extra_newline = (
+
+
+ New Messages
+
+);
+
+regression_extra_newline_2 = (
+
+ (
+
+ )
+
+);
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/newlines/test.js.snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/newlines/test.js.snap
new file mode 100644
index 00000000000..6561133b729
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/newlines/test.js.snap
@@ -0,0 +1,193 @@
+---
+source: crates/rome_js_formatter/tests/prettier_tests.rs
+info:
+ test_file: jsx/newlines/test.js
+---
+
+# Input
+
+```js
+keep =
+ Welcome to the Universal React Starter-kyt .
+ This starter kyt should serve as the base for an advanced,
+ server-rendered React app.
+
+
+newlines_text =
+
+ hi
+ there
+ how
+
+ are you
+
+
+ are you fine today?
+
+
+newlines_text_spaced =
+
+
+ space above
+
+ space below
+
+
+
+newlines_elems_spaced =
+
+
+ space above
+
+ space below
+
+
+
+newlines_mixed =
+
+ hi
+ there
+
+ how
+
+ are you
+
+
+ are you fine today?
+
+
+newlines_elems =
+
+
+
+
+ hi
+
+
+
+
+
+
+
+
+
+
+
+
+
+regression_extra_newline = (
+
+
+ New Messages
+
+);
+
+
+regression_extra_newline_2 = (
+
+ (
+
+ )
+
+);
+```
+
+
+# Prettier differences
+
+```diff
+--- Prettier
++++ Rome
+@@ -33,7 +33,9 @@
+
+ hi
+
++
+
++
+
+
+ );
+```
+
+# Output
+
+```js
+keep = (
+
+ Welcome to the Universal React Starter-kyt . This starter
+ kyt should serve as the base for an advanced, server-rendered React app.
+
+);
+
+newlines_text = hi there how are you are you fine today?
;
+
+newlines_text_spaced = space above space below
;
+
+newlines_elems_spaced = (
+
+ space above
+
+ space below
+
+);
+
+newlines_mixed = (
+
+ hi
+ there
+ how are you
+ are you fine today?
+
+);
+
+newlines_elems = (
+
+);
+
+regression_extra_newline = (
+
+
+ New Messages
+
+);
+
+regression_extra_newline_2 = (
+
+ (
+
+ )
+
+);
+```
+
+
+# Lines exceeding max width of 80 characters
+```
+ 45:
+```
+
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/newlines/windows.js b/crates/rome_js_formatter/tests/specs/prettier/jsx/newlines/windows.js
new file mode 100644
index 00000000000..d2b04f35a93
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/newlines/windows.js
@@ -0,0 +1,3 @@
+
+Text
+
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/newlines/windows.js.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/newlines/windows.js.prettier-snap
new file mode 100644
index 00000000000..a51f7aafaa9
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/newlines/windows.js.prettier-snap
@@ -0,0 +1 @@
+Text
;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/significant-space/comments.js b/crates/rome_js_formatter/tests/specs/prettier/jsx/significant-space/comments.js
new file mode 100644
index 00000000000..7a0895dcb44
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/significant-space/comments.js
@@ -0,0 +1,7 @@
+
+ {
+ // TODO: don't harcode this space! not all locales use whitespace
+ // in the same way
+ ' '
+ }
+
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/significant-space/comments.js.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/significant-space/comments.js.prettier-snap
new file mode 100644
index 00000000000..3632e7d413f
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/significant-space/comments.js.prettier-snap
@@ -0,0 +1,7 @@
+
+ {
+ // TODO: don't harcode this space! not all locales use whitespace
+ // in the same way
+ " "
+ }
+
;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/significant-space/test.js b/crates/rome_js_formatter/tests/specs/prettier/jsx/significant-space/test.js
new file mode 100644
index 00000000000..6f25e76bfdb
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/significant-space/test.js
@@ -0,0 +1,74 @@
+after =
+
+ foo bar
+
+
+before =
+
+ bar foo
+
+
+before_break1 =
+
+ foo
+
+
+before_break2 =
+
+ foo
+
+
+after_break =
+
+ foo
+
+
+within =
+
+ foo bar
+
+
+break_components =
+
+
+
+ foobar bar bar
yep
+
+
nope
+
+
+var x =
+ hello hi sdkflsdfjk
+
;
+
+nest_plz =
+
+
+regression_not_transformed_1 =
+ ;
+
+regression_not_transformed_2 =
+ ;
+
+similar_1 =
+ ;
+
+similar_2 =
+ ;
+
+similar_3 =
+ ;
+
+not_broken_end =
+
+ long text long text long text long text long text long text long text long text url long text long text
+
+
+not_broken_begin =
+
+ long text long text long text long text long text long text long text long text url long text long text
+
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/significant-space/test.js.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/significant-space/test.js.prettier-snap
new file mode 100644
index 00000000000..15330365b76
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/significant-space/test.js.prettier-snap
@@ -0,0 +1,117 @@
+after = (
+
+ foo bar
+
+);
+
+before = (
+
+ bar foo
+
+);
+
+before_break1 = (
+
+ {" "}
+ foo
+
+);
+
+before_break2 = (
+
+ {" "}
+ foo
+
+);
+
+after_break = (
+
+ foo{" "}
+
+
+);
+
+within = (
+
+ foo bar
+
+);
+
+break_components = (
+
+
+
+
+ foobar bar bar
+
+
+
+ yep
+
+
+
+
nope
+
+);
+
+var x = (
+
+ hello hi sdkflsdfjk
+
+);
+
+nest_plz = (
+
+);
+
+regression_not_transformed_1 = (
+
+ {" "}
+
+
+);
+
+regression_not_transformed_2 = (
+
+ {" "}
+
+);
+
+similar_1 = (
+
+ {" "}
+
+
+);
+
+similar_2 = (
+
+ {" "}
+
+);
+
+similar_3 = (
+
+
+
+);
+
+not_broken_end = (
+
+ long text long text long text long text long text long text long text long
+ text url long text long text
+
+);
+
+not_broken_begin = (
+
+ long text long text long text long text long text long text long text
+ long text url long text long text
+
+);
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/significant-space/test.js.snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/significant-space/test.js.snap
new file mode 100644
index 00000000000..054555963c5
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/significant-space/test.js.snap
@@ -0,0 +1,290 @@
+---
+source: crates/rome_js_formatter/tests/prettier_tests.rs
+info:
+ test_file: jsx/significant-space/test.js
+---
+
+# Input
+
+```js
+after =
+
+ foo bar
+
+
+before =
+
+ bar foo
+
+
+before_break1 =
+
+ foo
+
+
+before_break2 =
+
+ foo
+
+
+after_break =
+
+ foo
+
+
+within =
+
+ foo bar
+
+
+break_components =
+
+
+
+ foobar bar bar
yep
+
+
nope
+
+
+var x =
+ hello hi sdkflsdfjk
+
;
+
+nest_plz =
+
+
+regression_not_transformed_1 =
+ ;
+
+regression_not_transformed_2 =
+ ;
+
+similar_1 =
+ ;
+
+similar_2 =
+ ;
+
+similar_3 =
+ ;
+
+not_broken_end =
+
+ long text long text long text long text long text long text long text long text url long text long text
+
+
+not_broken_begin =
+
+ long text long text long text long text long text long text long text long text url long text long text
+
+```
+
+
+# Prettier differences
+
+```diff
+--- Prettier
++++ Rome
+@@ -12,7 +12,7 @@
+
+ before_break1 = (
+
+- {" "}
++
+ foo
+
+ );
+@@ -21,15 +21,16 @@
+
+ {" "}
++ />
+ foo
+
+ );
+
+ after_break = (
+
+- foo{" "}
+-
++ foo
+
+ );
+
+@@ -79,7 +80,8 @@
+
+ regression_not_transformed_2 = (
+
+- {" "}
++
++ {" "}
+
+ );
+
+@@ -92,13 +94,15 @@
+
+ similar_2 = (
+
+- {" "}
++
++ {" "}
+
+ );
+
+ similar_3 = (
+
+-
++
++
+
+ );
+
+@@ -111,7 +115,8 @@
+
+ not_broken_begin = (
+
+- long text long text long text long text long text long text long text
+- long text url long text long text
++
++ long text long text long text long text long text long text long text long
++ text url long text long text
+
+ );
+```
+
+# Output
+
+```js
+after = (
+
+ foo bar
+
+);
+
+before = (
+
+ bar foo
+
+);
+
+before_break1 = (
+
+
+ foo
+
+);
+
+before_break2 = (
+
+
+ foo
+
+);
+
+after_break = (
+
+ foo
+
+);
+
+within = (
+
+ foo bar
+
+);
+
+break_components = (
+
+
+
+
+ foobar bar bar
+
+
+
+ yep
+
+
+
+
nope
+
+);
+
+var x = (
+
+ hello hi sdkflsdfjk
+
+);
+
+nest_plz = (
+
+);
+
+regression_not_transformed_1 = (
+
+ {" "}
+
+
+);
+
+regression_not_transformed_2 = (
+
+
+ {" "}
+
+);
+
+similar_1 = (
+
+ {" "}
+
+
+);
+
+similar_2 = (
+
+
+ {" "}
+
+);
+
+similar_3 = (
+
+
+
+
+);
+
+not_broken_end = (
+
+ long text long text long text long text long text long text long text long
+ text url long text long text
+
+);
+
+not_broken_begin = (
+
+
+ long text long text long text long text long text long text long text long
+ text url long text long text
+
+);
+```
+
+
+
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/single-attribute-per-line/single-attribute-per-line.js b/crates/rome_js_formatter/tests/specs/prettier/jsx/single-attribute-per-line/single-attribute-per-line.js
new file mode 100644
index 00000000000..299cb8332aa
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/single-attribute-per-line/single-attribute-per-line.js
@@ -0,0 +1,27 @@
+import React from "react";
+
+const Component = () => (
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+
+
+
+
+
+
+
+
+);
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/single-attribute-per-line/single-attribute-per-line.js.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/single-attribute-per-line/single-attribute-per-line.js.prettier-snap
new file mode 100644
index 00000000000..c447f80ded5
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/single-attribute-per-line/single-attribute-per-line.js.prettier-snap
@@ -0,0 +1,38 @@
+import React from "react";
+
+const Component = () => (
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+
+
+
+
+
+
+
+
+);
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/split-attrs/test.js b/crates/rome_js_formatter/tests/specs/prettier/jsx/split-attrs/test.js
new file mode 100644
index 00000000000..59f3a7a8ae1
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/split-attrs/test.js
@@ -0,0 +1,49 @@
+long_closed =
+
+
+long_open =
+
+ hello
+
+
+long_open_long_children =
+
+
+ Hello world
+
+
+
+
+ d
+
+
+
+short_closed =
+
+
+short_open =
+
+ hello
+
+
+make_self_closing =
+
+
+
+
+
+
+leave_opening =
+
+
+long_string =
+ hello world
+
+long_string_with_extra_param =
+ hello world
+
+// rome-ignore format: Instability issue
+long_obj =
+ hello world
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/split-attrs/test.js.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/split-attrs/test.js.prettier-snap
new file mode 100644
index 00000000000..1a4851d6ae5
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/split-attrs/test.js.prettier-snap
@@ -0,0 +1,170 @@
+long_closed = (
+
+);
+
+long_open = (
+
+ hello
+
+);
+
+long_open_long_children = (
+
+
+ Hello world
+
+
+
+
+
+
+ d
+
+
+
+
+
+);
+
+short_closed = ;
+
+short_open = (
+
+ hello
+
+);
+
+make_self_closing = (
+
+
+
+
+);
+
+leave_opening = (
+
+ {" "}
+
+);
+
+long_string = (
+
+ hello world
+
+);
+
+long_string_with_extra_param = (
+
+ hello world
+
+);
+
+long_obj = (
+
+ hello world
+
+);
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/split-attrs/test.js.snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/split-attrs/test.js.snap
new file mode 100644
index 00000000000..9042378ed7f
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/split-attrs/test.js.snap
@@ -0,0 +1,261 @@
+---
+source: crates/rome_js_formatter/tests/prettier_tests.rs
+info:
+ test_file: jsx/split-attrs/test.js
+---
+
+# Input
+
+```js
+long_closed =
+
+
+long_open =
+
+ hello
+
+
+long_open_long_children =
+
+
+ Hello world
+
+
+
+
+ d
+
+
+
+short_closed =
+
+
+short_open =
+
+ hello
+
+
+make_self_closing =
+
+
+
+
+
+
+leave_opening =
+
+
+long_string =
+ hello world
+
+long_string_with_extra_param =
+ hello world
+
+// rome-ignore format: Instability issue
+long_obj =
+ hello world
+```
+
+
+# Prettier differences
+
+```diff
+--- Prettier
++++ Rome
+@@ -155,16 +155,6 @@
+
+ );
+
+-long_obj = (
+-
+- hello world
+-
+-);
++// rome-ignore format: Instability issue
++long_obj =
++ hello world
+```
+
+# Output
+
+```js
+long_closed = (
+
+);
+
+long_open = (
+
+ hello
+
+);
+
+long_open_long_children = (
+
+
+ Hello world
+
+
+
+
+
+
+ d
+
+
+
+
+
+);
+
+short_closed = ;
+
+short_open = (
+
+ hello
+
+);
+
+make_self_closing = (
+
+
+
+
+);
+
+leave_opening = (
+
+ {" "}
+
+);
+
+long_string = (
+
+ hello world
+
+);
+
+long_string_with_extra_param = (
+
+ hello world
+
+);
+
+// rome-ignore format: Instability issue
+long_obj =
+ hello world
+```
+
+
+# Lines exceeding max width of 80 characters
+```
+ 144:
+ 151: className="i use bootstrap and just put loooaads of classnames in here all the time"
+ 160:
hello world
+```
+
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/spread/attribute.js b/crates/rome_js_formatter/tests/specs/prettier/jsx/spread/attribute.js
new file mode 100644
index 00000000000..2f12f980007
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/spread/attribute.js
@@ -0,0 +1,25 @@
+
;
+
+
;
+
+
;
+
+
;
+
+
;
+
+
;
+
+
;
+
+
;
+
+
;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/spread/attribute.js.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/spread/attribute.js.prettier-snap
new file mode 100644
index 00000000000..a4fa06210ae
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/spread/attribute.js.prettier-snap
@@ -0,0 +1,36 @@
+
;
+
+
;
+
+
;
+
+
;
+
+
;
+
+
;
+
+
;
+
+
;
+
+
;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/spread/attribute.js.snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/spread/attribute.js.snap
new file mode 100644
index 00000000000..39071cb7e1f
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/spread/attribute.js.snap
@@ -0,0 +1,115 @@
+---
+source: crates/rome_js_formatter/tests/prettier_tests.rs
+info:
+ test_file: jsx/spread/attribute.js
+---
+
+# Input
+
+```js
+
;
+
+
;
+
+
;
+
+
;
+
+
;
+
+
;
+
+
;
+
+
;
+
+
;
+```
+
+
+# Prettier differences
+
+```diff
+--- Prettier
++++ Rome
+@@ -9,28 +9,21 @@
+
;
+
+
;
+
+
;
+
+
;
+
+
;
+```
+
+# Output
+
+```js
+
;
+
+
;
+
+
;
+
+
;
+
+
;
+
+
;
+
+
;
+
+
;
+
+
;
+```
+
+
+
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/spread/child.js b/crates/rome_js_formatter/tests/specs/prettier/jsx/spread/child.js
new file mode 100644
index 00000000000..94e59bf6d24
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/spread/child.js
@@ -0,0 +1,23 @@
+
{...a}
;
+
+
{...a /* comment */}
;
+
+
{/* comment */...a}
;
+
+// rome-ignore format: Instability issue
+
{...a //comment
+}
;
+
+
{...a
+ //comment
+}
;
+
+
{
+ //comment
+ ...a
+}
;
+
+// rome-ignore format: Instability issue
+
{//comment
+ ...a // comment
+}
;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/spread/child.js.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/spread/child.js.prettier-snap
new file mode 100644
index 00000000000..fc218066144
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/spread/child.js.prettier-snap
@@ -0,0 +1,32 @@
+
{...a}
;
+
+
{...a /* comment */}
;
+
+
{/* comment */ ...a}
;
+
+
+ {
+ ...a //comment
+ }
+
;
+
+
+ {
+ ...a
+ //comment
+ }
+
;
+
+
+ {
+ //comment
+ ...a
+ }
+
;
+
+
+ {
+ //comment
+ ...a // comment
+ }
+
;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/spread/child.js.snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/spread/child.js.snap
new file mode 100644
index 00000000000..5358e69534a
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/spread/child.js.snap
@@ -0,0 +1,116 @@
+---
+source: crates/rome_js_formatter/tests/prettier_tests.rs
+info:
+ test_file: jsx/spread/child.js
+---
+
+# Input
+
+```js
+
{...a}
;
+
+
{...a /* comment */}
;
+
+
{/* comment */...a}
;
+
+// rome-ignore format: Instability issue
+
{...a //comment
+}
;
+
+
{...a
+ //comment
+}
;
+
+
{
+ //comment
+ ...a
+}
;
+
+// rome-ignore format: Instability issue
+
{//comment
+ ...a // comment
+}
;
+```
+
+
+# Prettier differences
+
+```diff
+--- Prettier
++++ Rome
+@@ -4,29 +4,23 @@
+
+
{/* comment */ ...a}
;
+
+-
+- {
+- ...a //comment
+- }
+-
;
++// rome-ignore format: Instability issue
++
{...a //comment
++}
;
+
+
+- {
+- ...a
+- //comment
++ {...a
++ //comment
+ }
+
;
+
+
+ {
+- //comment
+- ...a
+- }
++ //comment
++ ...a}
+
;
+
+-
+- {
+- //comment
+- ...a // comment
+- }
+-
;
++// rome-ignore format: Instability issue
++
{//comment
++ ...a // comment
++}
;
+```
+
+# Output
+
+```js
+
{...a}
;
+
+
{...a /* comment */}
;
+
+
{/* comment */ ...a}
;
+
+// rome-ignore format: Instability issue
+
{...a //comment
+}
;
+
+
+ {...a
+ //comment
+ }
+
;
+
+
+ {
+ //comment
+ ...a}
+
;
+
+// rome-ignore format: Instability issue
+
{//comment
+ ...a // comment
+}
;
+```
+
+
+
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/stateless-arrow-fn/test.js b/crates/rome_js_formatter/tests/specs/prettier/jsx/stateless-arrow-fn/test.js
new file mode 100644
index 00000000000..2099e5bc09a
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/stateless-arrow-fn/test.js
@@ -0,0 +1,73 @@
+const render1 = ({ styles }) => (
+
+ Keep the wrapping parens. Put each key on its own line.
+
+);
+
+const render2 = ({ styles }) =>
+ Create wrapping parens.
+
;
+
+const render3 = ({ styles }) =>
Create wrapping parens.
;
+
+const render4 = ({ styles }) =>
Create wrapping parens and indent all the things .
;
+
+const render5 = ({ styles }) =>
Keep it on one line.
;
+
+const render6 = ({ styles }) => (
+
+
ddd d dd d d dddd dddd hello
+
ddd d dd d d dddd dddd hello
+
+
ddd d dd d d dddd dddd hello
hello
+
+)
+
+const render7 = () =>
+
+
Dont break each elem onto its own line.
+
+
+
+const render7A = () => (
+
+)
+
+const render7B = () => (
+
+ Dont break plz
+ Dont break plz
+ Dont break plz
+
+)
+
+const render8 = (props) =>
{props.text}
+const render9 = (props) =>
{props.looooooooooooooooooooooooooooooong_text}
+const render10 = (props) =>
{props.even_looooooooooooooooooooooooooooooooooooooooooonger_contents}
+
+const notJSX = (aaaaaaaaaaaaaaaaa, bbbbbbbbbbb) => this.someLongCallWithParams(aaaaaa, bbbbbbb).anotherLongCallWithParams(cccccccccccc, dddddddddddddddddddddd)
+
+React.render(
+
+ , document.querySelector('#react-root')
+)
+
+
+const renderTernary = (props) =>
+
+ {props.showTheThing ?
+ Hello world
+ : "hello " + "howdy! "}
+ {props.showTheThing ?
+ Hello world
+ :
+ null
+ }
+ {props.showTheThing ? null :
+ Hello world
+ }
+ {props.showTheOtherThing ? I am here
:
}
+ {props.showTheOtherThing ? I am here!!
: null}
+
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/stateless-arrow-fn/test.js.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/stateless-arrow-fn/test.js.prettier-snap
new file mode 100644
index 00000000000..7cbcef966ad
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/stateless-arrow-fn/test.js.prettier-snap
@@ -0,0 +1,170 @@
+const render1 = ({ styles }) => (
+
+ Keep the wrapping parens. Put each key on its own line.
+
+);
+
+const render2 = ({ styles }) => (
+
+ Create wrapping parens.
+
+);
+
+const render3 = ({ styles }) => (
+
+ Create wrapping parens.
+
+);
+
+const render4 = ({ styles }) => (
+
+ Create wrapping parens and indent all the things .
+
+);
+
+const render5 = ({ styles }) =>
Keep it on one line.
;
+
+const render6 = ({ styles }) => (
+
+
+ ddd d dd d d dddd dddd hello
+
+
+ ddd d dd d d dddd dddd hello
+
+
+
+ ddd d dd d d dddd dddd hello
+
{" "}
+
hello
+
+
+);
+
+const render7 = () => (
+
+
+
Dont break each elem onto its own line.
+
+
+);
+
+const render7A = () => (
+
+);
+
+const render7B = () => (
+
+
+ {" "}
+ Dont break plz
+
+
+
+ Dont break plz
+
+
+ Dont break plz
+
+
+
+);
+
+const render8 = (props) =>
{props.text}
;
+const render9 = (props) => (
+
{props.looooooooooooooooooooooooooooooong_text}
+);
+const render10 = (props) => (
+
+ {props.even_looooooooooooooooooooooooooooooooooooooooooonger_contents}
+
+);
+
+const notJSX = (aaaaaaaaaaaaaaaaa, bbbbbbbbbbb) =>
+ this.someLongCallWithParams(aaaaaa, bbbbbbb).anotherLongCallWithParams(
+ cccccccccccc,
+ dddddddddddddddddddddd,
+ );
+
+React.render(
+
,
+ document.querySelector("#react-root"),
+);
+
+const renderTernary = (props) => (
+
+ {props.showTheThing ? (
+
+ Hello world
+
+ ) : (
+ "hello " + "howdy! "
+ )}
+ {props.showTheThing ? (
+
+ Hello world
+
+ ) : null}
+ {props.showTheThing ? null : (
+
+ Hello world
+
+ )}
+ {props.showTheOtherThing ? I am here
:
}
+ {props.showTheOtherThing ? I am here!!
: null}
+
+);
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/stateless-arrow-fn/test.js.snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/stateless-arrow-fn/test.js.snap
new file mode 100644
index 00000000000..bd71e968e67
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/stateless-arrow-fn/test.js.snap
@@ -0,0 +1,300 @@
+---
+source: crates/rome_js_formatter/tests/prettier_tests.rs
+info:
+ test_file: jsx/stateless-arrow-fn/test.js
+---
+
+# Input
+
+```js
+const render1 = ({ styles }) => (
+
+ Keep the wrapping parens. Put each key on its own line.
+
+);
+
+const render2 = ({ styles }) =>
+ Create wrapping parens.
+
;
+
+const render3 = ({ styles }) =>
Create wrapping parens.
;
+
+const render4 = ({ styles }) =>
Create wrapping parens and indent all the things .
;
+
+const render5 = ({ styles }) =>
Keep it on one line.
;
+
+const render6 = ({ styles }) => (
+
+
ddd d dd d d dddd dddd hello
+
ddd d dd d d dddd dddd hello
+
+
ddd d dd d d dddd dddd hello
hello
+
+)
+
+const render7 = () =>
+
+
Dont break each elem onto its own line.
+
+
+
+const render7A = () => (
+
+)
+
+const render7B = () => (
+
+ Dont break plz
+ Dont break plz
+ Dont break plz
+
+)
+
+const render8 = (props) =>
{props.text}
+const render9 = (props) =>
{props.looooooooooooooooooooooooooooooong_text}
+const render10 = (props) =>
{props.even_looooooooooooooooooooooooooooooooooooooooooonger_contents}
+
+const notJSX = (aaaaaaaaaaaaaaaaa, bbbbbbbbbbb) => this.someLongCallWithParams(aaaaaa, bbbbbbb).anotherLongCallWithParams(cccccccccccc, dddddddddddddddddddddd)
+
+React.render(
+
+ , document.querySelector('#react-root')
+)
+
+
+const renderTernary = (props) =>
+
+ {props.showTheThing ?
+ Hello world
+ : "hello " + "howdy! "}
+ {props.showTheThing ?
+ Hello world
+ :
+ null
+ }
+ {props.showTheThing ? null :
+ Hello world
+ }
+ {props.showTheOtherThing ? I am here
:
}
+ {props.showTheOtherThing ? I am here!!
: null}
+
+```
+
+
+# Prettier differences
+
+```diff
+--- Prettier
++++ Rome
+@@ -55,7 +55,7 @@
+ attr4
+ >
+ ddd d dd d d dddd dddd
hello
+-
{" "}
++
+ hello
+
+
+@@ -65,7 +65,8 @@
+
+
+
Dont break each elem onto its own line.
+-
++
++
+
+ );
+
+@@ -81,7 +82,8 @@
+
+
+ {" "}
+- Dont break plz
++
++ Dont break plz
+
+
+
+```
+
+# Output
+
+```js
+const render1 = ({ styles }) => (
+
+ Keep the wrapping parens. Put each key on its own line.
+
+);
+
+const render2 = ({ styles }) => (
+
+ Create wrapping parens.
+
+);
+
+const render3 = ({ styles }) => (
+
+ Create wrapping parens.
+
+);
+
+const render4 = ({ styles }) => (
+
+ Create wrapping parens and indent all the things .
+
+);
+
+const render5 = ({ styles }) => Keep it on one line.
;
+
+const render6 = ({ styles }) => (
+
+
+ ddd d dd d d dddd dddd hello
+
+
+ ddd d dd d d dddd dddd hello
+
+
+
+ ddd d dd d d dddd dddd hello
+
+
hello
+
+
+);
+
+const render7 = () => (
+
+
+
Dont break each elem onto its own line.
+
+
+
+);
+
+const render7A = () => (
+
+);
+
+const render7B = () => (
+
+
+ {" "}
+
+ Dont break plz
+
+
+
+ Dont break plz
+
+
+ Dont break plz
+
+
+
+);
+
+const render8 = (props) => {props.text}
;
+const render9 = (props) => (
+ {props.looooooooooooooooooooooooooooooong_text}
+);
+const render10 = (props) => (
+
+ {props.even_looooooooooooooooooooooooooooooooooooooooooonger_contents}
+
+);
+
+const notJSX = (aaaaaaaaaaaaaaaaa, bbbbbbbbbbb) =>
+ this.someLongCallWithParams(aaaaaa, bbbbbbb).anotherLongCallWithParams(
+ cccccccccccc,
+ dddddddddddddddddddddd,
+ );
+
+React.render(
+ ,
+ document.querySelector("#react-root"),
+);
+
+const renderTernary = (props) => (
+
+ {props.showTheThing ? (
+
+ Hello world
+
+ ) : (
+ "hello " + "howdy! "
+ )}
+ {props.showTheThing ? (
+
+ Hello world
+
+ ) : null}
+ {props.showTheThing ? null : (
+
+ Hello world
+
+ )}
+ {props.showTheOtherThing ? I am here
:
}
+ {props.showTheOtherThing ? I am here!!
: null}
+
+);
+```
+
+
+
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/template/styled-components.js b/crates/rome_js_formatter/tests/specs/prettier/jsx/template/styled-components.js
new file mode 100644
index 00000000000..3377c40783a
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/template/styled-components.js
@@ -0,0 +1,18 @@
+;
+
+;
+
+;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/template/styled-components.js.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/template/styled-components.js.prettier-snap
new file mode 100644
index 00000000000..d47d923e3c3
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/template/styled-components.js.prettier-snap
@@ -0,0 +1,19 @@
+;
+
+;
+
+;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/template/styled-components.js.snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/template/styled-components.js.snap
new file mode 100644
index 00000000000..020bfb36ac6
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/template/styled-components.js.snap
@@ -0,0 +1,75 @@
+---
+source: crates/rome_js_formatter/tests/prettier_tests.rs
+info:
+ test_file: jsx/template/styled-components.js
+---
+
+# Input
+
+```js
+;
+
+;
+
+;
+```
+
+
+# Prettier differences
+
+```diff
+--- Prettier
++++ Rome
+@@ -11,9 +11,8 @@
+ `};
+
+ ;
+```
+
+# Output
+
+```js
+;
+
+;
+
+;
+```
+
+
+
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/text-wrap/test.js b/crates/rome_js_formatter/tests/specs/prettier/jsx/text-wrap/test.js
new file mode 100644
index 00000000000..f8cb6255443
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/text-wrap/test.js
@@ -0,0 +1,458 @@
+// Wrapping text
+x =
+
+ Some text that would need to wrap on to a new line in order to display correctly and nicely
+
+
+// Wrapping tags
+x =
+
+ f f f f f f
+
+
+// Wrapping tags
+x =
+
+ f f f f f f
+
+
+// Wrapping tags
+x =
+
+
+
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f
+
+
+// Wrapping tags
+x =
+
+ f
+
+
+x =
+
+ before
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur at mollis lorem.
after
+
+
+x =
+
+ before{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}{stuff}{stuff}after{stuff}after
+
+
+x =
+
+ before {stuff} after {stuff} after {stuff} after {stuff} after {stuff} after {stuff} {stuff} {stuff} after {stuff} after
+
+
+x =
+
+ Please state your name and occupation for the board of school directors.
+
+
+function DiffOverview(props) {
+ const { source, target, since } = props;
+ return (
+
+
+
+ This diff overview is computed against the current list of records in
+ this collection and the list it contained on {humanDate(since)} .
+
+
+ Note: last_modified
and schema
record metadata
+ are omitted for easier review.
+
+
+
+
+ );
+}
+
+x = Starting at minute {graphActivity.startTime}, running for {graphActivity.length} to minute {graphActivity.startTime + graphActivity.length}
+
+x =
+
+ First second third
+
Something
+
+
+x =
+
+
+ First
+
+ Second
+
+ Third
+
+
+
+x =
+
+ First
+ Second
+
Third
+
+
+leading_whitespace =
+ First Second Third Fourth Fifth Sixth Seventh Eighth Ninth Tenth Eleventh Twelfth Thirteenth Fourteenth
+
+trailing_whitespace =
+ First Second Third Fourth Fifth Sixth Seventh Eighth Ninth Tenth Eleventh Twelfth Thirteenth Fourteenth
+
+no_leading_or_trailing_whitespace =
+ First Second Third Fourth Fifth Sixth Seventh Eighth Ninth Tenth Eleventh Twelfth Thirteenth Fourteenth
+
+facebook_translation_leave_text_around_tag =
+
+
+ First
+ ,
+ (
+ Second
+ )
+
+
+x =
+
+
+ First second third fourth fifth sixth seventh
+ ,
+ (
+ Second
+ )
+
+
+this_really_should_split_across_lines =
+
+ before{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after
+
+
+unstable_before =
+
+ Your score: {`${mini.crosstable.users[sessionUserId]} - ${mini.crosstable.users[user.id]}`}
+
+
+unstable_after_first_run = (
+
+ Your score:{" "}
+ {`${mini.crosstable.users[sessionUserId]} - ${mini
+ .crosstable.users[user.id]}`}
+
+);
+
+solitary_whitespace =
+
+
+jsx_whitespace_on_newline =
+
+
+ First
+
+ Second
+
+ Third
+
+
+
+jsx_around_multiline_element =
+ Before
{"Enough text to make this element wrap on to multiple lines when formatting"}
After
+
+jsx_around_multiline_element_second_pass = (
+
+ Before{" "}
+
+ {
+ "Enough text to make this element wrap on to multiple lines when formatting"
+ }
+
{" "}
+ After
+
+);
+
+convert_space_expressions =
+ {" "}
+
+x =
+
+
+
+
+
+
+
+
+
+const Abc = () => {
+ return (
+
+ Please state your
+ {" "}
+ name
+ {" "}
+ and
+ {" "}
+ occupation
+ {" "}
+ for the board of directors.
+
+ );
+};
+
+x = Some stuff here
+
+headers_and_paragraphs = (
+
+
First
+
The first paragraph.
+
+
Second
+
The second paragraph.
+
+);
+
+no_text_one_tag_per_line =
+
+
+
+
+with_text_fill_line =
+
+ Text
+
+
+line_after_br =
+
+ Text
+ More text
+ And more
+
+
+line_after_br =
+
+ Text More text And more
+
+
+line_after_br =
+
+ Text
+
+ More text
+
+ And more
+
+
+
+line_after_br_2 = A B C
+
+br_followed_by_whitespace = text
+
+dont_preserve_blank_lines_when_jsx_contains_text =
+
+
+
Zeroth
+
+
First
+
+ Second
+
+
+
+multiple_expressions =
+
+ {header}
+ {body}
+ {footer}
+
+
+single_expression_child_tags =
+
+ You currently have {dashboardStr} and {userStr}
+
+
+expression_does_not_break =
+ texty text text text text text text text text text text text {this.props.type}
+
+// FIXME
+br_triggers_expression_break =
+
+ text text text text text text text text text text text {this.props.type}
+
+jsx_whitespace_after_tag =
+
+
+ {variable}
+
+ {" "}
+ ({variable})
+
+
+x =
+
+ ENDS IN
+ text text text text text text text text text text text
+
{" "}
+ HRS
+
+
+x =
+
+
Message
+ Hello, I'm a simple message.
+
+
+x =
+
+ Hello, I'm a simple message.
+
Message
+
+
+x =
+
+
+
+
+
+ Line {startRange.row + 1}:{startRange.column + 1} - {endRange.row + 1}:{endRange.column + 1}{caller}
+
+
+
+
+
+
+x =
+
+
+// NOTE: Multiple JSX whitespaces are collapsed into a single space.
+x =
+
+ {" "}{" "}{" "}
+
+
+// Don't break a self-closing element without attributes
+// ----------
+x =
+
+ text text text text text text text text text text text text text text text text text text text text text
+
;
+
+x =
+
+
+ First
+
-
+
+ Second
+
+
+
+x =
+
+
+ First
+
+ -
+
+ Second
+
+
+
+x =
+
+
+x =
+
+
+ First
+
-
+
+ Second
+
+
+
+x =
+
+
+ First
+
+ -
+
+ Second
+
+
+
+x =
+
+
+x =
+
+ {hour}:{minute}:{second}
+
+
+x =
+
+ {hour}
+ :
+ {minute}
+ :
+ {second}
+
+
+x =
+
+ {hour}:
+ {minute}:
+ {second}
+
+
+x = text here .
+
+x = Sales tax estimated using a rate of {salesTax * 100}%.
+
+x =
+ {title}
+
+
+x = bar
+
+x =
+
+ {name} ’s{' '}
+
+ Hello world .
+ You {type}ed this shipment to
+
+
+x =
+ {parameter.Description}: {errorMsg}
+
+
+x =
+ {value} solution{plural}
+
+
+x = Copy "{name}"
+
+x = (avg. {value}/5)
+
+x =
+ Use the Button
's
+
;
+
+this_really_should_split_across_lines =
+
+ before{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after
+
+
+let myDiv = ReactTestUtils.renderIntoDocument(
+
+);
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/text-wrap/test.js.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/text-wrap/test.js.prettier-snap
new file mode 100644
index 00000000000..8d55c7a9103
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/text-wrap/test.js.prettier-snap
@@ -0,0 +1,570 @@
+// Wrapping text
+x = (
+
+ Some text that would need to wrap on to a new line in order to display
+ correctly and nicely
+
+);
+
+// Wrapping tags
+x = (
+
+ f f f f {" "}
+ f f
+
+);
+
+// Wrapping tags
+x = (
+
+ f
+ f
+ f
+ f
+ f
+ f
+
+);
+
+// Wrapping tags
+x = (
+
+
+
+
+
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa {" "}
+
f
+
+);
+
+// Wrapping tags
+x = (
+
+ {" "}
+ f
+
+);
+
+x = (
+
+ before
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur at
+ mollis lorem.
+
+ after
+
+);
+
+x = (
+
+ before{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}
+ {stuff}
+ {stuff}after{stuff}after
+
+);
+
+x = (
+
+ before {stuff} after {stuff} after {stuff} after {stuff} after {stuff} after{" "}
+ {stuff} {stuff} {stuff} after {stuff} after
+
+);
+
+x = (
+
+ Please state your name and occupation for the board of{" "}
+ school directors.
+
+);
+
+function DiffOverview(props) {
+ const { source, target, since } = props;
+ return (
+
+
+
+ This diff overview is computed against the current list of records in
+ this collection and the list it contained on {humanDate(since)}
+ .
+
+
+ Note: last_modified
and schema
record
+ metadata are omitted for easier review.
+
+
+
+
+ );
+}
+
+x = (
+
+
+ Starting at minute {graphActivity.startTime}, running for{" "}
+ {graphActivity.length} to minute{" "}
+ {graphActivity.startTime + graphActivity.length}
+
+
+);
+
+x = (
+
+ First second third
+
+ Something
+
+
+);
+
+x = (
+
+
First
+ Second
+
Third
+
+);
+
+x = (
+
+);
+
+leading_whitespace = (
+
+ {" "}
+ First Second Third Fourth Fifth Sixth Seventh Eighth Ninth Tenth Eleventh
+ Twelfth Thirteenth Fourteenth
+
+);
+
+trailing_whitespace = (
+
+ First Second Third Fourth Fifth Sixth Seventh Eighth Ninth Tenth Eleventh
+ Twelfth Thirteenth Fourteenth{" "}
+
+);
+
+no_leading_or_trailing_whitespace = (
+
+ First Second Third Fourth Fifth Sixth Seventh Eighth Ninth Tenth Eleventh
+ Twelfth Thirteenth Fourteenth
+
+);
+
+facebook_translation_leave_text_around_tag = (
+
+ First , (Second )
+
+);
+
+x = (
+
+ First second third fourth fifth sixth seventh , (
+ Second )
+
+);
+
+this_really_should_split_across_lines = (
+
+ before{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}
+ after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}
+ after{stuff}after{stuff}after
+
+);
+
+unstable_before = (
+
+ Your score:{" "}
+ {`${mini.crosstable.users[sessionUserId]} - ${
+ mini.crosstable.users[user.id]
+ }`}
+
+);
+
+unstable_after_first_run = (
+
+ Your score:{" "}
+ {`${mini.crosstable.users[sessionUserId]} - ${
+ mini.crosstable.users[user.id]
+ }`}
+
+);
+
+solitary_whitespace = (
+
+ {" "}
+
+);
+
+jsx_whitespace_on_newline = (
+
+);
+
+jsx_around_multiline_element = (
+
+ Before{" "}
+
+ {
+ "Enough text to make this element wrap on to multiple lines when formatting"
+ }
+
{" "}
+ After
+
+);
+
+jsx_around_multiline_element_second_pass = (
+
+ Before{" "}
+
+ {
+ "Enough text to make this element wrap on to multiple lines when formatting"
+ }
+
{" "}
+ After
+
+);
+
+convert_space_expressions =
;
+
+x = (
+
+
+
+
+
+
+
+
+);
+
+const Abc = () => {
+ return (
+
+ Please state your name and occupation for the board of
+ directors.
+
+ );
+};
+
+x = Some stuff here
;
+
+headers_and_paragraphs = (
+
+
First
+
The first paragraph.
+
+
Second
+
The second paragraph.
+
+);
+
+no_text_one_tag_per_line = (
+
+
+
+
+);
+
+with_text_fill_line = (
+
+ Text
+
+
+);
+
+line_after_br = (
+
+ Text
+
+ More text
+
+ And more
+
+
+);
+
+line_after_br = (
+
+ Text
+
+ More text
+
+ And more
+
+
+);
+
+line_after_br = (
+
+ Text
+
+ More text
+
+ And more
+
+
+);
+
+line_after_br_2 = (
+
+ A B C
+
+);
+
+br_followed_by_whitespace = (
+
+ text
+
+);
+
+dont_preserve_blank_lines_when_jsx_contains_text = (
+
+
Zeroth
+
First
+ Second
+
+);
+
+multiple_expressions = (
+
+ {header}
+ {body}
+ {footer}
+
+);
+
+single_expression_child_tags = (
+
+ You currently have {dashboardStr} and{" "}
+ {userStr}
+
+);
+
+expression_does_not_break = (
+
+ texty text text text text text text text text text text text{" "}
+ {this.props.type}{" "}
+
+);
+
+// FIXME
+br_triggers_expression_break = (
+
+
+ text text text text text text text text text text text {
+ this.props.type
+ }{" "}
+
+);
+
+jsx_whitespace_after_tag = (
+
+
+ {variable}
+ {" "}
+ ({variable})
+
+);
+
+x = (
+
+ ENDS IN
text text text text text text text text text text text
{" "}
+ HRS
+
+);
+
+x = (
+
+
Message
+ Hello, I'm a simple message.
+
+);
+
+x = (
+
+ Hello, I'm a simple message.
+
Message
+
+);
+
+x = (
+
+
+
+
+
+ Line {startRange.row + 1}:{startRange.column + 1} -{" "}
+ {endRange.row + 1}:{endRange.column + 1}
+ {caller}
+
+
+
+
+
+);
+
+x = (
+
+);
+
+// NOTE: Multiple JSX whitespaces are collapsed into a single space.
+x =
;
+
+// Don't break a self-closing element without attributes
+// ----------
+x = (
+
+ text text text text text text text text text text text text text text text
+
+ text text text text text text
+
+);
+
+x = (
+
+);
+
+x = (
+
+);
+
+x = (
+
+);
+
+x = (
+
+
+ First
+
+ -
+
+ Second
+
+
+);
+
+x = (
+
+
+ First
+
+ -
+
+ Second
+
+
+);
+
+x = (
+
+
+ First
+
+ -
+
+ Second
+
+
+);
+
+x = (
+
+ {hour}:{minute}:{second}
+
+);
+
+x = (
+
+ {hour}:{minute}:{second}
+
+);
+
+x = (
+
+ {hour}:{minute}:{second}
+
+);
+
+x = (
+
+ text here .
+
+);
+
+x = Sales tax estimated using a rate of {salesTax * 100}%.
;
+
+x = {title}
;
+
+x = (
+
+
+ bar
+
+);
+
+x = (
+
+
+ {name} ’s{" "}
+
+ Hello world .
+ You {type}ed this shipment to
+
+);
+
+x = (
+
+ {parameter.Description}: {errorMsg}
+
+);
+
+x = (
+
+ {value} solution{plural}
+
+);
+
+x = Copy "{name}" ;
+
+x = (avg. {value}/5) ;
+
+x = (
+
+ Use the Button
's
+
+);
+
+this_really_should_split_across_lines = (
+
+ before{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}
+ after{stuff}after
+
+);
+
+let myDiv = ReactTestUtils.renderIntoDocument(
+ ,
+);
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/text-wrap/test.js.snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/text-wrap/test.js.snap
new file mode 100644
index 00000000000..03eb8021691
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/text-wrap/test.js.snap
@@ -0,0 +1,1390 @@
+---
+source: crates/rome_js_formatter/tests/prettier_tests.rs
+info:
+ test_file: jsx/text-wrap/test.js
+---
+
+# Input
+
+```js
+// Wrapping text
+x =
+
+ Some text that would need to wrap on to a new line in order to display correctly and nicely
+
+
+// Wrapping tags
+x =
+
+ f f f f f f
+
+
+// Wrapping tags
+x =
+
+ f f f f f f
+
+
+// Wrapping tags
+x =
+
+
+
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa f
+
+
+// Wrapping tags
+x =
+
+ f
+
+
+x =
+
+ before
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur at mollis lorem.
after
+
+
+x =
+
+ before{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}{stuff}{stuff}after{stuff}after
+
+
+x =
+
+ before {stuff} after {stuff} after {stuff} after {stuff} after {stuff} after {stuff} {stuff} {stuff} after {stuff} after
+
+
+x =
+
+ Please state your name and occupation for the board of school directors.
+
+
+function DiffOverview(props) {
+ const { source, target, since } = props;
+ return (
+
+
+
+ This diff overview is computed against the current list of records in
+ this collection and the list it contained on {humanDate(since)} .
+
+
+ Note: last_modified
and schema
record metadata
+ are omitted for easier review.
+
+
+
+
+ );
+}
+
+x = Starting at minute {graphActivity.startTime}, running for {graphActivity.length} to minute {graphActivity.startTime + graphActivity.length}
+
+x =
+
+ First second third
+
Something
+
+
+x =
+
+
+ First
+
+ Second
+
+ Third
+
+
+
+x =
+
+ First
+ Second
+
Third
+
+
+leading_whitespace =
+ First Second Third Fourth Fifth Sixth Seventh Eighth Ninth Tenth Eleventh Twelfth Thirteenth Fourteenth
+
+trailing_whitespace =
+ First Second Third Fourth Fifth Sixth Seventh Eighth Ninth Tenth Eleventh Twelfth Thirteenth Fourteenth
+
+no_leading_or_trailing_whitespace =
+ First Second Third Fourth Fifth Sixth Seventh Eighth Ninth Tenth Eleventh Twelfth Thirteenth Fourteenth
+
+facebook_translation_leave_text_around_tag =
+
+
+ First
+ ,
+ (
+ Second
+ )
+
+
+x =
+
+
+ First second third fourth fifth sixth seventh
+ ,
+ (
+ Second
+ )
+
+
+this_really_should_split_across_lines =
+
+ before{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after
+
+
+unstable_before =
+
+ Your score: {`${mini.crosstable.users[sessionUserId]} - ${mini.crosstable.users[user.id]}`}
+
+
+unstable_after_first_run = (
+
+ Your score:{" "}
+ {`${mini.crosstable.users[sessionUserId]} - ${mini
+ .crosstable.users[user.id]}`}
+
+);
+
+solitary_whitespace =
+
+
+jsx_whitespace_on_newline =
+
+
+ First
+
+ Second
+
+ Third
+
+
+
+jsx_around_multiline_element =
+ Before
{"Enough text to make this element wrap on to multiple lines when formatting"}
After
+
+jsx_around_multiline_element_second_pass = (
+
+ Before{" "}
+
+ {
+ "Enough text to make this element wrap on to multiple lines when formatting"
+ }
+
{" "}
+ After
+
+);
+
+convert_space_expressions =
+ {" "}
+
+x =
+
+
+
+
+
+
+
+
+
+const Abc = () => {
+ return (
+
+ Please state your
+ {" "}
+ name
+ {" "}
+ and
+ {" "}
+ occupation
+ {" "}
+ for the board of directors.
+
+ );
+};
+
+x = Some stuff here
+
+headers_and_paragraphs = (
+
+
First
+
The first paragraph.
+
+
Second
+
The second paragraph.
+
+);
+
+no_text_one_tag_per_line =
+
+
+
+
+with_text_fill_line =
+
+ Text
+
+
+line_after_br =
+
+ Text
+ More text
+ And more
+
+
+line_after_br =
+
+ Text More text And more
+
+
+line_after_br =
+
+ Text
+
+ More text
+
+ And more
+
+
+
+line_after_br_2 = A B C
+
+br_followed_by_whitespace = text
+
+dont_preserve_blank_lines_when_jsx_contains_text =
+
+
+
Zeroth
+
+
First
+
+ Second
+
+
+
+multiple_expressions =
+
+ {header}
+ {body}
+ {footer}
+
+
+single_expression_child_tags =
+
+ You currently have {dashboardStr} and {userStr}
+
+
+expression_does_not_break =
+ texty text text text text text text text text text text text {this.props.type}
+
+// FIXME
+br_triggers_expression_break =
+
+ text text text text text text text text text text text {this.props.type}
+
+jsx_whitespace_after_tag =
+
+
+ {variable}
+
+ {" "}
+ ({variable})
+
+
+x =
+
+ ENDS IN
+ text text text text text text text text text text text
+
{" "}
+ HRS
+
+
+x =
+
+
Message
+ Hello, I'm a simple message.
+
+
+x =
+
+ Hello, I'm a simple message.
+
Message
+
+
+x =
+
+
+
+
+
+ Line {startRange.row + 1}:{startRange.column + 1} - {endRange.row + 1}:{endRange.column + 1}{caller}
+
+
+
+
+
+
+x =
+
+
+// NOTE: Multiple JSX whitespaces are collapsed into a single space.
+x =
+
+ {" "}{" "}{" "}
+
+
+// Don't break a self-closing element without attributes
+// ----------
+x =
+
+ text text text text text text text text text text text text text text text text text text text text text
+
;
+
+x =
+
+
+ First
+
-
+
+ Second
+
+
+
+x =
+
+
+ First
+
+ -
+
+ Second
+
+
+
+x =
+
+
+x =
+
+
+ First
+
-
+
+ Second
+
+
+
+x =
+
+
+ First
+
+ -
+
+ Second
+
+
+
+x =
+
+
+x =
+
+ {hour}:{minute}:{second}
+
+
+x =
+
+ {hour}
+ :
+ {minute}
+ :
+ {second}
+
+
+x =
+
+ {hour}:
+ {minute}:
+ {second}
+
+
+x = text here .
+
+x = Sales tax estimated using a rate of {salesTax * 100}%.
+
+x =
+ {title}
+
+
+x = bar
+
+x =
+
+ {name} ’s{' '}
+
+ Hello world .
+ You {type}ed this shipment to
+
+
+x =
+ {parameter.Description}: {errorMsg}
+
+
+x =
+ {value} solution{plural}
+
+
+x = Copy "{name}"
+
+x = (avg. {value}/5)
+
+x =
+ Use the Button
's
+
;
+
+this_really_should_split_across_lines =
+
+ before{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after
+
+
+let myDiv = ReactTestUtils.renderIntoDocument(
+
+);
+```
+
+
+# Prettier differences
+
+```diff
+--- Prettier
++++ Rome
+@@ -9,8 +9,10 @@
+ // Wrapping tags
+ x = (
+
+- f f f f {" "}
+- f f
++ f f f f
++ f
++
++ f
+
+ );
+
+@@ -32,15 +34,16 @@
+
+
+
+- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa {" "}
+- f
++ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
++ f
++
+
+ );
+
+ // Wrapping tags
+ x = (
+
+- {" "}
++
+ f
+
+ );
+@@ -66,15 +69,19 @@
+
+ x = (
+
+- before {stuff} after {stuff} after {stuff} after {stuff} after {stuff} after{" "}
+- {stuff} {stuff} {stuff} after {stuff} after
++ before {stuff} after {stuff} after {stuff} after {stuff} after {stuff} after {
++ stuff
++ }
++ {stuff} {stuff} after {stuff} after
+
+ );
+
+ x = (
+
+- Please state your name and occupation for the board of{" "}
+- school directors.
++ Please state your name and occupation for the board of
++ school
++
++ directors.
+
+ );
+
+@@ -101,9 +108,10 @@
+ x = (
+
+
+- Starting at minute {graphActivity.startTime}, running for{" "}
+- {graphActivity.length} to minute{" "}
+- {graphActivity.startTime + graphActivity.length}
++ Starting at minute {graphActivity.startTime}, running for {
++ graphActivity.length
++ }
++ to minute {graphActivity.startTime + graphActivity.length}
+
+
+ );
+@@ -176,19 +184,17 @@
+
+ unstable_before = (
+
+- Your score:{" "}
+- {`${mini.crosstable.users[sessionUserId]} - ${
+- mini.crosstable.users[user.id]
+- }`}
++ Your score: {`${
++ mini.crosstable.users[sessionUserId]
++ } - ${mini.crosstable.users[user.id]}`}
+
+ );
+
+ unstable_after_first_run = (
+
+- Your score:{" "}
+- {`${mini.crosstable.users[sessionUserId]} - ${
+- mini.crosstable.users[user.id]
+- }`}
++ Your score: {`${
++ mini.crosstable.users[sessionUserId]
++ } - ${mini.crosstable.users[user.id]}`}
+
+ );
+
+@@ -213,24 +219,22 @@
+
+ jsx_around_multiline_element = (
+
+- Before{" "}
+-
++ Before
+ {
+ "Enough text to make this element wrap on to multiple lines when formatting"
+ }
+-
{" "}
++
+ After
+
+ );
+
+ jsx_around_multiline_element_second_pass = (
+
+- Before{" "}
+-
++ Before
+ {
+ "Enough text to make this element wrap on to multiple lines when formatting"
+ }
+-
{" "}
++
+ After
+
+ );
+@@ -251,8 +255,11 @@
+ const Abc = () => {
+ return (
+
+- Please state your name and occupation for the board of
+- directors.
++ Please state your
++ {" "}name
++ and
++ {" "}occupation
++ for the board of directors.
+
+ );
+ };
+@@ -318,19 +325,25 @@
+
+ line_after_br_2 = (
+
+- A B C
++ A
++
++ B
++
++ C
+
+ );
+
+ br_followed_by_whitespace = (
+
+- text
++
++ text
+
+ );
+
+ dont_preserve_blank_lines_when_jsx_contains_text = (
+
+
Zeroth
++
+
First
+ Second
+
+@@ -346,15 +359,18 @@
+
+ single_expression_child_tags = (
+
+- You currently have {dashboardStr} and{" "}
+- {userStr}
++ You currently have {dashboardStr} and
++ {userStr}
++
+
+ );
+
+ expression_does_not_break = (
+
+- texty text text text text text text text text text text text{" "}
+- {this.props.type}{" "}
++ texty text text text text text text text text text text text {
++ this.props.type
++ }
++ {" "}
+
+ );
+
+@@ -362,9 +378,8 @@
+ br_triggers_expression_break = (
+
+
+- text text text text text text text text text text text {
+- this.props.type
+- }{" "}
++ text text text text text text text text text text text {this.props.type}
++ {" "}
+
+ );
+
+@@ -372,14 +387,14 @@
+
+
+ {variable}
+- {" "}
++
+ ({variable})
+
+ );
+
+ x = (
+
+- ENDS IN
text text text text text text text text text text text
{" "}
++ ENDS IN
text text text text text text text text text text text
+ HRS
+
+ );
+@@ -404,8 +419,9 @@
+
+
+
+- Line {startRange.row + 1}:{startRange.column + 1} -{" "}
+- {endRange.row + 1}:{endRange.column + 1}
++ Line {startRange.row + 1}:{startRange.column + 1} - {endRange.row +
++ 1}
++ :{endRange.column + 1}
+ {caller}
+
+
+@@ -436,13 +452,16 @@
+
+ x = (
+
+-
First
-
Second
++
First
-
++
Second
+
+ );
+
+ x = (
+
+-
First
-
Second
++
First
++ -
++
Second
+
+ );
+
+@@ -496,19 +515,26 @@
+
+ x = (
+
+- {hour}:{minute}:{second}
++ {hour}
++ :
++ {minute}
++ :
++ {second}
+
+ );
+
+ x = (
+
+- {hour}:{minute}:{second}
++ {hour}:
++ {minute}:
++ {second}
+
+ );
+
+ x = (
+
+- text here .
++ text here .
++
+
+ );
+
+@@ -528,7 +554,8 @@
+
+ {name} ’s{" "}
+
+- Hello
world .
++ Hello
world .
++
+
You {type}ed this shipment to
+
+ );
+@@ -564,7 +591,8 @@
+
+ let myDiv = ReactTestUtils.renderIntoDocument(
+ ,
+ );
+```
+
+# Output
+
+```js
+// Wrapping text
+x = (
+
+ Some text that would need to wrap on to a new line in order to display
+ correctly and nicely
+
+);
+
+// Wrapping tags
+x = (
+
+ f f f f
+ f
+
+ f
+
+);
+
+// Wrapping tags
+x = (
+
+ f
+ f
+ f
+ f
+ f
+ f
+
+);
+
+// Wrapping tags
+x = (
+
+
+
+
+
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ f
+
+
+);
+
+// Wrapping tags
+x = (
+
+
+ f
+
+);
+
+x = (
+
+ before
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur at
+ mollis lorem.
+
+ after
+
+);
+
+x = (
+
+ before{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}
+ {stuff}
+ {stuff}after{stuff}after
+
+);
+
+x = (
+
+ before {stuff} after {stuff} after {stuff} after {stuff} after {stuff} after {
+ stuff
+ }
+ {stuff} {stuff} after {stuff} after
+
+);
+
+x = (
+
+ Please state your name and occupation for the board of
+ school
+
+ directors.
+
+);
+
+function DiffOverview(props) {
+ const { source, target, since } = props;
+ return (
+
+
+
+ This diff overview is computed against the current list of records in
+ this collection and the list it contained on {humanDate(since)}
+ .
+
+
+ Note: last_modified
and schema
record
+ metadata are omitted for easier review.
+
+
+
+
+ );
+}
+
+x = (
+
+
+ Starting at minute {graphActivity.startTime}, running for {
+ graphActivity.length
+ }
+ to minute {graphActivity.startTime + graphActivity.length}
+
+
+);
+
+x = (
+
+ First second third
+
+ Something
+
+
+);
+
+x = (
+
+
First
+ Second
+
Third
+
+);
+
+x = (
+
+);
+
+leading_whitespace = (
+
+ {" "}
+ First Second Third Fourth Fifth Sixth Seventh Eighth Ninth Tenth Eleventh
+ Twelfth Thirteenth Fourteenth
+
+);
+
+trailing_whitespace = (
+
+ First Second Third Fourth Fifth Sixth Seventh Eighth Ninth Tenth Eleventh
+ Twelfth Thirteenth Fourteenth{" "}
+
+);
+
+no_leading_or_trailing_whitespace = (
+
+ First Second Third Fourth Fifth Sixth Seventh Eighth Ninth Tenth Eleventh
+ Twelfth Thirteenth Fourteenth
+
+);
+
+facebook_translation_leave_text_around_tag = (
+
+ First , (Second )
+
+);
+
+x = (
+
+ First second third fourth fifth sixth seventh , (
+ Second )
+
+);
+
+this_really_should_split_across_lines = (
+
+ before{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}
+ after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}
+ after{stuff}after{stuff}after
+
+);
+
+unstable_before = (
+
+ Your score: {`${
+ mini.crosstable.users[sessionUserId]
+ } - ${mini.crosstable.users[user.id]}`}
+
+);
+
+unstable_after_first_run = (
+
+ Your score: {`${
+ mini.crosstable.users[sessionUserId]
+ } - ${mini.crosstable.users[user.id]}`}
+
+);
+
+solitary_whitespace = (
+
+ {" "}
+
+);
+
+jsx_whitespace_on_newline = (
+
+);
+
+jsx_around_multiline_element = (
+
+ Before
+ {
+ "Enough text to make this element wrap on to multiple lines when formatting"
+ }
+
+ After
+
+);
+
+jsx_around_multiline_element_second_pass = (
+
+ Before
+ {
+ "Enough text to make this element wrap on to multiple lines when formatting"
+ }
+
+ After
+
+);
+
+convert_space_expressions =
;
+
+x = (
+
+
+
+
+
+
+
+
+);
+
+const Abc = () => {
+ return (
+
+ Please state your
+ {" "}name
+ and
+ {" "}occupation
+ for the board of directors.
+
+ );
+};
+
+x = Some stuff here
;
+
+headers_and_paragraphs = (
+
+
First
+
The first paragraph.
+
+
Second
+
The second paragraph.
+
+);
+
+no_text_one_tag_per_line = (
+
+
+
+
+);
+
+with_text_fill_line = (
+
+ Text
+
+
+);
+
+line_after_br = (
+
+ Text
+
+ More text
+
+ And more
+
+
+);
+
+line_after_br = (
+
+ Text
+
+ More text
+
+ And more
+
+
+);
+
+line_after_br = (
+
+ Text
+
+ More text
+
+ And more
+
+
+);
+
+line_after_br_2 = (
+
+ A
+
+ B
+
+ C
+
+);
+
+br_followed_by_whitespace = (
+
+
+ text
+
+);
+
+dont_preserve_blank_lines_when_jsx_contains_text = (
+
+
Zeroth
+
+
First
+ Second
+
+);
+
+multiple_expressions = (
+
+ {header}
+ {body}
+ {footer}
+
+);
+
+single_expression_child_tags = (
+
+ You currently have {dashboardStr} and
+ {userStr}
+
+
+);
+
+expression_does_not_break = (
+
+ texty text text text text text text text text text text text {
+ this.props.type
+ }
+ {" "}
+
+);
+
+// FIXME
+br_triggers_expression_break = (
+
+
+ text text text text text text text text text text text {this.props.type}
+ {" "}
+
+);
+
+jsx_whitespace_after_tag = (
+
+
+ {variable}
+
+ ({variable})
+
+);
+
+x = (
+
+ ENDS IN
text text text text text text text text text text text
+ HRS
+
+);
+
+x = (
+
+
Message
+ Hello, I'm a simple message.
+
+);
+
+x = (
+
+ Hello, I'm a simple message.
+
Message
+
+);
+
+x = (
+
+
+
+
+
+ Line {startRange.row + 1}:{startRange.column + 1} - {endRange.row +
+ 1}
+ :{endRange.column + 1}
+ {caller}
+
+
+
+
+
+);
+
+x = (
+
+);
+
+// NOTE: Multiple JSX whitespaces are collapsed into a single space.
+x =
;
+
+// Don't break a self-closing element without attributes
+// ----------
+x = (
+
+ text text text text text text text text text text text text text text text
+
+ text text text text text text
+
+);
+
+x = (
+
+);
+
+x = (
+
+);
+
+x = (
+
+);
+
+x = (
+
+
+ First
+
+ -
+
+ Second
+
+
+);
+
+x = (
+
+
+ First
+
+ -
+
+ Second
+
+
+);
+
+x = (
+
+
+ First
+
+ -
+
+ Second
+
+
+);
+
+x = (
+
+ {hour}:{minute}:{second}
+
+);
+
+x = (
+
+ {hour}
+ :
+ {minute}
+ :
+ {second}
+
+);
+
+x = (
+
+ {hour}:
+ {minute}:
+ {second}
+
+);
+
+x = (
+
+ text here .
+
+
+);
+
+x = Sales tax estimated using a rate of {salesTax * 100}%.
;
+
+x = {title}
;
+
+x = (
+
+
+ bar
+
+);
+
+x = (
+
+
+ {name} ’s{" "}
+
+ Hello world .
+
+ You {type}ed this shipment to
+
+);
+
+x = (
+
+ {parameter.Description}: {errorMsg}
+
+);
+
+x = (
+
+ {value} solution{plural}
+
+);
+
+x = Copy "{name}" ;
+
+x = (avg. {value}/5) ;
+
+x = (
+
+ Use the Button
's
+
+);
+
+this_really_should_split_across_lines = (
+
+ before{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}
+ after{stuff}after
+
+);
+
+let myDiv = ReactTestUtils.renderIntoDocument(
+ ,
+);
+```
+
+
+# Lines exceeding max width of 80 characters
+```
+ 72: before {stuff} after {stuff} after {stuff} after {stuff} after {stuff} after {
+ 122:
+ 224: "Enough text to make this element wrap on to multiple lines when formatting"
+ 235: "Enough text to make this element wrap on to multiple lines when formatting"
+```
+
diff --git a/crates/rome_js_formatter/tests/specs/prettier/prepare_tests.js b/crates/rome_js_formatter/tests/specs/prettier/prepare_tests.js
index 288ca96c300..9840ae0e75e 100644
--- a/crates/rome_js_formatter/tests/specs/prettier/prepare_tests.js
+++ b/crates/rome_js_formatter/tests/specs/prettier/prepare_tests.js
@@ -78,6 +78,7 @@ async function traverseDir(dir, config) {
}
const PRETTIER_ROOT_JS = path.resolve(PRETTIER_ROOT, "js");
+const PRETTIER_ROOT_JSX = path.resolve(PRETTIER_ROOT, "jsx");
const PRETTIER_ROOT_TS = path.resolve(PRETTIER_ROOT, "typescript");
const defaultConfig = {
@@ -94,6 +95,13 @@ async function main() {
...defaultConfig,
parser: "babel",
});
+
+ console.log("Extracting tests from %s ...", {PRETTIER_ROOT_JSX});
+ await traverseDir(PRETTIER_ROOT_JSX, {
+ ...defaultConfig,
+ parser: "babel",
+ });
+
console.log("Extracting tests from %s ...", PRETTIER_ROOT_TS);
await traverseDir(PRETTIER_ROOT_TS, {
...defaultConfig,
diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/conditional-types/issue-13275.ts b/crates/rome_js_formatter/tests/specs/prettier/typescript/conditional-types/issue-13275.ts
new file mode 100644
index 00000000000..de1ccb2859a
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/conditional-types/issue-13275.ts
@@ -0,0 +1 @@
+type Foo
= T extends ((...a: any[]) => infer R extends string) ? R : never;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/conditional-types/issue-13275.ts.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/conditional-types/issue-13275.ts.prettier-snap
new file mode 100644
index 00000000000..de1ccb2859a
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/conditional-types/issue-13275.ts.prettier-snap
@@ -0,0 +1 @@
+type Foo = T extends ((...a: any[]) => infer R extends string) ? R : never;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/enum/computed-members.ts.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/enum/computed-members.ts.prettier-snap
index ba48c56ec74..7ba227a2b2c 100644
--- a/crates/rome_js_formatter/tests/specs/prettier/typescript/enum/computed-members.ts.prettier-snap
+++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/enum/computed-members.ts.prettier-snap
@@ -1,13 +1,13 @@
enum A {
- [i++],
+ i++,
}
const bar = "bar";
enum B {
- [bar] = 2,
+ bar = 2,
}
const foo = () => "foo";
enum C {
- [foo()] = 2,
+ foo() = 2,
}
diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/enum/computed-members.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/enum/computed-members.ts.snap
index 0f789d4cf8d..3c1443ded3f 100644
--- a/crates/rome_js_formatter/tests/specs/prettier/typescript/enum/computed-members.ts.snap
+++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/enum/computed-members.ts.snap
@@ -1,5 +1,7 @@
---
source: crates/rome_js_formatter/tests/prettier_tests.rs
+info:
+ test_file: typescript/enum/computed-members.ts
---
# Input
@@ -28,19 +30,19 @@ enum C {
+++ Rome
@@ -1,13 +1,7 @@
-enum A {
-- [i++],
+- i++,
-}
+enum A { [i++] }
const bar = "bar";
-enum B {
-- [bar] = 2,
+- bar = 2,
-}
+enum B { [bar] = 2 }
const foo = () => "foo";
-enum C {
-- [foo()] = 2,
+- foo() = 2,
-}
+enum C { [foo()] = 2 }
```
diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/error-recovery/jsdoc_only_types.ts.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/error-recovery/jsdoc_only_types.ts.prettier-snap
index 7751d7a4192..fd8cf153040 100644
--- a/crates/rome_js_formatter/tests/specs/prettier/typescript/error-recovery/jsdoc_only_types.ts.prettier-snap
+++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/error-recovery/jsdoc_only_types.ts.prettier-snap
@@ -1,8 +1,8 @@
let a: *;
function b(x: ?) {}
let c: ?string;
-let d: string?;
+let d: ?string;
let e: ?(string | number);
let f: !string;
-let g: string!;
+let g: !string;
let h: !(string | number);
diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/error-recovery/jsdoc_only_types.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/error-recovery/jsdoc_only_types.ts.snap
index bc35ce5fc7d..7f845c09a23 100644
--- a/crates/rome_js_formatter/tests/specs/prettier/typescript/error-recovery/jsdoc_only_types.ts.snap
+++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/error-recovery/jsdoc_only_types.ts.snap
@@ -1,5 +1,7 @@
---
source: crates/rome_js_formatter/tests/prettier_tests.rs
+info:
+ test_file: typescript/error-recovery/jsdoc_only_types.ts
---
# Input
@@ -27,10 +29,10 @@ let h: !(string | number);
+*
function b(x: ?) {}
-let c: ?string;
--let d: string?;
+-let d: ?string;
-let e: ?(string | number);
-let f: !string;
--let g: string!;
+-let g: !string;
-let h: !(string | number);
+let c:
+?string
diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/interface2/break.ts b/crates/rome_js_formatter/tests/specs/prettier/typescript/interface2/break.ts
index 579bb27c4f3..3bf95b1df83 100644
--- a/crates/rome_js_formatter/tests/specs/prettier/typescript/interface2/break.ts
+++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/interface2/break.ts
@@ -1,7 +1,7 @@
export interface Environment1 extends GenericEnvironment<
SomeType,
AnotherType,
- YetAnotherType
+ YetAnotherType,
> {
m(): void;
};
@@ -12,7 +12,7 @@ export class Environment2 extends GenericEnvironment<
DifferentType1,
DifferentType2,
DifferentType3,
- DifferentType4
+ DifferentType4,
> {
m() {};
};
diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/interface2/break.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/interface2/break.ts.snap
index 0aafee6722c..5104cc03914 100644
--- a/crates/rome_js_formatter/tests/specs/prettier/typescript/interface2/break.ts.snap
+++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/interface2/break.ts.snap
@@ -1,5 +1,7 @@
---
source: crates/rome_js_formatter/tests/prettier_tests.rs
+info:
+ test_file: typescript/interface2/break.ts
---
# Input
@@ -8,7 +10,7 @@ source: crates/rome_js_formatter/tests/prettier_tests.rs
export interface Environment1 extends GenericEnvironment<
SomeType,
AnotherType,
- YetAnotherType
+ YetAnotherType,
> {
m(): void;
};
@@ -19,7 +21,7 @@ export class Environment2 extends GenericEnvironment<
DifferentType1,
DifferentType2,
DifferentType3,
- DifferentType4
+ DifferentType4,
> {
m() {};
};
@@ -79,7 +81,30 @@ export interface ExtendsLongOneWithGenerics extends Bar< SomeLongTypeSomeLongTyp
```diff
--- Prettier
+++ Rome
-@@ -68,14 +68,14 @@
+@@ -1,5 +1,8 @@
+-export interface Environment1
+- extends GenericEnvironment {
++export interface Environment1 extends GenericEnvironment<
++ SomeType,
++ AnotherType,
++ YetAnotherType,
++> {
+ m(): void;
+ }
+ export class Environment2 extends GenericEnvironment<
+@@ -9,9 +12,9 @@
+ DifferentType1,
+ DifferentType2,
+ DifferentType3,
+- DifferentType4
++ DifferentType4,
+ > {
+- m() {}
++ m() {};
+ }
+
+ // Declare Interface Break
+@@ -68,14 +71,14 @@
interface ExtendsMany
extends ASingleGenericInterface<
@@ -102,7 +127,7 @@ export interface ExtendsLongOneWithGenerics extends Bar< SomeLongTypeSomeLongTyp
x: string;
}
-@@ -97,6 +97,6 @@
+@@ -97,6 +100,6 @@
export interface ExtendsLongOneWithGenerics
extends Bar<
@@ -117,8 +142,11 @@ export interface ExtendsLongOneWithGenerics extends Bar< SomeLongTypeSomeLongTyp
# Output
```js
-export interface Environment1
- extends GenericEnvironment {
+export interface Environment1 extends GenericEnvironment<
+ SomeType,
+ AnotherType,
+ YetAnotherType,
+> {
m(): void;
}
export class Environment2 extends GenericEnvironment<
@@ -128,9 +156,9 @@ export class Environment2 extends GenericEnvironment<
DifferentType1,
DifferentType2,
DifferentType3,
- DifferentType4
+ DifferentType4,
> {
- m() {}
+ m() {};
}
// Declare Interface Break
@@ -222,4 +250,21 @@ export interface ExtendsLongOneWithGenerics
```
+# Errors
+```
+error[SyntaxError]: expected a type parameter but instead found '>'
+ ┌─ break.ts:5:1
+ │
+5 │ > {
+ │ ^ Expected a type parameter here
+
+error[SyntaxError]: expected a type parameter but instead found '>'
+ ┌─ break.ts:16:1
+ │
+16 │ > {
+ │ ^ Expected a type parameter here
+
+
+```
+
diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/literal/multiline.ts b/crates/rome_js_formatter/tests/specs/prettier/typescript/literal/multiline.ts
new file mode 100644
index 00000000000..22648828e01
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/literal/multiline.ts
@@ -0,0 +1,6 @@
+type loremIpsumFooBazBar1 = 'Multiline string\
+ Multiline string'
+
+type loremIpsumFooBazBar2 = 'Multiline string\
+ Multiline string\
+ Multiline string'
diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/literal/multiline.ts.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/literal/multiline.ts.prettier-snap
new file mode 100644
index 00000000000..73c3e12f412
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/literal/multiline.ts.prettier-snap
@@ -0,0 +1,7 @@
+type loremIpsumFooBazBar1 = "Multiline string\
+ Multiline string";
+
+type loremIpsumFooBazBar2 =
+ "Multiline string\
+ Multiline string\
+ Multiline string";
diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/literal/multiline.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/literal/multiline.ts.snap
new file mode 100644
index 00000000000..553bece6606
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/literal/multiline.ts.snap
@@ -0,0 +1,47 @@
+---
+source: crates/rome_js_formatter/tests/prettier_tests.rs
+info:
+ test_file: typescript/literal/multiline.ts
+---
+
+# Input
+
+```js
+type loremIpsumFooBazBar1 = 'Multiline string\
+ Multiline string'
+
+type loremIpsumFooBazBar2 = 'Multiline string\
+ Multiline string\
+ Multiline string'
+```
+
+
+# Prettier differences
+
+```diff
+--- Prettier
++++ Rome
+@@ -1,7 +1,6 @@
+ type loremIpsumFooBazBar1 = "Multiline string\
+ Multiline string";
+
+-type loremIpsumFooBazBar2 =
+- "Multiline string\
++type loremIpsumFooBazBar2 = "Multiline string\
+ Multiline string\
+ Multiline string";
+```
+
+# Output
+
+```js
+type loremIpsumFooBazBar1 = "Multiline string\
+ Multiline string";
+
+type loremIpsumFooBazBar2 = "Multiline string\
+ Multiline string\
+ Multiline string";
+```
+
+
+
diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/typeof-this/decorators.ts b/crates/rome_js_formatter/tests/specs/prettier/typescript/typeof-this/decorators.ts
new file mode 100644
index 00000000000..e10c347fb64
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/typeof-this/decorators.ts
@@ -0,0 +1,6 @@
+// https://github.com/typescript-eslint/typescript-eslint/pull/4382
+function decorator() {}
+@decorator
+class Foo {
+ bar(baz: typeof this) {}
+}
diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/typeof-this/decorators.ts.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/typeof-this/decorators.ts.prettier-snap
new file mode 100644
index 00000000000..e10c347fb64
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/typeof-this/decorators.ts.prettier-snap
@@ -0,0 +1,6 @@
+// https://github.com/typescript-eslint/typescript-eslint/pull/4382
+function decorator() {}
+@decorator
+class Foo {
+ bar(baz: typeof this) {}
+}
diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/typeof-this/decorators.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/typeof-this/decorators.ts.snap
new file mode 100644
index 00000000000..e9c459e11a2
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/typeof-this/decorators.ts.snap
@@ -0,0 +1,46 @@
+---
+source: crates/rome_js_formatter/tests/prettier_tests.rs
+info:
+ test_file: typescript/typeof-this/decorators.ts
+---
+
+# Input
+
+```js
+// https://github.com/typescript-eslint/typescript-eslint/pull/4382
+function decorator() {}
+@decorator
+class Foo {
+ bar(baz: typeof this) {}
+}
+```
+
+
+# Prettier differences
+
+```diff
+--- Prettier
++++ Rome
+@@ -1,5 +1,6 @@
+ // https://github.com/typescript-eslint/typescript-eslint/pull/4382
+ function decorator() {}
++
+ @decorator
+ class Foo {
+ bar(baz: typeof this) {}
+```
+
+# Output
+
+```js
+// https://github.com/typescript-eslint/typescript-eslint/pull/4382
+function decorator() {}
+
+@decorator
+class Foo {
+ bar(baz: typeof this) {}
+}
+```
+
+
+
diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/typeof-this/typeof-this.ts b/crates/rome_js_formatter/tests/specs/prettier/typescript/typeof-this/typeof-this.ts
new file mode 100644
index 00000000000..7f3c4f11d4c
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/typeof-this/typeof-this.ts
@@ -0,0 +1,3 @@
+// https://github.com/typescript-eslint/typescript-eslint/pull/4382
+let self: typeof this;
+let foo: typeof this.foo;
diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/typeof-this/typeof-this.ts.prettier-snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/typeof-this/typeof-this.ts.prettier-snap
new file mode 100644
index 00000000000..7f3c4f11d4c
--- /dev/null
+++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/typeof-this/typeof-this.ts.prettier-snap
@@ -0,0 +1,3 @@
+// https://github.com/typescript-eslint/typescript-eslint/pull/4382
+let self: typeof this;
+let foo: typeof this.foo;
diff --git a/crates/rome_service/src/configuration/linter/rules.rs b/crates/rome_service/src/configuration/linter/rules.rs
index 5e7bf136aaa..bb8a22ed0c3 100644
--- a/crates/rome_service/src/configuration/linter/rules.rs
+++ b/crates/rome_service/src/configuration/linter/rules.rs
@@ -215,7 +215,6 @@ struct CorrectnessSchema {
no_unsafe_negation: Option,
no_unused_template_literal: Option,
use_block_statements: Option,
- use_optional_chain: Option,
use_simplified_logic_expression: Option,
use_single_case_statement: Option,
use_single_var_declarator: Option,
@@ -225,7 +224,7 @@ struct CorrectnessSchema {
}
impl Correctness {
const CATEGORY_NAME: &'static str = "correctness";
- pub(crate) const CATEGORY_RULES: [&'static str; 29] = [
+ pub(crate) const CATEGORY_RULES: [&'static str; 28] = [
"noArguments",
"noAsyncPromiseExecutor",
"noCatchAssign",
@@ -248,7 +247,6 @@ impl Correctness {
"noUnsafeNegation",
"noUnusedTemplateLiteral",
"useBlockStatements",
- "useOptionalChain",
"useSimplifiedLogicExpression",
"useSingleCaseStatement",
"useSingleVarDeclarator",
@@ -256,7 +254,7 @@ impl Correctness {
"useValidTypeof",
"useWhile",
];
- const RECOMMENDED_RULES: [&'static str; 29] = [
+ const RECOMMENDED_RULES: [&'static str; 28] = [
"noArguments",
"noAsyncPromiseExecutor",
"noCatchAssign",
@@ -279,7 +277,6 @@ impl Correctness {
"noUnsafeNegation",
"noUnusedTemplateLiteral",
"useBlockStatements",
- "useOptionalChain",
"useSimplifiedLogicExpression",
"useSingleCaseStatement",
"useSingleVarDeclarator",
@@ -287,7 +284,7 @@ impl Correctness {
"useValidTypeof",
"useWhile",
];
- const RECOMMENDED_RULES_AS_FILTERS: [RuleFilter<'static>; 29] = [
+ const RECOMMENDED_RULES_AS_FILTERS: [RuleFilter<'static>; 28] = [
RuleFilter::Rule("correctness", Self::CATEGORY_RULES[0]),
RuleFilter::Rule("correctness", Self::CATEGORY_RULES[1]),
RuleFilter::Rule("correctness", Self::CATEGORY_RULES[2]),
@@ -316,7 +313,6 @@ impl Correctness {
RuleFilter::Rule("correctness", Self::CATEGORY_RULES[25]),
RuleFilter::Rule("correctness", Self::CATEGORY_RULES[26]),
RuleFilter::Rule("correctness", Self::CATEGORY_RULES[27]),
- RuleFilter::Rule("correctness", Self::CATEGORY_RULES[28]),
];
pub(crate) fn is_recommended(&self) -> bool { !matches!(self.recommended, Some(false)) }
pub(crate) fn get_enabled_rules(&self) -> IndexSet {
@@ -343,7 +339,7 @@ impl Correctness {
pub(crate) fn is_recommended_rule(rule_name: &str) -> bool {
Self::RECOMMENDED_RULES.contains(&rule_name)
}
- pub(crate) fn recommended_rules_as_filters() -> [RuleFilter<'static>; 29] {
+ pub(crate) fn recommended_rules_as_filters() -> [RuleFilter<'static>; 28] {
Self::RECOMMENDED_RULES_AS_FILTERS
}
}
@@ -392,15 +388,17 @@ struct NurserySchema {
no_unreachable: Option,
no_unused_variables: Option,
use_camel_case: Option,
+ use_optional_chain: Option,
}
impl Nursery {
const CATEGORY_NAME: &'static str = "nursery";
- pub(crate) const CATEGORY_RULES: [&'static str; 5] = [
+ pub(crate) const CATEGORY_RULES: [&'static str; 6] = [
"noDangerouslySetInnerHtml",
"noNewSymbol",
"noUnreachable",
"noUnusedVariables",
"useCamelCase",
+ "useOptionalChain",
];
const RECOMMENDED_RULES: [&'static str; 0] = [];
const RECOMMENDED_RULES_AS_FILTERS: [RuleFilter<'static>; 0] = [];
diff --git a/editors/vscode/configuration_schema.json b/editors/vscode/configuration_schema.json
index 39e35c875c5..dac8d9128d1 100644
--- a/editors/vscode/configuration_schema.json
+++ b/editors/vscode/configuration_schema.json
@@ -271,16 +271,6 @@
}
]
},
- "useOptionalChain": {
- "anyOf": [
- {
- "$ref": "#/definitions/RuleConfiguration"
- },
- {
- "type": "null"
- }
- ]
- },
"useSimplifiedLogicExpression": {
"anyOf": [
{
@@ -547,6 +537,16 @@
"type": "null"
}
]
+ },
+ "useOptionalChain": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/RuleConfiguration"
+ },
+ {
+ "type": "null"
+ }
+ ]
}
}
},
diff --git a/npm/backend-jsonrpc/src/workspace.ts b/npm/backend-jsonrpc/src/workspace.ts
index 44c251b2cc7..521ad1f36de 100644
--- a/npm/backend-jsonrpc/src/workspace.ts
+++ b/npm/backend-jsonrpc/src/workspace.ts
@@ -144,7 +144,6 @@ export interface Correctness {
*/
recommended?: boolean;
useBlockStatements?: RuleConfiguration;
- useOptionalChain?: RuleConfiguration;
useSimplifiedLogicExpression?: RuleConfiguration;
useSingleCaseStatement?: RuleConfiguration;
useSingleVarDeclarator?: RuleConfiguration;
@@ -165,6 +164,7 @@ export interface Nursery {
*/
recommended?: boolean;
useCamelCase?: RuleConfiguration;
+ useOptionalChain?: RuleConfiguration;
}
/**
* A list of rules that belong to this group
diff --git a/website/src/_includes/contributors.md b/website/src/_includes/contributors.md
new file mode 100644
index 00000000000..2ad95787f66
--- /dev/null
+++ b/website/src/_includes/contributors.md
@@ -0,0 +1,672 @@
+
+
+### Code contributors
+
+
diff --git a/website/src/credits.md b/website/src/credits.md
index df0a7c27b34..e5059a78056 100644
--- a/website/src/credits.md
+++ b/website/src/credits.md
@@ -107,308 +107,7 @@ layout: layouts/page.liquid
-## Code Contributors
-
-
-
-
+{% include ./contributors.md %}
### Acknowledgements
diff --git a/website/src/docs/lint/rules/index.md b/website/src/docs/lint/rules/index.md
index 5c27efca887..ac11607c922 100644
--- a/website/src/docs/lint/rules/index.md
+++ b/website/src/docs/lint/rules/index.md
@@ -193,14 +193,6 @@ Requires following curly brace conventions.
JavaScript allows the omission of curly braces when a block contains only one statement. However, it is considered by many to be best practice to never omit curly braces around blocks, even when they are optional, because it can lead to bugs and reduces code clarity.
-
-Enforce using concise optional chain instead of chained logical expressions.
-
-
Enforce camel case naming convention.
+
+
+Enforce using concise optional chain instead of chained logical expressions.
+
Style
diff --git a/website/src/docs/lint/rules/noAsyncPromiseExecutor.md b/website/src/docs/lint/rules/noAsyncPromiseExecutor.md
index 1dedf152fcf..0109c29be83 100644
--- a/website/src/docs/lint/rules/noAsyncPromiseExecutor.md
+++ b/website/src/docs/lint/rules/noAsyncPromiseExecutor.md
@@ -13,6 +13,7 @@ The executor function can also be an async function. However, this is usually a
1. If an async executor function throws an error, the error will be lost and won't cause the newly-constructed `Promise` to reject. This could make it difficult to debug and handle some errors.
2. If a Promise executor function is using `await`, this is usually a sign that it is not actually necessary to use the `new Promise` constructor, or the scope of the `new Promise` constructor can be reduced.
+
## Examples
### Invalid
diff --git a/website/src/docs/lint/rules/noUnusedVariables.md b/website/src/docs/lint/rules/noUnusedVariables.md
index 51b6acdecd6..57b215d6528 100644
--- a/website/src/docs/lint/rules/noUnusedVariables.md
+++ b/website/src/docs/lint/rules/noUnusedVariables.md
@@ -11,6 +11,7 @@ There are two exceptions to this rule:
1. variables that starts with underscore, ex: `let _something;`
2. the `React` variable;
+
The pattern of having an underscore as prefix of a name of variable is a very diffuse
pattern among programmers, and Rome decided to follow it.
diff --git a/website/src/docs/lint/rules/useOptionalChain.md b/website/src/docs/lint/rules/useOptionalChain.md
index 7aee93c8890..37a49dc130d 100644
--- a/website/src/docs/lint/rules/useOptionalChain.md
+++ b/website/src/docs/lint/rules/useOptionalChain.md
@@ -5,8 +5,6 @@ layout: layouts/rule.liquid
# useOptionalChain (since v0.10.0)
-> This rule is recommended by Rome.
-
Enforce using concise optional chain instead of chained logical expressions.
TypeScript 3.7 added support for the optional chain operator.
@@ -22,11 +20,11 @@ It is much safer than relying upon logical operator chaining; which chains on an
foo && foo.bar && foo.bar.baz && foo.bar.baz.buzz
```
-{% raw %}error [ correctness/useOptionalChain ] : Change to an optional chain.
- ┌ ─ correctness/useOptionalChain.js:1:1
+{% raw %}warning [ nursery/useOptionalChain ] : Change to an optional chain.
+ ┌ ─ nursery/useOptionalChain.js:1:1
│
-1 │ f o o & & f o o . b a r & & f o o . b a r . b a z & & f o o . b a r . b a z . b u z z
- │ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
+1 │ foo && foo.bar && foo.bar.baz && foo.bar.baz.buzz
+ │ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Suggested fix : Change to an optional chain.
| @@ -1 +1 @@
@@ -39,11 +37,11 @@ foo && foo.bar && foo.bar.baz && foo.bar.baz.buzz
foo.bar && foo.bar.baz.buzz
```
-{% raw %}error [ correctness/useOptionalChain ] : Change to an optional chain.
- ┌ ─ correctness/useOptionalChain.js:1:1
+{% raw %}warning [ nursery/useOptionalChain ] : Change to an optional chain.
+ ┌ ─ nursery/useOptionalChain.js:1:1
│
-1 │ f o o . b a r & & f o o . b a r . b a z . b u z z
- │ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
+1 │ foo.bar && foo.bar.baz.buzz
+ │ - - - - - - - - - - - - - - - - - - - - - - - - - - -
Suggested fix : Change to an optional chain.
| @@ -1 +1 @@
@@ -56,11 +54,11 @@ foo.bar && foo.bar.baz.buzz
foo !== undefined && foo.bar != undefined && foo.bar.baz !== null && foo.bar.baz.buzz
```
-{% raw %}error [ correctness/useOptionalChain ] : Change to an optional chain.
- ┌ ─ correctness/useOptionalChain.js:1:1
+{% raw %}warning [ nursery/useOptionalChain ] : Change to an optional chain.
+ ┌ ─ nursery/useOptionalChain.js:1:1
│
-1 │ f o o ! = = u n d e f i n e d & & f o o . b a r ! = u n d e f i n e d & & f o o . b a r . b a z ! = = n u l l & & f o o . b a r . b a z . b u z z
- │ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
+1 │ foo !== undefined && foo.bar != undefined && foo.bar.baz !== null && foo.bar.baz.buzz
+ │ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Suggested fix : Change to an optional chain.
| @@ -1 +1 @@
@@ -73,11 +71,11 @@ foo !== undefined && foo.bar != undefined && foo.bar.baz !== null && foo.bar.baz
((foo || {}).bar || {}).baz;
```
-{% raw %}error [ correctness/useOptionalChain ] : Change to an optional chain.
- ┌ ─ correctness/useOptionalChain.js:1:1
+{% raw %}warning [ nursery/useOptionalChain ] : Change to an optional chain.
+ ┌ ─ nursery/useOptionalChain.js:1:1
│
-1 │ ( ( f o o | | { } ) . b a r | | { } ) . b a z ;
- │ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
+1 │ ((foo || {}).bar || {}).baz;
+ │ - - - - - - - - - - - - - - - - - - - - - - - - - - -
Suggested fix : Change to an optional chain.
| @@ -1 +1 @@
@@ -90,11 +88,11 @@ foo !== undefined && foo.bar != undefined && foo.bar.baz !== null && foo.bar.baz
(await (foo1 || {}).foo2 || {}).foo3;
```
-{% raw %}error [ correctness/useOptionalChain ] : Change to an optional chain.
- ┌ ─ correctness/useOptionalChain.js:1:1
+{% raw %}warning [ nursery/useOptionalChain ] : Change to an optional chain.
+ ┌ ─ nursery/useOptionalChain.js:1:1
│
-1 │ ( a w a i t ( f o o 1 | | { } ) . f o o 2 | | { } ) . f o o 3 ;
- │ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
+1 │ (await (foo1 || {}).foo2 || {}).foo3;
+ │ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Suggested fix : Change to an optional chain.
| @@ -1 +1 @@
@@ -107,11 +105,11 @@ foo !== undefined && foo.bar != undefined && foo.bar.baz !== null && foo.bar.baz
(((typeof x) as string) || {}).bar;
```
-{% raw %}error [ correctness/useOptionalChain ] : Change to an optional chain.
- ┌ ─ correctness/useOptionalChain.js:1:1
+{% raw %}warning [ nursery/useOptionalChain ] : Change to an optional chain.
+ ┌ ─ nursery/useOptionalChain.js:1:1
│
-1 │ ( ( ( t y p e o f x ) a s s t r i n g ) | | { } ) . b a r ;
- │ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
+1 │ (((typeof x) as string) || {}).bar;
+ │ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Suggested fix : Change to an optional chain.
| @@ -1 +1 @@
diff --git a/xtask/contributors/Cargo.toml b/xtask/contributors/Cargo.toml
new file mode 100644
index 00000000000..aa0c4e9b8a9
--- /dev/null
+++ b/xtask/contributors/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "xtask_contributors"
+version = "0.0.0"
+edition = "2021"
+publish = false
+
+[dependencies]
+serde = { version = "1.0.133", features = ["derive"] }
+serde_json = { version = "1.0.74" }
+xtask = { path = '../', version = "0.0" }
+ureq = { version = "2.4.0", features = ["json"] }
+pico-args = "0.5.0"
+html-escape = "0.2.11"
\ No newline at end of file
diff --git a/xtask/contributors/src/main.rs b/xtask/contributors/src/main.rs
new file mode 100644
index 00000000000..998693c740e
--- /dev/null
+++ b/xtask/contributors/src/main.rs
@@ -0,0 +1,99 @@
+use pico_args::Arguments;
+use serde::{Deserialize, Serialize};
+use std::fmt::Write;
+use xtask::glue::fs2;
+use xtask::*;
+
+/// A token is needed to run this script. To create a token, go to https://github.com/settings/tokens
+/// and give it read access to the repository.
+///
+/// Only users that have read rights can run this script
+fn main() -> Result<()> {
+ let root = project_root().join("website/src/_includes");
+ let mut args = Arguments::from_env();
+ let token: String = args.value_from_str("--token").unwrap();
+ let contributors = get_contributors(&token);
+
+ let mut content = String::new();
+
+ let command = "Use the command `cargo contributors`".to_string();
+ write!(content, "", prepend_generated_preamble(command))?;
+ content.push('\n');
+ content.push_str("### Code contributors");
+ content.push('\n');
+ content.push_str("");
+ fs2::write(root.join("contributors.md"), content)?;
+
+ Ok(())
+}
+
+#[derive(Debug, Deserialize, Serialize)]
+struct Contributor {
+ avatar_url: String,
+ login: String,
+}
+
+fn get_contributors(token: &str) -> Vec {
+ let mut contributors = Vec::new();
+ contributors_request(
+ "https://api.github.com/repos/rome/tools/contributors",
+ token,
+ &mut contributors,
+ );
+ contributors
+}
+
+fn contributors_request(url: &str, token: &str, contributors: &mut Vec) {
+ let request = ureq::get(url)
+ .set("User-Agent", "@rome")
+ .set("Authorization", &format!("token {token}"));
+
+ match request.call() {
+ Ok(response) => {
+ if let Some(link) = response.header("link") {
+ if link.contains("rel=\"next\"") {
+ let start_index = link
+ .find("rel=\"prev\", ")
+ .map(|index| index + "rel=\"prev\", ".len())
+ .unwrap_or(0);
+ // SAFETY: checked before
+ let end_index = link.find("; rel=\"next\"").unwrap();
+ let url = &link[start_index..end_index];
+ let url = url.replace('<', "").replace('>', "");
+
+ contributors_request(&url, token, contributors);
+ }
+ }
+ let result: Result, std::io::Error> = response.into_json();
+ if let Ok(new_contributors) = result {
+ contributors.extend(new_contributors);
+ }
+ }
+ Err(err) => {
+ eprintln!("{:?}", err);
+ }
+ }
+}
diff --git a/xtask/lintdoc/src/main.rs b/xtask/lintdoc/src/main.rs
index 3d69ae83558..f0624a86616 100644
--- a/xtask/lintdoc/src/main.rs
+++ b/xtask/lintdoc/src/main.rs
@@ -317,6 +317,7 @@ fn parse_documentation(
Event::End(Tag::List(_)) => {
list_order = None;
+ writeln!(content)?;
}
Event::Start(Tag::Item) => {
if let Some(num) = list_order {
diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs
index edcd613f325..ec28b54c3ca 100644
--- a/xtask/src/lib.rs
+++ b/xtask/src/lib.rs
@@ -43,7 +43,7 @@ pub fn reformat(text: impl Display) -> Result {
reformat_without_preamble(text).map(prepend_generated_preamble)
}
-const PREAMBLE: &str = "Generated file, do not edit by hand, see `xtask/codegen`";
+pub const PREAMBLE: &str = "Generated file, do not edit by hand, see `xtask/codegen`";
pub fn prepend_generated_preamble(content: impl Display) -> String {
format!("//! {}\n\n{}", PREAMBLE, content)
}