Repository: rwjblue/ember-template-lint (js)

Issue:
New Rule: `no-unnecessary-concatenation`
#### Bad

```hbs
<img src="{{url}}" alt="{{t "alternate-text"}}">
```

#### Good

```hbs
<img src={{url}} alt={{t "alternate-text"}}>
```

Pull request:
Add `no-unnecessary-concat` rule
Resolves #350 

/cc @rwjblue @tomdale

Patch:
diff --git a/lib/rules/index.js b/lib/rules/index.js
index 1797893..7194cf9 100644
--- a/lib/rules/index.js
+++ b/lib/rules/index.js
@@ -33,4 +33,5 @@ module.exports = {
   'no-trailing-spaces': require('./lint-no-trailing-spaces'),
   'quotes': require('./lint-quotes'),
   'no-trailing-dot-in-path-expression': require('./lint-trailing-dot-in-path-expression'),
+  'no-unnecessary-concat': require('./lint-no-unnecessary-concat'),
 };
diff --git a/lib/rules/lint-no-unnecessary-concat.js b/lib/rules/lint-no-unnecessary-concat.js
new file mode 100644
index 0000000..7e8221e
--- /dev/null
+++ b/lib/rules/lint-no-unnecessary-concat.js
@@ -0,0 +1,24 @@
+'use strict';
+
+const Rule = require('./base');
+
+module.exports = class NoUnnecessaryConcat extends Rule {
+  visitor() {
+    return {
+      ConcatStatement(node) {
+        if (node.parts.length === 1) {
+          let source = this.sourceForNode(node);
+          let innerSource = this.sourceForNode(node.parts[0]);
+          let message = `Unnecessary string concatenation. Use ${innerSource} instead of ${source}.`;
+
+          this.log({
+            message,
+            line: node.loc && node.loc.start.line,
+            column: node.loc && node.loc.start.column,
+            source
+          });
+        }
+      }
+    };
+  }
+};


Test patch:
diff --git a/test/unit/rules/lint-no-unnecessary-concat-test.js b/test/unit/rules/lint-no-unnecessary-concat-test.js
new file mode 100644
index 0000000..8f3a950
--- /dev/null
+++ b/test/unit/rules/lint-no-unnecessary-concat-test.js
@@ -0,0 +1,46 @@
+'use strict';
+
+const generateRuleTests = require('../../helpers/rule-test-harness');
+
+generateRuleTests({
+  name: 'no-unnecessary-concat',
+
+  config: true,
+
+  good: [
+    '<div class={{clazz}}></div>',
+    '<div class="first {{second}}"></div>',
+    '"{{foo}}"',
+  ],
+
+  bad: [
+    {
+      template: '<div class="{{clazz}}"></div>',
+
+      result: {
+        message: 'Unnecessary string concatenation. Use {{clazz}} instead of "{{clazz}}".',
+        moduleId: 'layout.hbs',
+        source: '"{{clazz}}"',
+        line: 1,
+        column: 11,
+      },
+    },
+    {
+      template: '<img src="{{url}}" alt="{{t "alternate-text"}}">',
+
+      results: [{
+        message: 'Unnecessary string concatenation. Use {{url}} instead of "{{url}}".',
+        moduleId: 'layout.hbs',
+        source: '"{{url}}"',
+        line: 1,
+        column: 9,
+      }, {
+        message: 'Unnecessary string concatenation. Use {{t "alternate-text"}} instead of "{{t "alternate-text"}}".',
+        moduleId: 'layout.hbs',
+        source: '"{{t "alternate-text"}}"',
+        line: 1,
+        column: 23,
+      }],
+    },
+  ],
+});