Skip to content

Commit

Permalink
Add vue/space-in-parens rule (#1157)
Browse files Browse the repository at this point in the history
* ⭐️New: Add `vue/space-in-parens` rule

* update

* update

* update
  • Loading branch information
ota-meshi committed May 23, 2020
1 parent 812f6bb commit 625e271
Show file tree
Hide file tree
Showing 5 changed files with 248 additions and 1 deletion.
23 changes: 23 additions & 0 deletions docs/rules/space-in-parens.md
@@ -0,0 +1,23 @@
---
pageClass: rule-details
sidebarDepth: 0
title: vue/space-in-parens
description: enforce consistent spacing inside parentheses
---
# vue/space-in-parens
> enforce consistent spacing inside parentheses
- :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.

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

## :books: Further reading

- [space-in-parens]

[space-in-parens]: https://eslint.org/docs/rules/space-in-parens

## :mag: Implementation

- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/space-in-parens.js)
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/space-in-parens.js)
1 change: 1 addition & 0 deletions lib/configs/no-layout-rules.js
Expand Up @@ -32,6 +32,7 @@ module.exports = {
'vue/padding-line-between-blocks': 'off',
'vue/script-indent': 'off',
'vue/singleline-html-element-content-newline': 'off',
'vue/space-in-parens': 'off',
'vue/space-infix-ops': 'off',
'vue/space-unary-ops': 'off',
'vue/template-curly-spacing': 'off'
Expand Down
12 changes: 12 additions & 0 deletions lib/rules/space-in-parens.js
@@ -0,0 +1,12 @@
/**
* @author Yosuke Ota
*/
'use strict'

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

// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories
module.exports = wrapCoreRule(
require('eslint/lib/rules/space-in-parens'),
{ skipDynamicArguments: true, skipDynamicArgumentsReport: true }
)
8 changes: 7 additions & 1 deletion lib/utils/index.js
Expand Up @@ -117,7 +117,9 @@ function wrapContextToOverrideReportMethodToSkipDynamicArgument (context) {
report (descriptor, ...args) {
let range = null
if (descriptor.loc) {
range = [sourceCode.getIndexFromLoc(descriptor.loc.start), sourceCode.getIndexFromLoc(descriptor.loc.end)]
const startLoc = isLoc(descriptor.loc.start) ? descriptor.loc.start : descriptor.loc
const endLoc = descriptor.loc.end || startLoc
range = [sourceCode.getIndexFromLoc(startLoc), sourceCode.getIndexFromLoc(endLoc)]
} else if (descriptor.node) {
range = descriptor.node.range
}
Expand All @@ -131,6 +133,10 @@ function wrapContextToOverrideReportMethodToSkipDynamicArgument (context) {
context.report(descriptor, ...args)
}
}

function isLoc (loc) {
return loc && typeof loc === 'object' && typeof loc.line === 'number' && typeof loc.column === 'number'
}
}

// ------------------------------------------------------------------------------
Expand Down
205 changes: 205 additions & 0 deletions tests/lib/rules/space-in-parens.js
@@ -0,0 +1,205 @@
/**
* @author Yosuke Ota
*/
'use strict'

const { RuleTester, CLIEngine } = require('eslint')
const semver = require('semver')
const rule = require('../../../lib/rules/space-in-parens')

const errorMessage = semver.lt(CLIEngine.version, '6.4.0')
? (obj) => {
const messageId = obj.messageId
delete obj.messageId
obj.message = messageId.startsWith('missing') ? 'There must be a space inside this paren.' : 'There should be no spaces inside this paren.'
return obj
}
: obj => obj

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

tester.run('space-in-parens', rule, {
valid: [
`<template>
<button
@click="foo(arg)"
/>
</template>`,
{
code: `
<template>
<button
@click="foo( arg )"
/>
</template>`,
options: ['always']
},
`
<template>
<button
:[foo(arg)]="foo(arg)"
/>
</template>`,
{
code: `
<template>
<button
:[foo(arg)]="foo( arg )"
/>
</template>`,
options: ['always']
}
],
invalid: [
{
code: `
<template>
<button
@click="foo( arg )"
/>
</template>`,
output: `
<template>
<button
@click="foo(arg)"
/>
</template>`,
errors: [
errorMessage({
messageId: 'rejectedOpeningSpace',
line: 4
}),
errorMessage({
messageId: 'rejectedClosingSpace',
line: 4
})
]
},
{
code: `
<template>
<button
@click="foo(arg)"
/>
</template>`,
options: ['always'],
output: `
<template>
<button
@click="foo( arg )"
/>
</template>`,
errors: [
errorMessage({
messageId: 'missingOpeningSpace',
line: 4
}),
errorMessage({
messageId: 'missingClosingSpace',
line: 4
})
]
},
{
code: `
<template>
<input
:value="( 1 + 2 ) + 3"
>
</template>`,
output: `
<template>
<input
:value="(1 + 2) + 3"
>
</template>`,
errors: [
errorMessage({
messageId: 'rejectedOpeningSpace',
line: 4
}),
errorMessage({
messageId: 'rejectedClosingSpace',
line: 4
})
]
},
{
code: `
<template>
<input
:value="(1 + 2) + 3"
>
</template>`,
options: ['always'],
output: `
<template>
<input
:value="( 1 + 2 ) + 3"
>
</template>`,
errors: [
errorMessage({
messageId: 'missingOpeningSpace',
line: 4
}),
errorMessage({
messageId: 'missingClosingSpace',
line: 4
})
]
},
{
code: `
<template>
<input
:[(1+2)]="( 1 + 2 ) + 3"
>
</template>`,
output: `
<template>
<input
:[(1+2)]="(1 + 2) + 3"
>
</template>`,
errors: [
errorMessage({
messageId: 'rejectedOpeningSpace',
line: 4
}),
errorMessage({
messageId: 'rejectedClosingSpace',
line: 4
})
]
},
{
code: `
<template>
<input
:[(1+2)]="(1 + 2) + 3"
>
</template>`,
options: ['always'],
output: `
<template>
<input
:[(1+2)]="( 1 + 2 ) + 3"
>
</template>`,
errors: [
errorMessage({
messageId: 'missingOpeningSpace',
line: 4
}),
errorMessage({
messageId: 'missingClosingSpace',
line: 4
})
]
}
]
})

0 comments on commit 625e271

Please sign in to comment.