forked from ember-cli/eslint-plugin-ember
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtemplate-require-input-type.js
More file actions
129 lines (119 loc) · 4.16 KB
/
template-require-input-type.js
File metadata and controls
129 lines (119 loc) · 4.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
const rule = require('../../../lib/rules/template-require-input-type');
const RuleTester = require('eslint').RuleTester;
const ERROR_MISSING = 'All `<input>` elements should have a `type` attribute';
const errInvalid = (value) => `\`<input type="${value}">\` is not a valid input type`;
const validHbs = [
'<input type="text" />',
'<input type="email" />',
'<input type="checkbox" />',
'<input type="submit" />',
'<input type="datetime-local" />',
'<input type="{{this.inputType}}" />',
'<input type={{this.inputType}} />',
'<div />',
'<div type="foo" />',
'<MyInput type="unknown" />',
// Default (requireExplicit=false): missing `type` is allowed.
'<input />',
'<input name="email" />',
];
const invalidHbs = [
{
code: '<input type="" />',
output: '<input type="text" />',
errors: [{ message: errInvalid('') }],
},
{
code: '<input type="foo" />',
output: '<input type="text" />',
errors: [{ message: errInvalid('foo') }],
},
{
code: '<input type="TEXTY" />',
output: '<input type="text" />',
errors: [{ message: errInvalid('TEXTY') }],
},
// Valueless type attribute — per HTML spec resolves to the missing-value
// default (Text state), same runtime result as `type=""`. Flag and autofix
// to `type="text"`. (Output loses the pre-slash space because the
// valueless attr range ends at `type`; prettier will re-insert if needed.)
{
code: '<input type />',
output: '<input type="text"/>',
errors: [{ message: errInvalid('') }],
},
];
const requireExplicitInvalid = [
{
code: '<input />',
options: [{ requireExplicit: true }],
output: '<input type="text" />',
errors: [{ message: ERROR_MISSING }],
},
{
code: '<input name="email" />',
options: [{ requireExplicit: true }],
output: '<input type="text" name="email" />',
errors: [{ message: ERROR_MISSING }],
},
{
code: '<input name="email" />',
options: [{ requireExplicit: true }],
output: '<input type="text" name="email" />',
errors: [{ message: ERROR_MISSING }],
},
];
const requireExplicitValid = [
// With requireExplicit: an explicit known type satisfies the rule.
{ code: '<input type="text" />', options: [{ requireExplicit: true }] },
// Dynamic type also satisfies — we can't know the runtime value.
{ code: '<input type={{this.inputType}} />', options: [{ requireExplicit: true }] },
];
const gjsValid = validHbs.map((code) => `<template>${code}</template>`);
const gjsInvalid = invalidHbs.map(({ code, output, errors }) => ({
code: `<template>${code}</template>`,
output: `<template>${output}</template>`,
errors,
}));
const gjsRuleTester = new RuleTester({
parser: require.resolve('ember-eslint-parser'),
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
});
gjsRuleTester.run('template-require-input-type', rule, {
valid: [
...gjsValid,
...requireExplicitValid.map(({ code, options }) => ({
code: `<template>${code}</template>`,
options,
})),
// Scope-shadowed `input` — the template's `<input>` refers to the local
// const binding (a component), not the native HTML element. The rule
// skips it via `isNativeElement`'s scope check.
`const input = 'foo';
<template><input type="not-a-valid-type" /></template>`,
`const input = 'foo';
<template><input /></template>`,
// Block-param shadowing — `<Foo as |input|>` binds `input` inside the
// yield block. The inner `<input>` should resolve to the block-param,
// not the native tag.
`import Foo from 'whatever';
<template><Foo as |input|><input type="not-a-valid-type" /></Foo></template>`,
],
invalid: [
...gjsInvalid,
...requireExplicitInvalid.map(({ code, options, output, errors }) => ({
code: `<template>${code}</template>`,
options,
output: `<template>${output}</template>`,
errors,
})),
],
});
const hbsRuleTester = new RuleTester({
parser: require.resolve('ember-eslint-parser/hbs'),
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
});
hbsRuleTester.run('template-require-input-type', rule, {
valid: [...validHbs, ...requireExplicitValid],
invalid: [...invalidHbs, ...requireExplicitInvalid],
});