Skip to content

Commit 2bd2cb4

Browse files
author
Hideaki Matsunami
committed
feat: fixable match-component-file-name rule
improve vuejs#1816 For the following reasons why name option changed. If change file name, alto need to change import statement.
1 parent 4fc9116 commit 2bd2cb4

File tree

2 files changed

+165
-2
lines changed

2 files changed

+165
-2
lines changed

lib/rules/match-component-file-name.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ module.exports = {
3737
categories: undefined,
3838
url: 'https://eslint.vuejs.org/rules/match-component-file-name.html'
3939
},
40-
fixable: null,
40+
fixable: 'code',
4141
schema: [
4242
{
4343
type: 'object',
@@ -102,19 +102,25 @@ module.exports = {
102102
*/
103103
function verifyName(node) {
104104
let name
105+
let quote = ''
105106
if (node.type === 'TemplateLiteral') {
106107
const quasis = node.quasis[0]
107108
name = quasis.value.cooked
109+
quote = '`'
108110
} else {
109111
name = `${node.value}`
112+
quote = node.raw[0]
110113
}
111114

112115
if (!compareNames(name, filename)) {
113116
errors.push({
114117
node,
115118
message:
116119
'Component name `{{name}}` should match file name `{{filename}}`.',
117-
data: { filename, name }
120+
data: { filename, name },
121+
fix(fixer) {
122+
return fixer.replaceText(node, `${quote}${filename}${quote}`)
123+
}
118124
})
119125
}
120126
}

tests/lib/rules/match-component-file-name.js

+157
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,12 @@ ruleTester.run('match-component-file-name', rule, {
560560
render() { return <div /> }
561561
}
562562
`,
563+
output: `
564+
export default {
565+
name: 'MyComponent',
566+
render() { return <div /> }
567+
}
568+
`,
563569
parserOptions: jsxParserOptions,
564570
errors: [
565571
{
@@ -576,6 +582,35 @@ ruleTester.run('match-component-file-name', rule, {
576582
render() { return <div /> }
577583
}
578584
`,
585+
output: `
586+
export default {
587+
name: 'MyComponent',
588+
render() { return <div /> }
589+
}
590+
`,
591+
options: [{ extensions: ['jsx'] }],
592+
parserOptions: jsxParserOptions,
593+
errors: [
594+
{
595+
message:
596+
'Component name `MComponent` should match file name `MyComponent`.'
597+
}
598+
]
599+
},
600+
{
601+
filename: 'MyComponent.jsx',
602+
code: `
603+
export default {
604+
name: "MComponent",
605+
render() { return <div /> }
606+
}
607+
`,
608+
output: `
609+
export default {
610+
name: "MyComponent",
611+
render() { return <div /> }
612+
}
613+
`,
579614
options: [{ extensions: ['jsx'] }],
580615
parserOptions: jsxParserOptions,
581616
errors: [
@@ -593,6 +628,12 @@ ruleTester.run('match-component-file-name', rule, {
593628
render() { return <div /> }
594629
}
595630
`,
631+
output: `
632+
export default {
633+
name: \`MyComponent\`,
634+
render() { return <div /> }
635+
}
636+
`,
596637
options: [{ extensions: ['jsx'] }],
597638
parserOptions: jsxParserOptions,
598639
errors: [
@@ -614,6 +655,42 @@ ruleTester.run('match-component-file-name', rule, {
614655
}
615656
</script>
616657
`,
658+
output: `
659+
<script>
660+
export default {
661+
name: 'MyComponent',
662+
template: '<div />'
663+
}
664+
</script>
665+
`,
666+
options: [{ extensions: ['vue'] }],
667+
parser: require.resolve('vue-eslint-parser'),
668+
parserOptions,
669+
errors: [
670+
{
671+
message:
672+
'Component name `MComponent` should match file name `MyComponent`.'
673+
}
674+
]
675+
},
676+
{
677+
filename: 'MyComponent.vue',
678+
code: `
679+
<script>
680+
export default {
681+
name: "MComponent",
682+
template: '<div />'
683+
}
684+
</script>
685+
`,
686+
output: `
687+
<script>
688+
export default {
689+
name: "MyComponent",
690+
template: '<div />'
691+
}
692+
</script>
693+
`,
617694
options: [{ extensions: ['vue'] }],
618695
parser: require.resolve('vue-eslint-parser'),
619696
parserOptions,
@@ -634,6 +711,14 @@ ruleTester.run('match-component-file-name', rule, {
634711
}
635712
</script>
636713
`,
714+
output: `
715+
<script>
716+
export default {
717+
name: \`MyComponent\`,
718+
template: '<div />'
719+
}
720+
</script>
721+
`,
637722
options: [{ extensions: ['vue'] }],
638723
parser: require.resolve('vue-eslint-parser'),
639724
parserOptions,
@@ -654,6 +739,35 @@ ruleTester.run('match-component-file-name', rule, {
654739
template: '<div />'
655740
})
656741
`,
742+
output: `
743+
new Vue({
744+
name: 'MyComponent',
745+
template: '<div />'
746+
})
747+
`,
748+
options: [{ extensions: ['js'] }],
749+
parserOptions,
750+
errors: [
751+
{
752+
message:
753+
'Component name `MComponent` should match file name `MyComponent`.'
754+
}
755+
]
756+
},
757+
{
758+
filename: 'MyComponent.js',
759+
code: `
760+
new Vue({
761+
name: "MComponent",
762+
template: '<div />'
763+
})
764+
`,
765+
output: `
766+
new Vue({
767+
name: "MyComponent",
768+
template: '<div />'
769+
})
770+
`,
657771
options: [{ extensions: ['js'] }],
658772
parserOptions,
659773
errors: [
@@ -671,6 +785,12 @@ ruleTester.run('match-component-file-name', rule, {
671785
template: '<div />'
672786
})
673787
`,
788+
output: `
789+
new Vue({
790+
name: \`MyComponent\`,
791+
template: '<div />'
792+
})
793+
`,
674794
options: [{ extensions: ['js'] }],
675795
parserOptions,
676796
errors: [
@@ -687,6 +807,11 @@ ruleTester.run('match-component-file-name', rule, {
687807
name: 'MComponent',
688808
})
689809
`,
810+
output: `
811+
Vue.mixin({
812+
name: 'MyComponent',
813+
})
814+
`,
690815
options: [{ extensions: ['js'] }],
691816
parserOptions,
692817
errors: [
@@ -703,6 +828,11 @@ ruleTester.run('match-component-file-name', rule, {
703828
name: \`MComponent\`,
704829
})
705830
`,
831+
output: `
832+
Vue.mixin({
833+
name: \`MyComponent\`,
834+
})
835+
`,
706836
options: [{ extensions: ['js'] }],
707837
parserOptions,
708838
errors: [
@@ -719,6 +849,11 @@ ruleTester.run('match-component-file-name', rule, {
719849
template: '<div />'
720850
})
721851
`,
852+
output: `
853+
Vue.component('MyComponent', {
854+
template: '<div />'
855+
})
856+
`,
722857
options: [{ extensions: ['js'] }],
723858
parserOptions,
724859
errors: [
@@ -735,6 +870,11 @@ ruleTester.run('match-component-file-name', rule, {
735870
template: '<div />'
736871
})
737872
`,
873+
output: `
874+
Vue.component(\`MyComponent\`, {
875+
template: '<div />'
876+
})
877+
`,
738878
options: [{ extensions: ['js'] }],
739879
parserOptions,
740880
errors: [
@@ -751,6 +891,11 @@ ruleTester.run('match-component-file-name', rule, {
751891
template: '<div />'
752892
})
753893
`,
894+
output: `
895+
app.component(\`MyComponent\`, {
896+
template: '<div />'
897+
})
898+
`,
754899
options: [{ extensions: ['js'] }],
755900
parserOptions,
756901
errors: [
@@ -770,6 +915,12 @@ ruleTester.run('match-component-file-name', rule, {
770915
render() { return <div /> }
771916
}
772917
`,
918+
output: `
919+
export default {
920+
name: 'MyComponent',
921+
render() { return <div /> }
922+
}
923+
`,
773924
options: [{ shouldMatchCase: true }],
774925
parserOptions: jsxParserOptions,
775926
errors: [
@@ -787,6 +938,12 @@ ruleTester.run('match-component-file-name', rule, {
787938
render() { return <div /> }
788939
}
789940
`,
941+
output: `
942+
export default {
943+
name: 'my-component',
944+
render() { return <div /> }
945+
}
946+
`,
790947
options: [{ shouldMatchCase: true }],
791948
parserOptions: jsxParserOptions,
792949
errors: [

0 commit comments

Comments
 (0)