Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4d79ceb

Browse files
dev1437FloEdelmann
andauthored
Create vue/multiline-ternary extension rule (#1996)
* Create initial multiline ternary rule * Docs * Linting * Tests and apply Document * Fix import * Fix tests * Fix test * Run npm run update * Update tests * lint * Update doc * Add tests for script tag * Update tests/lib/rules/multiline-ternary.js Co-authored-by: Flo Edelmann <florian-edelmann@online.de> * Add example * Lint Co-authored-by: Flo Edelmann <florian-edelmann@online.de>
1 parent db3a1c1 commit 4d79ceb

File tree

6 files changed

+376
-0
lines changed

6 files changed

+376
-0
lines changed

‎docs/rules/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ The following rules extend the rules provided by ESLint itself and apply them to
292292
| [vue/key-spacing](./key-spacing.md) | Enforce consistent spacing between keys and values in object literal properties in `<template>` | :wrench: | :lipstick: |
293293
| [vue/keyword-spacing](./keyword-spacing.md) | Enforce consistent spacing before and after keywords in `<template>` | :wrench: | :lipstick: |
294294
| [vue/max-len](./max-len.md) | enforce a maximum line length in `.vue` files | | :lipstick: |
295+
| [vue/multiline-ternary](./multiline-ternary.md) | Enforce newlines between operands of ternary expressions in `<template>` | :wrench: | :lipstick: |
295296
| [vue/no-constant-condition](./no-constant-condition.md) | Disallow constant expressions in conditions in `<template>` | | :warning: |
296297
| [vue/no-empty-pattern](./no-empty-pattern.md) | Disallow empty destructuring patterns in `<template>` | | :warning: |
297298
| [vue/no-extra-parens](./no-extra-parens.md) | Disallow unnecessary parentheses in `<template>` | :wrench: | :lipstick: |

‎docs/rules/multiline-ternary.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
---
2+
pageClass: rule-details
3+
sidebarDepth: 0
4+
title: vue/multiline-ternary
5+
description: Enforce newlines between operands of ternary expressions in `<template>`
6+
---
7+
# vue/multiline-ternary
8+
9+
> Enforce newlines between operands of ternary expressions in `<template>`
10+
11+
- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> ***This rule has not been released yet.*** </badge>
12+
- :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.
13+
14+
This rule is the same rule as core [multiline-ternary] rule but it applies to the expressions in `<template>` and `<style>`.
15+
16+
## :book: Rule Details
17+
18+
<eslint-code-block fix :rules="{'vue/multiline-ternary': ['error']}">
19+
20+
```vue
21+
<template>
22+
<div>
23+
<!-- ✓ GOOD -->
24+
<div :class="isEnabled
25+
? 'check'
26+
: 'stop'" />
27+
28+
<!-- ✗ BAD -->
29+
<div :class="isEnabled ? 'check' : 'stop'" />
30+
</div>
31+
</template>
32+
33+
<style>
34+
div {
35+
/* ✓ GOOD */
36+
color: v-bind('myFlag
37+
? foo
38+
: bar');
39+
40+
/* ✗ BAD */
41+
color: v-bind('myFlag ? foo : bar');
42+
}
43+
</style>
44+
```
45+
46+
</eslint-code-block>
47+
48+
## :books: Further Reading
49+
50+
- [multiline-ternary]
51+
52+
[multiline-ternary]: https://eslint.org/docs/rules/multiline-ternary
53+
54+
## :mag: Implementation
55+
56+
- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/multiline-ternary.js)
57+
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/multiline-ternary.js)
58+
59+
<sup>Taken with ❤️ [from ESLint core](https://eslint.org/docs/rules/multiline-ternary)</sup>

‎lib/configs/no-layout-rules.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ module.exports = {
3131
'vue/max-attributes-per-line': 'off',
3232
'vue/max-len': 'off',
3333
'vue/multiline-html-element-content-newline': 'off',
34+
'vue/multiline-ternary': 'off',
3435
'vue/mustache-interpolation-spacing': 'off',
3536
'vue/new-line-between-multi-line-property': 'off',
3637
'vue/no-extra-parens': 'off',

‎lib/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ module.exports = {
5454
'max-len': require('./rules/max-len'),
5555
'multi-word-component-names': require('./rules/multi-word-component-names'),
5656
'multiline-html-element-content-newline': require('./rules/multiline-html-element-content-newline'),
57+
'multiline-ternary': require('./rules/multiline-ternary'),
5758
'mustache-interpolation-spacing': require('./rules/mustache-interpolation-spacing'),
5859
'new-line-between-multi-line-property': require('./rules/new-line-between-multi-line-property'),
5960
'next-tick-style': require('./rules/next-tick-style'),

‎lib/rules/multiline-ternary.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* @author dev1437
3+
* See LICENSE file in root directory for full license.
4+
*/
5+
'use strict'
6+
7+
// ------------------------------------------------------------------------------
8+
// Requirements
9+
// ------------------------------------------------------------------------------
10+
11+
const { wrapCoreRule } = require('../utils')
12+
13+
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories
14+
module.exports = wrapCoreRule('multiline-ternary', {
15+
skipDynamicArguments: true,
16+
applyDocument: true
17+
})

‎tests/lib/rules/multiline-ternary.js

Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
/**
2+
* @author dev1437
3+
* See LICENSE file in root directory for full license.
4+
*/
5+
'use strict'
6+
7+
const { RuleTester, ESLint } = require('../../eslint-compat')
8+
const rule = require('../../../lib/rules/multiline-ternary')
9+
const semver = require('semver')
10+
11+
const tester = new RuleTester({
12+
parser: require.resolve('vue-eslint-parser'),
13+
parserOptions: {
14+
ecmaVersion: 2020,
15+
sourceType: 'module'
16+
}
17+
})
18+
19+
tester.run('multiline-ternary', rule, {
20+
valid: [
21+
{
22+
filename: 'test.vue',
23+
code: `
24+
<template>
25+
<div :class="{
26+
'test': someReallyLongCondition ?
27+
aVeryLongOutput :
28+
thisCantFitOnASingleLine
29+
}">
30+
</div>
31+
</template>
32+
`
33+
},
34+
{
35+
// doesn't check ternary statements in <script> block
36+
filename: 'test.vue',
37+
code: `
38+
<script>
39+
let test = someReallyLongCondition ? aVeryLongOutput : thisCantFitOnASingleLine
40+
</script>
41+
`
42+
},
43+
{
44+
filename: 'test.vue',
45+
code: `
46+
<template>
47+
<div :class="{
48+
'test': someReallyLongCondition ? aVeryLongOutput : thisCantFitOnASingleLine
49+
}">
50+
</div>
51+
</template>
52+
`,
53+
options: ['never']
54+
},
55+
{
56+
filename: 'test.vue',
57+
code: `
58+
<template>
59+
<div class="test">
60+
</div>
61+
</template>
62+
<style>
63+
.test {
64+
color: v-bind('someReallyLongCondition ? aVeryLongOutput : thisCantFitOnASingleLine')
65+
}
66+
</style>
67+
`,
68+
options: ['never']
69+
}
70+
],
71+
invalid: [
72+
{
73+
filename: 'test.vue',
74+
code: `
75+
<template>
76+
<div :class="{
77+
'test': someReallyLongCondition ?
78+
aVeryLongOutput : thisCantFitOnASingleLine
79+
}">
80+
</div>
81+
</template>
82+
`,
83+
output: semver.gte(ESLint.version, '7.1.0')
84+
? `
85+
<template>
86+
<div :class="{
87+
'test': someReallyLongCondition ?
88+
aVeryLongOutput
89+
: thisCantFitOnASingleLine
90+
}">
91+
</div>
92+
</template>
93+
`
94+
: null,
95+
errors: [
96+
{
97+
message:
98+
'Expected newline between consequent and alternate of ternary expression.',
99+
line: 5,
100+
column: 15
101+
}
102+
],
103+
options: ['always-multiline']
104+
},
105+
{
106+
filename: 'test.vue',
107+
code: `
108+
<template>
109+
<div :class="{
110+
'test': someReallyLongCondition ?
111+
aVeryLongOutput : thisCantFitOnASingleLine
112+
}">
113+
</div>
114+
</template>
115+
`,
116+
output: semver.gte(ESLint.version, '7.1.0')
117+
? `
118+
<template>
119+
<div :class="{
120+
'test': someReallyLongCondition ?aVeryLongOutput : thisCantFitOnASingleLine
121+
}">
122+
</div>
123+
</template>
124+
`
125+
: null,
126+
errors: [
127+
{
128+
message:
129+
'Unexpected newline between test and consequent of ternary expression.',
130+
line: 4,
131+
column: 21
132+
}
133+
],
134+
options: ['never']
135+
},
136+
{
137+
filename: 'test.vue',
138+
code: `
139+
<template>
140+
<div :class="{
141+
'test': someReallyLongCondition ? aVeryLongOutput : thisCantFitOnASingleLine
142+
}">
143+
</div>
144+
</template>
145+
`,
146+
output: semver.gte(ESLint.version, '7.1.0')
147+
? `
148+
<template>
149+
<div :class="{
150+
'test': someReallyLongCondition
151+
? aVeryLongOutput
152+
: thisCantFitOnASingleLine
153+
}">
154+
</div>
155+
</template>
156+
`
157+
: null,
158+
errors: [
159+
{
160+
message:
161+
'Expected newline between test and consequent of ternary expression.',
162+
line: 4,
163+
column: 21
164+
},
165+
{
166+
message:
167+
'Expected newline between consequent and alternate of ternary expression.',
168+
line: 4,
169+
column: 47
170+
}
171+
]
172+
},
173+
{
174+
filename: 'test.vue',
175+
code: `
176+
<template>
177+
<div :style="{
178+
'test': someReallyLongCondition ? aVeryLongOutput : thisCantFitOnASingleLine
179+
}">
180+
</div>
181+
</template>
182+
`,
183+
output: semver.gte(ESLint.version, '7.1.0')
184+
? `
185+
<template>
186+
<div :style="{
187+
'test': someReallyLongCondition
188+
? aVeryLongOutput
189+
: thisCantFitOnASingleLine
190+
}">
191+
</div>
192+
</template>
193+
`
194+
: null,
195+
errors: [
196+
{
197+
message:
198+
'Expected newline between test and consequent of ternary expression.',
199+
line: 4,
200+
column: 21
201+
},
202+
{
203+
message:
204+
'Expected newline between consequent and alternate of ternary expression.',
205+
line: 4,
206+
column: 47
207+
}
208+
]
209+
},
210+
{
211+
filename: 'test.vue',
212+
code: `
213+
<template>
214+
<div class="test">
215+
</div>
216+
</template>
217+
<style>
218+
.test {
219+
color: v-bind('someReallyLongCondition ? aVeryLongOutput : thisCantFitOnASingleLine')
220+
}
221+
</style>
222+
`,
223+
output: semver.gte(ESLint.version, '7.1.0')
224+
? `
225+
<template>
226+
<div class="test">
227+
</div>
228+
</template>
229+
<style>
230+
.test {
231+
color: v-bind('someReallyLongCondition
232+
? aVeryLongOutput
233+
: thisCantFitOnASingleLine')
234+
}
235+
</style>
236+
`
237+
: null,
238+
errors: [
239+
{
240+
message:
241+
'Expected newline between test and consequent of ternary expression.',
242+
line: 8,
243+
column: 30
244+
},
245+
{
246+
message:
247+
'Expected newline between consequent and alternate of ternary expression.',
248+
line: 8,
249+
column: 56
250+
}
251+
]
252+
},
253+
{
254+
filename: 'test.vue',
255+
code: `
256+
<template>
257+
<div :class="{
258+
'test': someReallyLongCondition ? aVeryLongOutput : thisCantFitOnASingleLine
259+
}">
260+
</div>
261+
</template>
262+
<script>
263+
let test = someReallyLongCondition ? aVeryLongOutput : thisCantFitOnASingleLine
264+
</script>
265+
`,
266+
output: semver.gte(ESLint.version, '7.1.0')
267+
? `
268+
<template>
269+
<div :class="{
270+
'test': someReallyLongCondition
271+
? aVeryLongOutput
272+
: thisCantFitOnASingleLine
273+
}">
274+
</div>
275+
</template>
276+
<script>
277+
let test = someReallyLongCondition ? aVeryLongOutput : thisCantFitOnASingleLine
278+
</script>
279+
`
280+
: null,
281+
errors: [
282+
{
283+
message:
284+
'Expected newline between test and consequent of ternary expression.',
285+
line: 4,
286+
column: 19
287+
},
288+
{
289+
message:
290+
'Expected newline between consequent and alternate of ternary expression.',
291+
line: 4,
292+
column: 45
293+
}
294+
]
295+
}
296+
]
297+
})

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /