Repository: sveltejs/prettier-plugin-svelte (ts)

Issue:
Broken change for div with `class`
Testing v1.3.0 with previous formatting on v1.2.1 resulted in this change:

```
-    <div class="met-ex metropolis02">
-      Growth <b>&</b> Usage
+    <divclass="met-ex metropolis02">
+      Growth
+      <b>&</b>
+      Usage
```


Pull request:
Fix attribute/body order
Fixes #146 

Patch:
diff --git a/src/print/index.ts b/src/print/index.ts
index 8de0040..14cd52c 100644
--- a/src/print/index.ts
+++ b/src/print/index.ts
@@ -177,6 +177,8 @@ export function print(path: FastPath, options: ParserOptions, print: PrintFn): D
                     node.type !== 'Element' ||
                     selfClosingTags.indexOf(node.name) !== -1);
 
+            // Order important: print attributes first
+            const attributes = path.map((childPath) => childPath.call(print), 'attributes');
             let body: Doc;
 
             if (isEmpty) {
@@ -206,7 +208,7 @@ export function print(path: FastPath, options: ParserOptions, print: PrintFn): D
                                           close,
                                       ])
                                     : '',
-                                ...path.map((childPath) => childPath.call(print), 'attributes'),
+                                ...attributes,
                                 options.svelteBracketNewLine
                                     ? dedent(isSelfClosingTag ? line : softline)
                                     : '',
@@ -439,7 +441,7 @@ export function print(path: FastPath, options: ParserOptions, print: PrintFn): D
         case 'Comment': {
             /**
              * If there is no sibling node that starts right after us but the parent indicates
-             * that there used to be, that means that node was actually an embedded `<style>` 
+             * that there used to be, that means that node was actually an embedded `<style>`
              * or `<script>` node that was cut out.
              * If so, the comment does not refer to the next line we will see.
              * The `embed` function handles printing the comment in the right place.
@@ -545,7 +547,7 @@ function printChildren(path: FastPath, print: PrintFn): Doc[] {
      */
     function outputChildDoc(childDoc?: Doc, fromNode?: Node) {
         if (!isPreformat) {
-            if ((!childDoc || !fromNode || canBreakBefore(fromNode))) {
+            if (!childDoc || !fromNode || canBreakBefore(fromNode)) {
                 linebreakPossible();
 
                 const lastChild = childDocs[childDocs.length - 1];


Test patch:
diff --git a/test/formatting/index.ts b/test/formatting/index.ts
index df978bd..10fdbf1 100644
--- a/test/formatting/index.ts
+++ b/test/formatting/index.ts
@@ -2,7 +2,14 @@ import test from 'ava';
 import { readdirSync, readFileSync, existsSync } from 'fs';
 import { format } from 'prettier';
 
-const dirs = readdirSync('test/formatting/samples');
+let dirs = readdirSync('test/formatting/samples');
+const endsWithOnly = (f: string): boolean => f.endsWith('.only');
+const hasOnly = dirs.some(endsWithOnly);
+dirs = !hasOnly ? dirs : dirs.filter(endsWithOnly);
+
+if (process.env.CI && hasOnly) {
+    throw new Error('.only tests present');
+}
 
 for (const dir of dirs) {
     const input = readFileSync(`test/formatting/samples/${dir}/input.html`, 'utf-8').replace(
diff --git a/test/printer/index.ts b/test/printer/index.ts
index ac09bdb..6f38cd9 100644
--- a/test/printer/index.ts
+++ b/test/printer/index.ts
@@ -2,13 +2,20 @@ import test from 'ava';
 import { readdirSync, readFileSync, existsSync } from 'fs';
 import { format } from 'prettier';
 
-const files = readdirSync('test/printer/samples').filter(name => name.endsWith('.html'));
+let files = readdirSync('test/printer/samples').filter((name) => name.endsWith('.html'));
+const endsWithOnly = (f: string): boolean => f.endsWith('.only.html');
+const hasOnly = files.some(endsWithOnly);
+files = !hasOnly ? files : files.filter(endsWithOnly);
+
+if (process.env.CI && hasOnly) {
+    throw new Error('.only tests present');
+}
 
 for (const file of files) {
     const input = readFileSync(`test/printer/samples/${file}`, 'utf-8').replace(/\r?\n/g, '\n');
     const options = readOptions(`test/printer/samples/${file.replace('.html', '.options.json')}`);
 
-    test(`printer: ${file.slice(0, file.length - '.html'.length)}`, t => {
+    test(`printer: ${file.slice(0, file.length - '.html'.length)}`, (t) => {
         const actualOutput = format(input, {
             parser: 'svelte' as any,
             plugins: [require.resolve('../../src')],
diff --git a/test/printer/samples/element-with-class-and-comment-inside.html b/test/printer/samples/element-with-class-and-comment-inside.html
new file mode 100644
index 0000000..7529bb9
--- /dev/null
+++ b/test/printer/samples/element-with-class-and-comment-inside.html
@@ -0,0 +1,5 @@
+<div class="test">
+    <!-- c -->
+</div>
+
+<div class="test"><!-- c --></div>