Skip to content

Commit

Permalink
New: no-template-curly-in-string rule (fixes #6186) (#6767)
Browse files Browse the repository at this point in the history
* New: wrong-quotes-for-template-string rule (fixes #6186)

* Review fixes

* Rename wrong-quotes-for-template-string to no-template-curly-in-string

* Simplify regex

* Update error message

* Use const instead of var

* Update docs
  • Loading branch information
jfmengels authored and ilyavolodin committed Aug 9, 2016
1 parent 80789ab commit be68f0b
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 0 deletions.
1 change: 1 addition & 0 deletions conf/eslint.json
Expand Up @@ -223,6 +223,7 @@
"vars-on-top": "off",
"wrap-iife": "off",
"wrap-regex": "off",
"no-template-curly-in-string": "off",
"yield-star-spacing": "off",
"yoda": "off"
}
Expand Down
33 changes: 33 additions & 0 deletions docs/rules/no-template-curly-in-string.md
@@ -0,0 +1,33 @@
# Disallow template literal placeholder syntax in regular strings (no-template-curly-in-string)

ECMAScript 6 allows programmers to create strings containing variable or expressions using template literals, instead of string concatenation, by writing expressions like `${variable}` between two backtick quotes (\`). It can be easy to use the wrong quotes when wanting to use template literals, by writing `"${variable}"`, and end up with the literal value `"${variable}"` instead of a string containing the value of the injected expressions.


## Rule Details

This rule aims to warn when a regular string contains what looks like a template literal placeholder. It will warn when it finds a string containing the template literal place holder (`${something}`) that uses either `\"` or `\'` for the quotes.

## Examples

Examples of **incorrect** code for this rule:

```js
/*eslint no-template-curly-in-string: "error"*/
"Hello ${name}!";
'Hello ${name}!';
"Time: ${12 * 60 * 60 * 1000}";
```

Examples of **correct** code for this rule:

```js
/*eslint no-template-curly-in-string: "error"*/
`Hello ${name}!`;
`Time: ${12 * 60 * 60 * 1000}`;

templateFunction`Hello ${name}`;
```

## When Not To Use It

This rule should not be used in ES3/5 environments.
37 changes: 37 additions & 0 deletions lib/rules/no-template-curly-in-string.js
@@ -0,0 +1,37 @@
/**
* @fileoverview Warn when using template string syntax in regular strings
* @author Jeroen Engels
*/
"use strict";

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

module.exports = {
meta: {
docs: {
description: "Disallow template literal placeholder syntax in regular strings",
category: "Possible Errors",
recommended: false
},

schema: []
},

create: function(context) {
const regex = /\$\{[^}]+\}/;

return {
Literal: function(node) {
if (typeof node.value === "string" && regex.test(node.value)) {
context.report({
node: node,
message: "Unexpected template string expression."
});
}
}
};

}
};
79 changes: 79 additions & 0 deletions tests/lib/rules/no-template-curly-in-string.js
@@ -0,0 +1,79 @@
/**
* @fileoverview Warn when using template string syntax in regular strings.
* @author Jeroen Engels
*/
"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const rule = require("../../../lib/rules/no-template-curly-in-string"),
RuleTester = require("../../../lib/testers/rule-tester");


//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

const ruleTester = new RuleTester();

const message = "Unexpected template string expression.";
const parserOptions = { ecmaVersion: 6 };

ruleTester.run("no-template-curly-in-string", rule, {
valid: [
{ code: "`Hello, ${name}`;", parserOptions },
{ code: "templateFunction`Hello, ${name}`;", parserOptions },
{ code: "`Hello, name`;", parserOptions },
{ code: "'Hello, name';", parserOptions },
{ code: "'Hello, ' + name;", parserOptions },
{ code: "`Hello, ${index + 1}`", parserOptions },
{ code: "`Hello, ${name + \" foo\"}`", parserOptions },
{ code: "`Hello, ${name || \"foo\"}`", parserOptions },
{ code: "`Hello, ${{foo: \"bar\"}.foo}`", parserOptions },
{ code: "'$2'", parserOptions },
{ code: "'${'", parserOptions },
{ code: "'$}'", parserOptions },
{ code: "'{foo}'", parserOptions },
{ code: "'{foo: \"bar\"}'", parserOptions },
{ code: "const number = 3", parserOptions }
],
invalid: [
{
code: "'Hello, ${name}'",
parserOptions,
errors: [{ message }]
},
{
code: "\"Hello, ${name}\"",
parserOptions,
errors: [{ message }]
},
{
code: "'${greeting}, ${name}'",
parserOptions,
errors: [{ message }]
},
{
code: "'Hello, ${index + 1}'",
parserOptions,
errors: [{ message }]
},
{
code: "'Hello, ${name + \" foo\"}'",
parserOptions,
errors: [{ message }]
},
{
code: "'Hello, ${name || \"foo\"}'",
parserOptions,
errors: [{ message }]
},
{
code: "'Hello, ${{foo: \"bar\"}.foo}'",
parserOptions,
errors: [{ message }]
}
]
});

0 comments on commit be68f0b

Please sign in to comment.