Initial commit
This commit is contained in:
Коммит
fb243e652b
|
@ -0,0 +1 @@
|
|||
node_modules/
|
|
@ -0,0 +1,44 @@
|
|||
# eslint-plugin-amo
|
||||
|
||||
ESLint plugin for AMO.
|
||||
|
||||
## Installation
|
||||
|
||||
You'll first need to install [ESLint](http://eslint.org):
|
||||
|
||||
```
|
||||
$ npm i eslint --save-dev
|
||||
```
|
||||
|
||||
Next, install `eslint-plugin-amo`:
|
||||
|
||||
```
|
||||
$ npm install eslint-plugin-amo --save-dev
|
||||
```
|
||||
|
||||
**Note:** If you installed ESLint globally (using the `-g` flag) then you must
|
||||
also install `eslint-plugin-amo` globally.
|
||||
|
||||
## Usage
|
||||
|
||||
Add `amo` to the plugins section of your `.eslintrc` configuration file. You can
|
||||
omit the `eslint-plugin-` prefix:
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": [
|
||||
"amo"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Then configure the rules you want to use under the rules section.
|
||||
|
||||
```json
|
||||
{
|
||||
"rules": {
|
||||
"amo/rule-name": 2
|
||||
}
|
||||
}
|
||||
```
|
|
@ -0,0 +1,13 @@
|
|||
"use strict";
|
||||
|
||||
var requireIndex = require("requireindex");
|
||||
|
||||
// import all rules in lib/rules
|
||||
module.exports.rules = requireIndex(__dirname + "/rules");
|
||||
|
||||
// Default configuration.
|
||||
module.exports.configs = {
|
||||
recommended: {
|
||||
'amo/i18n-no-tagged-templates': 2,
|
||||
},
|
||||
};
|
|
@ -0,0 +1,67 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
docs: {
|
||||
category: 'Possible Errors',
|
||||
description: 'Ensure no template literal tags are passed to i18n methods',
|
||||
recommended: true,
|
||||
},
|
||||
messages: {
|
||||
noTemplateLiteralTags: 'Do not use a template literal tag such as "{{ tag }}" when calling a `i18n` method.',
|
||||
},
|
||||
fixable: true,
|
||||
schema: [],
|
||||
},
|
||||
|
||||
create: (context) => {
|
||||
const METHODS = {
|
||||
gettext: [0],
|
||||
dgettext: [1],
|
||||
dcgettext: [1],
|
||||
ngettext: [0, 1],
|
||||
dngettext: [1, 2],
|
||||
dcngettext: [1, 2],
|
||||
pgettext: [1],
|
||||
dpgettext: [2],
|
||||
dcpgettext: [2],
|
||||
npgettext: [1, 2],
|
||||
dnpgettext: [2, 3],
|
||||
dcnpgettext: [2, 3],
|
||||
};
|
||||
|
||||
return {
|
||||
'CallExpression': (node) => {
|
||||
const { callee, arguments: args } = node;
|
||||
|
||||
if (!callee.type === 'MemberExpression' || !args.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { object, property } = node.callee;
|
||||
|
||||
if (!object || !object.name || object.name !== 'i18n') {
|
||||
return;
|
||||
}
|
||||
|
||||
const positions = METHODS[property.name] || [];
|
||||
|
||||
positions.forEach((position) => {
|
||||
const arg = args[position];
|
||||
if (arg.type === 'TaggedTemplateExpression') {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'noTemplateLiteralTags',
|
||||
data: {
|
||||
tag: arg.tag.name,
|
||||
},
|
||||
fix: (fixer) => {
|
||||
return fixer.remove(arg.tag);
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "eslint-plugin-amo",
|
||||
"version": "0.0.0",
|
||||
"description": "ESLint plugin for AMO",
|
||||
"keywords": [
|
||||
"eslint",
|
||||
"eslintplugin",
|
||||
"eslint-plugin"
|
||||
],
|
||||
"author": "Mozilla Add-ons Team",
|
||||
"license": "MPL-2.0",
|
||||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
"test": "mocha tests --recursive"
|
||||
},
|
||||
"dependencies": {
|
||||
"requireindex": "~1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^4.19.1",
|
||||
"mocha": "^5.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.x"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
"use strict";
|
||||
|
||||
const rule = require("../../../lib/rules/i18n-no-tagged-templates");
|
||||
const RuleTester = require("eslint").RuleTester;
|
||||
|
||||
const ruleTester = new RuleTester({
|
||||
parserOptions: {
|
||||
ecmaVersion: 6,
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const invalidExample = (code) => ({
|
||||
code,
|
||||
errors: [{
|
||||
messageId: 'noTemplateLiteralTags',
|
||||
data: {
|
||||
tag: 'tag',
|
||||
},
|
||||
}],
|
||||
});
|
||||
|
||||
ruleTester.run("i18n-no-tagged-templates", rule, {
|
||||
valid: [
|
||||
"i18n.gettext('hello')",
|
||||
'i18n.gettext(`hello`)',
|
||||
'i18n.gettext(`hello\n\nworld`)',
|
||||
'i18n.dgettext(tag`domain`, `some content`)',
|
||||
"i18n.ngettext('singular', `plural`)",
|
||||
"<p>{i18n.gettext(`plural`)}</p>",
|
||||
],
|
||||
invalid: [
|
||||
invalidExample("i18n.gettext(tag`translated string`)"),
|
||||
invalidExample("i18n.dgettext('domain', tag`translated string`)"),
|
||||
invalidExample("i18n.dcgettext('domain', tag`translated string`)"),
|
||||
invalidExample("i18n.dcgettext('domain', tag`translated string`)"),
|
||||
invalidExample("i18n.ngettext('singular', tag`plural`)"),
|
||||
invalidExample("i18n.dngettext('domain', 'singular', tag`plural`)"),
|
||||
invalidExample("i18n.dngettext('domain', tag`singular`, `plural`)"),
|
||||
// test with multiple tags
|
||||
{
|
||||
code: "i18n.dngettext('domain', someTag`singular`, someTag`plural`)",
|
||||
errors: [
|
||||
{ messageId: 'noTemplateLiteralTags', data: { tag: 'someTag' } },
|
||||
{ messageId: 'noTemplateLiteralTags', data: { tag: 'someTag' } },
|
||||
],
|
||||
},
|
||||
invalidExample('<p>{i18n.gettext(tag`translated string`)}</p>'),
|
||||
// test with `--fix`
|
||||
{
|
||||
code: '<p>{i18n.gettext(tagToRemove`translated string`)}</p>',
|
||||
errors: [
|
||||
{ messageId: 'noTemplateLiteralTags', data: { tag: 'tagToRemove' } },
|
||||
],
|
||||
output: '<p>{i18n.gettext(`translated string`)}</p>',
|
||||
},
|
||||
// test with `--fix` and multiple tags
|
||||
{
|
||||
code: '<p>{i18n.ngettext(t1`singular`, t2`plural`)}</p>',
|
||||
errors: [
|
||||
{ messageId: 'noTemplateLiteralTags', data: { tag: 't1' } },
|
||||
{ messageId: 'noTemplateLiteralTags', data: { tag: 't2' } },
|
||||
],
|
||||
output: '<p>{i18n.ngettext(`singular`, `plural`)}</p>',
|
||||
},
|
||||
]
|
||||
});
|
Загрузка…
Ссылка в новой задаче