From eb61d51ff4142e548584860d246dff613236f7f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sajn=C3=B3g?= Date: Tue, 24 Jul 2018 11:38:01 +0200 Subject: [PATCH 1/3] Add no-string-prop-type rule - basic implementation --- docs/rules/no-string-prop-type.md | 62 +++++++++++++++++++ lib/rules/no-string-prop-type.js | 77 ++++++++++++++++++++++++ tests/lib/rules/no-string-prop-type.js | 83 ++++++++++++++++++++++++++ 3 files changed, 222 insertions(+) create mode 100644 docs/rules/no-string-prop-type.md create mode 100644 lib/rules/no-string-prop-type.js create mode 100644 tests/lib/rules/no-string-prop-type.js diff --git a/docs/rules/no-string-prop-type.md b/docs/rules/no-string-prop-type.md new file mode 100644 index 000000000..79446ec2d --- /dev/null +++ b/docs/rules/no-string-prop-type.md @@ -0,0 +1,62 @@ +# disallow usage of strings as prop types (no-string-prop-type) + +... + + +## Rule Details + +This rule aims to... + +Examples of **incorrect** code for this rule: + +```js +export default { + props: { + myProp: "Number", + anotherProp: ["Number", "String"], + myFieldWithBadType: { + type: "Object", + default: function() { + return {} + }, + }, + myOtherFieldWithBadType: { + type: "Number", + default: 1, + }, + } +} +``` + +Examples of **correct** code for this rule: + +```js +export default { + props: { + myProp: Number, + anotherProp: [Number, String], + myFieldWithBadType: { + type: Object, + default: function() { + return {} + }, + }, + myOtherFieldWithBadType: { + type: Number, + default: 1, + }, + } +} +``` + +### Options + +- + +## When Not To Use It + +- + +## Further Reading + +- diff --git a/lib/rules/no-string-prop-type.js b/lib/rules/no-string-prop-type.js new file mode 100644 index 000000000..3934bf8b9 --- /dev/null +++ b/lib/rules/no-string-prop-type.js @@ -0,0 +1,77 @@ +/** + * @fileoverview disallow usage of strings as prop types + * @author Michał Sajnóg + */ +'use strict' + +const utils = require('../utils') + +// ------------------------------------------------------------------------------ +// Rule Definition +// ------------------------------------------------------------------------------ + +const message = '"type" property of prop should be of Object type, not String' + +module.exports = { + meta: { + docs: { + description: 'disallow usage of strings as prop types', + category: undefined, + url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.5.0/docs/rules/no-string-prop-type.md' + }, + fixable: 'code', // or "code" or "whitespace" + schema: [ + // fill in your schema + ] + }, + + create: function (context) { + const fix = node => fixer => { + return fixer.replaceText(node, node.value) + } + + return utils.executeOnVueComponent(context, (obj) => { + const node = obj.properties.find(p => + p.type === 'Property' && + p.key.type === 'Identifier' && + p.key.name === 'props' && + p.value.type === 'ObjectExpression' + ) + + if (!node) return + + node.value.properties.forEach(p => { + if (p.value.type === 'Literal') { + context.report({ + node: p.value, + message, + fix: fix(p.value) + }) + } else if (p.value.type === 'ArrayExpression') { + const wrongNode = p.value.elements.find(prop => prop.type === 'Literal') + + if (wrongNode) { + context.report({ + node: wrongNode, + message, + fix: fix(wrongNode) + }) + } + } else if (p.value.type === 'ObjectExpression') { + const wrongNode = p.value.properties.find(prop => + prop.type === 'Property' && + prop.key.name === 'type' && + prop.value.type === 'Literal' + ) + + if (wrongNode) { + context.report({ + node: wrongNode.value, + message + }) + } + } + }) + }) + } +} diff --git a/tests/lib/rules/no-string-prop-type.js b/tests/lib/rules/no-string-prop-type.js new file mode 100644 index 000000000..b59fddbc0 --- /dev/null +++ b/tests/lib/rules/no-string-prop-type.js @@ -0,0 +1,83 @@ +/** + * @fileoverview disallow usage of strings as prop types + * @author Michał Sajnóg + */ +'use strict' + +// ------------------------------------------------------------------------------ +// Requirements +// ------------------------------------------------------------------------------ + +const rule = require('../../../lib/rules/no-string-prop-type') +const RuleTester = require('eslint').RuleTester + +// ------------------------------------------------------------------------------ +// Tests +// ------------------------------------------------------------------------------ + +var ruleTester = new RuleTester({ + parserOptions: { + ecmaVersion: 7, + sourceType: 'module' + } +}) +ruleTester.run('no-string-prop-type', rule, { + + valid: [ + { + filename: 'SomeComponent.vue', + code: ` + export default { + props: { + myProp: Number, + anotherType: [Number, String], + extraProp: { + type: Number, + default: 10 + } + } + } + ` + } + ], + + invalid: [ + { + filename: 'SomeComponent.vue', + code: ` + export default { + props: { + myProp: 'Number', + anotherType: ['Number', 'String'], + extraProp: { + type: 'Number', + default: 10 + } + } + } + `, + output: ` + export default { + props: { + myProp: Number, + anotherType: [Number, String], + extraProp: { + type: 'Number', + default: 10 + } + } + } + `, + errors: [{ + message: '"type" property of prop should be of Object type, not String', + line: 4 + }, { + message: '"type" property of prop should be of Object type, not String', + line: 5 + }, { + message: '"type" property of prop should be of Object type, not String', + line: 7 + }] + } + ] +}) From da2898c11ea98dcac7cc983251ab62fe0f8fbc6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sajn=C3=B3g?= Date: Fri, 3 Aug 2018 18:49:05 +0200 Subject: [PATCH 2/3] Rename rule --- README.md | 1 + ...pe.md => require-prop-type-constructor.md} | 20 +---- lib/index.js | 1 + lib/rules/no-string-prop-type.js | 77 ------------------ lib/rules/require-prop-type-constructor.js | 81 +++++++++++++++++++ ...pe.js => require-prop-type-constructor.js} | 29 +++++-- 6 files changed, 109 insertions(+), 100 deletions(-) rename docs/rules/{no-string-prop-type.md => require-prop-type-constructor.md} (66%) delete mode 100644 lib/rules/no-string-prop-type.js create mode 100644 lib/rules/require-prop-type-constructor.js rename tests/lib/rules/{no-string-prop-type.js => require-prop-type-constructor.js} (64%) diff --git a/README.md b/README.md index 7870ed231..2da249f5e 100644 --- a/README.md +++ b/README.md @@ -230,6 +230,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi | | Rule ID | Description | |:---|:--------|:------------| | :wrench: | [vue/component-name-in-template-casing](./docs/rules/component-name-in-template-casing.md) | enforce specific casing for the component naming style in template | +| :wrench: | [vue/require-prop-type-constructor](./docs/rules/require-prop-type-constructor.md) | require prop type to be a constructor | | :wrench: | [vue/script-indent](./docs/rules/script-indent.md) | enforce consistent indentation in `