Skip to content

Commit

Permalink
Add vue/no-constant-condition rule (#1401)
Browse files Browse the repository at this point in the history
* Add `vue/no-constant-condition` rule

* Comment out failing test cases

* Support `v-else-if`, `v-else` and `v-show` as well

* Update plugin docs (remove version, add "unreleased" notice)

* Remove `v-else` again 🤦
  • Loading branch information
FloEdelmann committed Jan 3, 2021
1 parent 42a543d commit 6b62278
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/rules/README.md
Expand Up @@ -347,6 +347,7 @@ The following rules extend the rules provided by ESLint itself and apply them to
| [vue/key-spacing](./key-spacing.md) | enforce consistent spacing between keys and values in object literal properties | :wrench: |
| [vue/keyword-spacing](./keyword-spacing.md) | enforce consistent spacing before and after keywords | :wrench: |
| [vue/max-len](./max-len.md) | enforce a maximum line length | |
| [vue/no-constant-condition](./no-constant-condition.md) | disallow constant expressions in conditions | |
| [vue/no-empty-pattern](./no-empty-pattern.md) | disallow empty destructuring patterns | |
| [vue/no-extra-parens](./no-extra-parens.md) | disallow unnecessary parentheses | :wrench: |
| [vue/no-irregular-whitespace](./no-irregular-whitespace.md) | disallow irregular whitespace | |
Expand Down
26 changes: 26 additions & 0 deletions docs/rules/no-constant-condition.md
@@ -0,0 +1,26 @@
---
pageClass: rule-details
sidebarDepth: 0
title: vue/no-constant-condition
description: disallow constant expressions in conditions
---
# vue/no-constant-condition

> disallow constant expressions in conditions
- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> ***This rule has not been released yet.*** </badge>

This rule is the same rule as core [no-constant-condition] rule but it applies to the expressions in `<template>`.

## :books: Further Reading

- [no-constant-condition]

[no-constant-condition]: https://eslint.org/docs/rules/no-constant-condition

## :mag: Implementation

- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-constant-condition.js)
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-constant-condition.js)

<sup>Taken with ❤️ [from ESLint core](https://eslint.org/docs/rules/no-constant-condition)</sup>
1 change: 1 addition & 0 deletions lib/index.js
Expand Up @@ -53,6 +53,7 @@ module.exports = {
'no-bare-strings-in-template': require('./rules/no-bare-strings-in-template'),
'no-boolean-default': require('./rules/no-boolean-default'),
'no-confusing-v-for-v-if': require('./rules/no-confusing-v-for-v-if'),
'no-constant-condition': require('./rules/no-constant-condition'),
'no-custom-modifiers-on-v-model': require('./rules/no-custom-modifiers-on-v-model'),
'no-deprecated-data-object-declaration': require('./rules/no-deprecated-data-object-declaration'),
'no-deprecated-destroyed-lifecycle': require('./rules/no-deprecated-destroyed-lifecycle'),
Expand Down
29 changes: 29 additions & 0 deletions lib/rules/no-constant-condition.js
@@ -0,0 +1,29 @@
/**
* @author Flo Edelmann
*/
'use strict'

const { wrapCoreRule } = require('../utils')

const conditionalDirectiveNames = new Set(['v-show', 'v-if', 'v-else-if'])

// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories
module.exports = wrapCoreRule('no-constant-condition', {
create(_context, { coreHandlers }) {
return {
VDirectiveKey(node) {
if (
conditionalDirectiveNames.has(`v-${node.name.name}`) &&
node.parent.value &&
node.parent.value.expression &&
coreHandlers.IfStatement
) {
coreHandlers.IfStatement({
// @ts-expect-error -- Process expression of VExpressionContainer as IfStatement.
test: node.parent.value.expression
})
}
}
}
}
})
113 changes: 113 additions & 0 deletions tests/lib/rules/no-constant-condition.js
@@ -0,0 +1,113 @@
/**
* @author Flo Edelmann
*/
'use strict'

const { RuleTester } = require('eslint')
const rule = require('../../../lib/rules/no-constant-condition.js')

const tester = new RuleTester({
parser: require.resolve('vue-eslint-parser'),
parserOptions: { ecmaVersion: 6 }
})

tester.run('no-constant-condition', rule, {
valid: [
'<template><CustomButton v-if="a" /></template>',
'<template><CustomButton v-if="a == 0" /></template>',
'<template><CustomButton v-if="a == f()" /></template>',
'<template><CustomButton v-other-directive="true" /></template>'
],
invalid: [
{
code: '<template><CustomButton v-if="-2" /></template>',
errors: [
{
messageId: 'unexpected',
type: 'UnaryExpression',
column: 31,
endColumn: 33
}
]
},
{
code: '<template><CustomButton v-else-if="true" /></template>',
errors: [
{
messageId: 'unexpected',
type: 'Literal',
column: 36,
endColumn: 40
}
]
},
{
code: '<template><CustomButton v-if="1" /></template>',
errors: [
{
messageId: 'unexpected',
type: 'Literal',
column: 31,
endColumn: 32
}
]
},
{
code: '<template><CustomButton v-show="{}" /></template>',
errors: [
{
messageId: 'unexpected',
type: 'ObjectExpression',
column: 33,
endColumn: 35
}
]
},
{
code: '<template><CustomButton v-if="0 < 1" /></template>',
errors: [
{
messageId: 'unexpected',
type: 'BinaryExpression',
column: 31,
endColumn: 36
}
]
},
{
code: '<template><CustomButton v-if="0 || 1" /></template>',
errors: [
{
messageId: 'unexpected',
type: 'LogicalExpression',
column: 31,
endColumn: 37
}
]
}

// failing in Node.js v8, because template literals are not supported there:
// {
// code: '<template><CustomButton v-if="`foo`" /></template>',
// errors: [
// {
// messageId: 'unexpected',
// type: 'TemplateLiteral',
// column: 31,
// endColumn: 36
// }
// ]
// },
// {
// code: '<template><CustomButton v-if="``" /></template>',
// errors: [
// {
// messageId: 'unexpected',
// type: 'TemplateLiteral',
// column: 31,
// endColumn: 33
// }
// ]
// }
]
})

0 comments on commit 6b62278

Please sign in to comment.