Skip to content

⭐️New: Add rule no-boolean-default #612

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Feb 3, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi
| | Rule ID | Description |
|:---|:--------|:------------|
| | [vue/no-async-in-computed-properties](./docs/rules/no-async-in-computed-properties.md) | disallow asynchronous actions in computed properties |
| | [vue/no-boolean-default](./docs/rules/no-boolean-default.md) | Prevents boolean defaults from being set |
| | [vue/no-dupe-keys](./docs/rules/no-dupe-keys.md) | disallow duplication of field names |
| | [vue/no-duplicate-attributes](./docs/rules/no-duplicate-attributes.md) | disallow duplication of attributes |
| | [vue/no-parsing-error](./docs/rules/no-parsing-error.md) | disallow parsing errors in `<template>` |
Expand Down
38 changes: 38 additions & 0 deletions docs/rules/no-boolean-default.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Prevents boolean defaults from being set (vue/no-boolean-default)

- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.

Please describe the origin of the rule here.


## Rule Details

This rule aims to...

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

```js

// fill me in

```

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

```js

// fill me in

```

### Options

If there are any options, describe them here. Otherwise, delete this section.

## When Not To Use It

Give a short description of when it would be appropriate to turn off this rule.

## Further Reading

If there are other links that describe the issue this rule addresses, please include them here in a bulleted list.
1 change: 1 addition & 0 deletions lib/configs/essential.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module.exports = {
extends: require.resolve('./base'),
rules: {
'vue/no-async-in-computed-properties': 'error',
'vue/no-boolean-default': 'error',
'vue/no-dupe-keys': 'error',
'vue/no-duplicate-attributes': 'error',
'vue/no-parsing-error': 'error',
Expand Down
1 change: 1 addition & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module.exports = {
'mustache-interpolation-spacing': require('./rules/mustache-interpolation-spacing'),
'name-property-casing': require('./rules/name-property-casing'),
'no-async-in-computed-properties': require('./rules/no-async-in-computed-properties'),
'no-boolean-default': require('./rules/no-boolean-default'),
'no-confusing-v-for-v-if': require('./rules/no-confusing-v-for-v-if'),
'no-dupe-keys': require('./rules/no-dupe-keys'),
'no-duplicate-attributes': require('./rules/no-duplicate-attributes'),
Expand Down
108 changes: 108 additions & 0 deletions lib/rules/no-boolean-default.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/**
* @fileoverview Prevents boolean defaults from being set
* @author Hiroki Osame
*/
'use strict'

const utils = require('../utils')

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

module.exports = {
meta: {
docs: {
description: 'disallow boolean defaults',
category: 'essential',
recommended: false,
url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v5.0.0-beta.3/docs/rules/no-boolean-default.md'
},
fixable: 'code',
schema: [
{
enum: ['default-false', 'no-default', 'constructor']
}
]
},

create (context) {
function getPropsDef (vueComp) {
return vueComp.properties.find(p =>
p.type === 'Property' &&
p.key.type === 'Identifier' &&
p.key.name === 'props' &&
p.value.type === 'ObjectExpression'
)
}

function getBooleanProps (propsDef) {
return propsDef.value.properties
.filter(p => {
return (p.value.type === 'ObjectExpression') && p.value.properties.find(p => (
p.key.type === 'Identifier' &&
p.key.name === 'type' &&
p.value.type === 'Identifier' &&
p.value.name === 'Boolean'
))
})
}

function getDefaultNode (propDef) {
return propDef.value.properties.find(p => (p.key.type === 'Identifier' && p.key.name === 'default'))
}

return utils.executeOnVueComponent(context, (obj) => {
const propsDef = getPropsDef(obj)

if (!propsDef) { return }

const booleanProps = getBooleanProps(propsDef)

if (!booleanProps.length) { return }

const booleanType = context.options[0] || 'constructor'

booleanProps.forEach((propDef) => {
const defaultNode = getDefaultNode(propDef)

switch (booleanType) {
case 'no-default':
if (defaultNode) {
context.report({
node: defaultNode,
message: 'Boolean prop should not set a default (Vue defaults it to false).'
})
}
break

case 'default-false':
if (defaultNode.value.value !== false) {
context.report({
node: defaultNode,
message: 'Boolean prop should be defaulted to false.'
})
}
break

default:
const nonConstProperties = propDef.value.properties.filter(p => p.key.name !== 'type')

let fix
if (
nonConstProperties.length === 0 ||
(nonConstProperties.length === 1 && (nonConstProperties[0].key.name === 'default' && nonConstProperties[0].value.value === false))
) {
fix = fixer => fixer.replaceText(propDef.value, 'Boolean')
}

context.report({
node: propDef,
message: 'Boolean prop should use a constructor.',
fix
})
}
})
})
}
}
113 changes: 113 additions & 0 deletions tests/lib/rules/no-boolean-default.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/**
* @fileoverview Prevents boolean defaults from being set
* @author Hiroki Osame
*/
'use strict'

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

var rule = require('../../../lib/rules/no-boolean-default')

var RuleTester = require('eslint').RuleTester

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

var ruleTester = new RuleTester({
parserOptions: {
ecmaVersion: 2015,
sourceType: 'module'
}
})
ruleTester.run('no-boolean-default', rule, {

valid: [
{
filename: 'test.vue',
code: `
export default {
props: {
enabled: Boolean
}
}
`
}
],

invalid: [
{
filename: 'test.vue',
code: `
export default {
props: {
enabled: {
type: Boolean,
default: true,
}
}
}
`,
options: ['default-false'],
errors: [{
message: 'Boolean prop should be defaulted to false.',
line: 6
}]
},
{
filename: 'test.vue',
code: `
export default {
props: {
enabled: {
type: Boolean,
default: null,
}
}
}
`,
options: ['default-false'],
errors: [{
message: 'Boolean prop should be defaulted to false.',
line: 6
}]
},
{
filename: 'test.vue',
code: `
export default {
props: {
enabled: {
type: Boolean,
default: false,
}
}
}
`,
options: ['no-default'],
errors: [{
message: 'Boolean prop should not set a default (Vue defaults it to false).',
line: 6
}]
},
{
filename: 'test.vue',
code: `
export default {
props: {
enabled: {
type: Boolean,
}
}
}
`,
options: ['constructor'],
errors: [{
message: 'Boolean prop should use a constructor.',
line: 4
}]
}
]
})