-
-
Notifications
You must be signed in to change notification settings - Fork 668
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
1 parent
db3a1c1
commit 4d79ceb
Showing
6 changed files
with
376 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
--- | ||
pageClass: rule-details | ||
sidebarDepth: 0 | ||
title: vue/multiline-ternary | ||
description: Enforce newlines between operands of ternary expressions in `<template>` | ||
--- | ||
# vue/multiline-ternary | ||
|
||
> Enforce newlines between operands of ternary expressions in `<template>` | ||
- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> ***This rule has not been released yet.*** </badge> | ||
- :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 [multiline-ternary] rule but it applies to the expressions in `<template>` and `<style>`. | ||
|
||
## :book: Rule Details | ||
|
||
<eslint-code-block fix :rules="{'vue/multiline-ternary': ['error']}"> | ||
|
||
```vue | ||
<template> | ||
<div> | ||
<!-- ✓ GOOD --> | ||
<div :class="isEnabled | ||
? 'check' | ||
: 'stop'" /> | ||
<!-- ✗ BAD --> | ||
<div :class="isEnabled ? 'check' : 'stop'" /> | ||
</div> | ||
</template> | ||
<style> | ||
div { | ||
/* ✓ GOOD */ | ||
color: v-bind('myFlag | ||
? foo | ||
: bar'); | ||
/* ✗ BAD */ | ||
color: v-bind('myFlag ? foo : bar'); | ||
} | ||
</style> | ||
``` | ||
|
||
</eslint-code-block> | ||
|
||
## :books: Further Reading | ||
|
||
- [multiline-ternary] | ||
|
||
[multiline-ternary]: https://eslint.org/docs/rules/multiline-ternary | ||
|
||
## :mag: Implementation | ||
|
||
- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/multiline-ternary.js) | ||
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/multiline-ternary.js) | ||
|
||
<sup>Taken with ❤️ [from ESLint core](https://eslint.org/docs/rules/multiline-ternary)</sup> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/** | ||
* @author dev1437 | ||
* See LICENSE file in root directory for full license. | ||
*/ | ||
'use strict' | ||
|
||
// ------------------------------------------------------------------------------ | ||
// Requirements | ||
// ------------------------------------------------------------------------------ | ||
|
||
const { wrapCoreRule } = require('../utils') | ||
|
||
// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories | ||
module.exports = wrapCoreRule('multiline-ternary', { | ||
skipDynamicArguments: true, | ||
applyDocument: true | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,297 @@ | ||
/** | ||
* @author dev1437 | ||
* See LICENSE file in root directory for full license. | ||
*/ | ||
'use strict' | ||
|
||
const { RuleTester, ESLint } = require('../../eslint-compat') | ||
const rule = require('../../../lib/rules/multiline-ternary') | ||
const semver = require('semver') | ||
|
||
const tester = new RuleTester({ | ||
parser: require.resolve('vue-eslint-parser'), | ||
parserOptions: { | ||
ecmaVersion: 2020, | ||
sourceType: 'module' | ||
} | ||
}) | ||
|
||
tester.run('multiline-ternary', rule, { | ||
valid: [ | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<template> | ||
<div :class="{ | ||
'test': someReallyLongCondition ? | ||
aVeryLongOutput : | ||
thisCantFitOnASingleLine | ||
}"> | ||
</div> | ||
</template> | ||
` | ||
}, | ||
{ | ||
// doesn't check ternary statements in <script> block | ||
filename: 'test.vue', | ||
code: ` | ||
<script> | ||
let test = someReallyLongCondition ? aVeryLongOutput : thisCantFitOnASingleLine | ||
</script> | ||
` | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<template> | ||
<div :class="{ | ||
'test': someReallyLongCondition ? aVeryLongOutput : thisCantFitOnASingleLine | ||
}"> | ||
</div> | ||
</template> | ||
`, | ||
options: ['never'] | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<template> | ||
<div class="test"> | ||
</div> | ||
</template> | ||
<style> | ||
.test { | ||
color: v-bind('someReallyLongCondition ? aVeryLongOutput : thisCantFitOnASingleLine') | ||
} | ||
</style> | ||
`, | ||
options: ['never'] | ||
} | ||
], | ||
invalid: [ | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<template> | ||
<div :class="{ | ||
'test': someReallyLongCondition ? | ||
aVeryLongOutput : thisCantFitOnASingleLine | ||
}"> | ||
</div> | ||
</template> | ||
`, | ||
output: semver.gte(ESLint.version, '7.1.0') | ||
? ` | ||
<template> | ||
<div :class="{ | ||
'test': someReallyLongCondition ? | ||
aVeryLongOutput | ||
: thisCantFitOnASingleLine | ||
}"> | ||
</div> | ||
</template> | ||
` | ||
: null, | ||
errors: [ | ||
{ | ||
message: | ||
'Expected newline between consequent and alternate of ternary expression.', | ||
line: 5, | ||
column: 15 | ||
} | ||
], | ||
options: ['always-multiline'] | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<template> | ||
<div :class="{ | ||
'test': someReallyLongCondition ? | ||
aVeryLongOutput : thisCantFitOnASingleLine | ||
}"> | ||
</div> | ||
</template> | ||
`, | ||
output: semver.gte(ESLint.version, '7.1.0') | ||
? ` | ||
<template> | ||
<div :class="{ | ||
'test': someReallyLongCondition ?aVeryLongOutput : thisCantFitOnASingleLine | ||
}"> | ||
</div> | ||
</template> | ||
` | ||
: null, | ||
errors: [ | ||
{ | ||
message: | ||
'Unexpected newline between test and consequent of ternary expression.', | ||
line: 4, | ||
column: 21 | ||
} | ||
], | ||
options: ['never'] | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<template> | ||
<div :class="{ | ||
'test': someReallyLongCondition ? aVeryLongOutput : thisCantFitOnASingleLine | ||
}"> | ||
</div> | ||
</template> | ||
`, | ||
output: semver.gte(ESLint.version, '7.1.0') | ||
? ` | ||
<template> | ||
<div :class="{ | ||
'test': someReallyLongCondition | ||
? aVeryLongOutput | ||
: thisCantFitOnASingleLine | ||
}"> | ||
</div> | ||
</template> | ||
` | ||
: null, | ||
errors: [ | ||
{ | ||
message: | ||
'Expected newline between test and consequent of ternary expression.', | ||
line: 4, | ||
column: 21 | ||
}, | ||
{ | ||
message: | ||
'Expected newline between consequent and alternate of ternary expression.', | ||
line: 4, | ||
column: 47 | ||
} | ||
] | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<template> | ||
<div :style="{ | ||
'test': someReallyLongCondition ? aVeryLongOutput : thisCantFitOnASingleLine | ||
}"> | ||
</div> | ||
</template> | ||
`, | ||
output: semver.gte(ESLint.version, '7.1.0') | ||
? ` | ||
<template> | ||
<div :style="{ | ||
'test': someReallyLongCondition | ||
? aVeryLongOutput | ||
: thisCantFitOnASingleLine | ||
}"> | ||
</div> | ||
</template> | ||
` | ||
: null, | ||
errors: [ | ||
{ | ||
message: | ||
'Expected newline between test and consequent of ternary expression.', | ||
line: 4, | ||
column: 21 | ||
}, | ||
{ | ||
message: | ||
'Expected newline between consequent and alternate of ternary expression.', | ||
line: 4, | ||
column: 47 | ||
} | ||
] | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<template> | ||
<div class="test"> | ||
</div> | ||
</template> | ||
<style> | ||
.test { | ||
color: v-bind('someReallyLongCondition ? aVeryLongOutput : thisCantFitOnASingleLine') | ||
} | ||
</style> | ||
`, | ||
output: semver.gte(ESLint.version, '7.1.0') | ||
? ` | ||
<template> | ||
<div class="test"> | ||
</div> | ||
</template> | ||
<style> | ||
.test { | ||
color: v-bind('someReallyLongCondition | ||
? aVeryLongOutput | ||
: thisCantFitOnASingleLine') | ||
} | ||
</style> | ||
` | ||
: null, | ||
errors: [ | ||
{ | ||
message: | ||
'Expected newline between test and consequent of ternary expression.', | ||
line: 8, | ||
column: 30 | ||
}, | ||
{ | ||
message: | ||
'Expected newline between consequent and alternate of ternary expression.', | ||
line: 8, | ||
column: 56 | ||
} | ||
] | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<template> | ||
<div :class="{ | ||
'test': someReallyLongCondition ? aVeryLongOutput : thisCantFitOnASingleLine | ||
}"> | ||
</div> | ||
</template> | ||
<script> | ||
let test = someReallyLongCondition ? aVeryLongOutput : thisCantFitOnASingleLine | ||
</script> | ||
`, | ||
output: semver.gte(ESLint.version, '7.1.0') | ||
? ` | ||
<template> | ||
<div :class="{ | ||
'test': someReallyLongCondition | ||
? aVeryLongOutput | ||
: thisCantFitOnASingleLine | ||
}"> | ||
</div> | ||
</template> | ||
<script> | ||
let test = someReallyLongCondition ? aVeryLongOutput : thisCantFitOnASingleLine | ||
</script> | ||
` | ||
: null, | ||
errors: [ | ||
{ | ||
message: | ||
'Expected newline between test and consequent of ternary expression.', | ||
line: 4, | ||
column: 19 | ||
}, | ||
{ | ||
message: | ||
'Expected newline between consequent and alternate of ternary expression.', | ||
line: 4, | ||
column: 45 | ||
} | ||
] | ||
} | ||
] | ||
}) |