@mui/internal-code-infra 0.0.4-canary.73 → 0.0.4-canary.75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/package.json +7 -5
  2. package/src/brokenLinksChecker/crawlWorker.mjs +23 -0
  3. package/src/cli/cmdPublish.mjs +32 -3
  4. package/src/brokenLinksChecker/__fixtures__/static-site/broken-links.html +0 -20
  5. package/src/brokenLinksChecker/__fixtures__/static-site/broken-targets.html +0 -22
  6. package/src/brokenLinksChecker/__fixtures__/static-site/example.md +0 -20
  7. package/src/brokenLinksChecker/__fixtures__/static-site/external-links.html +0 -21
  8. package/src/brokenLinksChecker/__fixtures__/static-site/ignored-page.html +0 -17
  9. package/src/brokenLinksChecker/__fixtures__/static-site/index.html +0 -29
  10. package/src/brokenLinksChecker/__fixtures__/static-site/invalid-html.html +0 -15
  11. package/src/brokenLinksChecker/__fixtures__/static-site/known-targets.json +0 -5
  12. package/src/brokenLinksChecker/__fixtures__/static-site/nested/page.html +0 -21
  13. package/src/brokenLinksChecker/__fixtures__/static-site/orphaned-page.html +0 -20
  14. package/src/brokenLinksChecker/__fixtures__/static-site/page-with-api-links.html +0 -20
  15. package/src/brokenLinksChecker/__fixtures__/static-site/page-with-custom-targets.html +0 -24
  16. package/src/brokenLinksChecker/__fixtures__/static-site/page-with-ignored-content.html +0 -28
  17. package/src/brokenLinksChecker/__fixtures__/static-site/page-with-known-target-links.html +0 -19
  18. package/src/brokenLinksChecker/__fixtures__/static-site/unclosed-tags.html +0 -1
  19. package/src/brokenLinksChecker/__fixtures__/static-site/valid.html +0 -20
  20. package/src/brokenLinksChecker/__fixtures__/static-site/with-anchors.html +0 -31
  21. package/src/brokenLinksChecker/index.test.ts +0 -301
  22. package/src/changelog/categorizeCommits.test.ts +0 -319
  23. package/src/changelog/filterCommits.test.ts +0 -363
  24. package/src/changelog/parseCommitLabels.test.ts +0 -509
  25. package/src/changelog/renderChangelog.test.ts +0 -378
  26. package/src/changelog/sortSections.test.ts +0 -199
  27. package/src/cli/cmdVale.test.mjs +0 -644
  28. package/src/eslint/mui/rules/add-undef-to-optional.test.mjs +0 -361
  29. package/src/eslint/mui/rules/consistent-production-guard.test.mjs +0 -162
  30. package/src/eslint/mui/rules/disallow-active-elements-as-key-event-target.test.mjs +0 -66
  31. package/src/eslint/mui/rules/disallow-react-api-in-server-components.test.mjs +0 -305
  32. package/src/eslint/mui/rules/docgen-ignore-before-comment.test.mjs +0 -52
  33. package/src/eslint/mui/rules/flatten-parentheses.test.mjs +0 -245
  34. package/src/eslint/mui/rules/mui-name-matches-component-name.test.mjs +0 -247
  35. package/src/eslint/mui/rules/no-empty-box.test.mjs +0 -40
  36. package/src/eslint/mui/rules/no-floating-cleanup.test.mjs +0 -141
  37. package/src/eslint/mui/rules/no-guarded-throw.test.mjs +0 -206
  38. package/src/eslint/mui/rules/no-presentation-role.test.mjs +0 -33
  39. package/src/eslint/mui/rules/no-styled-box.test.mjs +0 -73
  40. package/src/eslint/mui/rules/require-dev-wrapper.test.mjs +0 -265
  41. package/src/eslint/mui/rules/rules-of-use-theme-variants.test.mjs +0 -149
  42. package/src/eslint/mui/rules/straight-quotes.test.mjs +0 -67
  43. package/src/remark/firstBlockHeading.test.mjs +0 -107
  44. package/src/remark/gitDiff.test.mjs +0 -45
  45. package/src/remark/noSpaceInLinks.test.mjs +0 -22
  46. package/src/remark/straightQuotes.test.mjs +0 -25
  47. package/src/remark/tableAlignment.test.mjs +0 -28
  48. package/src/remark/terminalLanguage.test.mjs +0 -17
  49. package/src/utils/build.test.mjs +0 -1263
  50. package/src/utils/pnpm.test.mjs +0 -731
  51. package/src/utils/template.test.mjs +0 -133
  52. package/src/utils/typescript.test.mjs +0 -341
@@ -1,247 +0,0 @@
1
- import eslint from 'eslint';
2
- import parser from '@typescript-eslint/parser';
3
- import rule from './mui-name-matches-component-name.mjs';
4
-
5
- const ruleTester = new eslint.RuleTester({
6
- languageOptions: {
7
- parser,
8
- },
9
- });
10
-
11
- ruleTester.run('mui-name-matches-component-name', rule, {
12
- valid: [
13
- // useThemeProps
14
- `
15
- const StaticDateRangePicker = React.forwardRef(function StaticDateRangePicker<TDate>(
16
- inProps: StaticDateRangePickerProps<TDate>,
17
- ref: React.Ref<HTMLDivElement>,
18
- ) {
19
- const props = useThemeProps({ props: inProps, name: 'MuiStaticDateRangePicker' });
20
- });
21
- `,
22
- `
23
- function CssBaseline(inProps) {
24
- useThemeProps({ props: inProps, name: 'MuiCssBaseline' });
25
- }
26
- `,
27
- `
28
- const Container = createContainer({
29
- createStyledComponent: styled('div', {
30
- name: 'MuiContainer',
31
- slot: 'Root',
32
- overridesResolver: (props, styles) => {
33
- const { ownerState } = props;
34
-
35
- return [
36
- styles.root,
37
- ownerState.fixed && styles.fixed,
38
- ownerState.disableGutters && styles.disableGutters,
39
- ];
40
- },
41
- }),
42
- useThemeProps: (inProps) => useThemeProps({ props: inProps, name: 'MuiContainer' }),
43
- });
44
- `,
45
- `
46
- const Grid = createGrid({
47
- createStyledComponent: styled('div', {
48
- name: 'MuiGrid',
49
- overridesResolver: (props, styles) => styles.root,
50
- }),
51
- componentName: 'MuiGrid',
52
- useThemeProps: (inProps) => useThemeProps({ props: inProps, name: 'MuiGrid' }),
53
- }) as OverridableComponent<GridTypeMap>;
54
- `,
55
- {
56
- code: `
57
- function useDatePickerDefaultizedProps(props, name) {
58
- useThemeProps({ props, name });
59
- }
60
- `,
61
- options: [{ customHooks: ['useDatePickerDefaultizedProps'] }],
62
- },
63
- // ================
64
- // useDefaultProps
65
- `
66
- const StaticDateRangePicker = React.forwardRef(function StaticDateRangePicker<TDate>(
67
- inProps: StaticDateRangePickerProps<TDate>,
68
- ref: React.Ref<HTMLDivElement>,
69
- ) {
70
- const props = useDefaultProps({ props: inProps, name: 'MuiStaticDateRangePicker' });
71
- });
72
- `,
73
- `
74
- function CssBaseline(inProps) {
75
- useDefaultProps({ props: inProps, name: 'MuiCssBaseline' });
76
- }
77
- `,
78
- `
79
- const Container = createContainer({
80
- createStyledComponent: styled('div', {
81
- name: 'MuiContainer',
82
- slot: 'Root',
83
- overridesResolver: (props, styles) => {
84
- const { ownerState } = props;
85
-
86
- return [
87
- styles.root,
88
- ownerState.fixed && styles.fixed,
89
- ownerState.disableGutters && styles.disableGutters,
90
- ];
91
- },
92
- }),
93
- useDefaultProps: (inProps) => useDefaultProps({ props: inProps, name: 'MuiContainer' }),
94
- });
95
- `,
96
- `
97
- const Grid = createGrid({
98
- createStyledComponent: styled('div', {
99
- name: 'MuiGrid',
100
- overridesResolver: (props, styles) => styles.root,
101
- }),
102
- componentName: 'MuiGrid',
103
- useDefaultProps: (inProps) => useDefaultProps({ props: inProps, name: 'MuiGrid' }),
104
- }) as OverridableComponent<GridTypeMap>;
105
- `,
106
- {
107
- code: `
108
- const StaticDateRangePicker = React.forwardRef(function StaticDateRangePicker<TDate>(
109
- inProps: StaticDateRangePickerProps<TDate>,
110
- ref: React.Ref<HTMLDivElement>,
111
- ) {
112
- const props = useDatePickerDefaultizedProps(inProps, 'MuiStaticDateRangePicker');
113
- });
114
- `,
115
- options: [{ customHooks: ['useDatePickerDefaultizedProps'] }],
116
- },
117
- {
118
- code: `
119
- function useDatePickerDefaultizedProps(props, name) {
120
- useDefaultProps({ props, name });
121
- }
122
- `,
123
- options: [{ customHooks: ['useDatePickerDefaultizedProps'] }],
124
- },
125
- ],
126
- invalid: [
127
- // useThemeProps
128
- {
129
- code: `
130
- const StaticDateRangePicker = React.forwardRef(function StaticDateRangePicker<TDate>(
131
- inProps: StaticDateRangePickerProps<TDate>,
132
- ref: React.Ref<HTMLDivElement>,
133
- ) {
134
- const props = useThemeProps({ props: inProps, name: 'MuiPickersDateRangePicker' });
135
- });
136
- `,
137
- errors: [
138
- {
139
- message:
140
- "Expected `name` to be 'MuiStaticDateRangePicker' but instead got 'MuiPickersDateRangePicker'.",
141
- },
142
- ],
143
- },
144
- {
145
- code: 'useThemeProps({ props: inProps })',
146
- errors: [
147
- {
148
- message: 'Unable to find `name` property. Did you forget to pass `name`?',
149
- },
150
- ],
151
- },
152
- {
153
- code: 'useThemeProps({ props: inProps, name })',
154
- errors: [
155
- {
156
- message:
157
- 'Unable to resolve `name`. Please hardcode the `name` i.e. use a string literal.',
158
- },
159
- ],
160
- },
161
- {
162
- code: "useThemeProps({ props: inProps, name: 'MuiPickersDateRangePicker' })",
163
- errors: [
164
- {
165
- message: 'Unable to find component for this call.',
166
- },
167
- ],
168
- },
169
- {
170
- code: `
171
- const StaticDateRangePicker = React.forwardRef(function StaticDateRangePicker<TDate>(
172
- inProps: StaticDateRangePickerProps<TDate>,
173
- ref: React.Ref<HTMLDivElement>,
174
- ) {
175
- const props = useDatePickerDefaultizedProps(inProps, 'MuiPickersDateRangePicker');
176
- });
177
- `,
178
- options: [{ customHooks: ['useDatePickerDefaultizedProps'] }],
179
- errors: [
180
- {
181
- message:
182
- "Expected `name` to be 'MuiStaticDateRangePicker' but instead got 'MuiPickersDateRangePicker'.",
183
- },
184
- ],
185
- },
186
- // ================
187
- // useDefaultProps
188
- {
189
- code: `
190
- const StaticDateRangePicker = React.forwardRef(function StaticDateRangePicker<TDate>(
191
- inProps: StaticDateRangePickerProps<TDate>,
192
- ref: React.Ref<HTMLDivElement>,
193
- ) {
194
- const props = useDefaultProps({ props: inProps, name: 'MuiPickersDateRangePicker' });
195
- });
196
- `,
197
- errors: [
198
- {
199
- message:
200
- "Expected `name` to be 'MuiStaticDateRangePicker' but instead got 'MuiPickersDateRangePicker'.",
201
- },
202
- ],
203
- },
204
- {
205
- code: 'useDefaultProps({ props: inProps })',
206
- errors: [
207
- {
208
- message: 'Unable to find `name` property. Did you forget to pass `name`?',
209
- },
210
- ],
211
- },
212
- {
213
- code: 'useDefaultProps({ props: inProps, name })',
214
- errors: [
215
- {
216
- message:
217
- 'Unable to resolve `name`. Please hardcode the `name` i.e. use a string literal.',
218
- },
219
- ],
220
- },
221
- {
222
- code: "useDefaultProps({ props: inProps, name: 'MuiPickersDateRangePicker' })",
223
- errors: [
224
- {
225
- message: 'Unable to find component for this call.',
226
- },
227
- ],
228
- },
229
- {
230
- code: `
231
- const StaticDateRangePicker = React.forwardRef(function StaticDateRangePicker<TDate>(
232
- inProps: StaticDateRangePickerProps<TDate>,
233
- ref: React.Ref<HTMLDivElement>,
234
- ) {
235
- const props = useDatePickerDefaultizedProps(inProps);
236
- });
237
- `,
238
- options: [{ customHooks: ['useDatePickerDefaultizedProps'] }],
239
- errors: [
240
- {
241
- message:
242
- "Unable to find name argument. Expected `useDatePickerDefaultizedProps(firstParameter, 'MuiComponent')`.",
243
- },
244
- ],
245
- },
246
- ],
247
- });
@@ -1,40 +0,0 @@
1
- import eslint from 'eslint';
2
- import parser from '@typescript-eslint/parser';
3
- import rule from './no-empty-box.mjs';
4
-
5
- const ruleTester = new eslint.RuleTester({
6
- languageOptions: {
7
- parser,
8
- parserOptions: {
9
- ecmaFeatures: { jsx: true },
10
- },
11
- },
12
- });
13
-
14
- ruleTester.run('no-empty-box', rule, {
15
- valid: ['<Box sx={{ width: 1 }}>Foo</Box>', '<Box sx={{ width: 1 }} />', '<Box {...props} />'],
16
- invalid: [
17
- {
18
- code: '<Box>Foo</Box>',
19
- errors: [
20
- {
21
- messageId: 'emptyBox',
22
- data: {
23
- component: 'div',
24
- },
25
- },
26
- ],
27
- },
28
- {
29
- code: '<Box component="span">Foo</Box>',
30
- errors: [
31
- {
32
- messageId: 'emptyBox',
33
- data: {
34
- component: 'span',
35
- },
36
- },
37
- ],
38
- },
39
- ],
40
- });
@@ -1,141 +0,0 @@
1
- import { RuleTester } from '@typescript-eslint/rule-tester';
2
- import TSESlintParser from '@typescript-eslint/parser';
3
- import rule from './no-floating-cleanup.mjs';
4
-
5
- const ruleTester = new RuleTester({
6
- languageOptions: {
7
- parser: TSESlintParser,
8
- parserOptions: {
9
- tsconfigRootDir: import.meta.dirname,
10
- projectService: {
11
- allowDefaultProject: ['*.ts'],
12
- },
13
- },
14
- },
15
- });
16
-
17
- ruleTester.run('no-floating-cleanup', rule, {
18
- valid: [
19
- {
20
- name: 'stored cleanup function',
21
- code: `
22
- type Unsubscribe = () => void;
23
- declare function subscribe(cb: () => void): Unsubscribe;
24
- function f() {
25
- const un = subscribe(() => {});
26
- un();
27
- }
28
- `,
29
- },
30
- {
31
- name: 'explicit void opt-out',
32
- code: `
33
- type Unsubscribe = () => void;
34
- declare function subscribe(cb: () => void): Unsubscribe;
35
- function f() {
36
- void subscribe(() => {});
37
- }
38
- `,
39
- },
40
- {
41
- name: 'call returning void',
42
- code: `
43
- declare function noop(): void;
44
- function f() {
45
- noop();
46
- }
47
- `,
48
- },
49
- {
50
- name: 'fluent builder methods returning `this`',
51
- code: `
52
- interface Scale {
53
- (value: number): number;
54
- domain(d: number[]): this;
55
- range(r: number[]): this;
56
- }
57
- declare const scale: Scale;
58
- function f() {
59
- scale.domain([0, 1]);
60
- scale.range([0, 100]);
61
- }
62
- `,
63
- },
64
- {
65
- name: 'fluent builder method with an inferred `this` return',
66
- code: `
67
- class Builder {
68
- configure() {
69
- return this;
70
- }
71
- }
72
- declare const builder: Builder;
73
- function f() {
74
- builder.configure();
75
- }
76
- `,
77
- },
78
- ],
79
- invalid: [
80
- {
81
- name: 'discarded unsubscribe function',
82
- code: `
83
- type Unsubscribe = () => void;
84
- declare function subscribe(cb: () => void): Unsubscribe;
85
- function f() {
86
- subscribe(() => {});
87
- }
88
- `,
89
- errors: [{ messageId: 'floatingCleanup', line: 5 }],
90
- },
91
- {
92
- name: 'call returning a fresh callable (not `this`)',
93
- code: `
94
- interface Scale {
95
- (value: number): number;
96
- copy(): Scale;
97
- }
98
- declare const scale: Scale;
99
- function f() {
100
- scale.copy();
101
- }
102
- `,
103
- errors: [{ messageId: 'floatingCleanup', line: 8 }],
104
- },
105
- {
106
- name: 'discarded cleanup behind a unary operator',
107
- code: `
108
- type Unsubscribe = () => void;
109
- declare function subscribe(cb: () => void): Unsubscribe;
110
- function f() {
111
- !subscribe(() => {});
112
- }
113
- `,
114
- errors: [{ messageId: 'floatingCleanup', line: 5 }],
115
- },
116
- {
117
- name: 'discarded cleanup in a logical expression',
118
- code: `
119
- type Unsubscribe = () => void;
120
- declare function subscribe(cb: () => void): Unsubscribe;
121
- declare const enabled: boolean;
122
- function f() {
123
- enabled && subscribe(() => {});
124
- }
125
- `,
126
- errors: [{ messageId: 'floatingCleanup', line: 6 }],
127
- },
128
- {
129
- name: 'discarded cleanup in a conditional expression',
130
- code: `
131
- type Unsubscribe = () => void;
132
- declare function subscribe(cb: () => void): Unsubscribe;
133
- declare const enabled: boolean;
134
- function f() {
135
- enabled ? subscribe(() => {}) : undefined;
136
- }
137
- `,
138
- errors: [{ messageId: 'floatingCleanup', line: 6 }],
139
- },
140
- ],
141
- });
@@ -1,206 +0,0 @@
1
- import eslint from 'eslint';
2
- import parser from '@typescript-eslint/parser';
3
- import rule from './no-guarded-throw.mjs';
4
-
5
- const ruleTester = new eslint.RuleTester({
6
- languageOptions: {
7
- parser,
8
- },
9
- });
10
-
11
- ruleTester.run('no-guarded-throw', rule, {
12
- valid: [
13
- // Should pass: Unconditional throw
14
- {
15
- code: `
16
- throw new Error('Something went wrong');
17
- `,
18
- },
19
- // Should pass: Throw inside a non-NODE_ENV conditional
20
- {
21
- code: `
22
- if (value == null) {
23
- throw new TypeError('value is required');
24
- }
25
- `,
26
- },
27
- // Should pass: Throw inside a catch block (no NODE_ENV guard)
28
- {
29
- code: `
30
- try {
31
- doSomething();
32
- } catch (error) {
33
- throw new Error('Failed');
34
- }
35
- `,
36
- },
37
- // Should pass: Throw inside arrow function inside NODE_ENV guard
38
- {
39
- code: `
40
- if (process.env.NODE_ENV !== 'production') {
41
- const fn = () => {
42
- throw new Error('inside arrow function');
43
- };
44
- }
45
- `,
46
- },
47
- // Should pass: Throw inside function expression inside NODE_ENV guard
48
- {
49
- code: `
50
- if (process.env.NODE_ENV !== 'production') {
51
- const fn = function () {
52
- throw new Error('inside function expression');
53
- };
54
- }
55
- `,
56
- },
57
- // Should pass: Throw inside function declaration inside NODE_ENV guard
58
- {
59
- code: `
60
- if (process.env.NODE_ENV !== 'production') {
61
- function validate() {
62
- throw new Error('inside function declaration');
63
- }
64
- }
65
- `,
66
- },
67
- ],
68
- invalid: [
69
- // Should fail: Throw inside !== 'production' guard
70
- {
71
- code: `
72
- if (process.env.NODE_ENV !== 'production') {
73
- throw new Error('Dev-only error');
74
- }
75
- `,
76
- errors: [{ messageId: 'guardedThrow' }],
77
- },
78
- // Should fail: Throw inside === 'production' guard
79
- {
80
- code: `
81
- if (process.env.NODE_ENV === 'production') {
82
- throw new Error('Prod-only error');
83
- }
84
- `,
85
- errors: [{ messageId: 'guardedThrow' }],
86
- },
87
- // Should fail: Throw in else block of === 'production' check
88
- {
89
- code: `
90
- if (process.env.NODE_ENV === 'production') {
91
- // production path
92
- } else {
93
- throw new Error('Non-production error');
94
- }
95
- `,
96
- errors: [{ messageId: 'guardedThrow' }],
97
- },
98
- // Should fail: Throw nested inside NODE_ENV guard
99
- {
100
- code: `
101
- if (process.env.NODE_ENV !== 'production') {
102
- if (value == null) {
103
- throw new TypeError('value is required');
104
- }
105
- }
106
- `,
107
- errors: [{ messageId: 'guardedThrow' }],
108
- },
109
- // Should fail: Reversed comparison (literal on left)
110
- {
111
- code: `
112
- if ('production' !== process.env.NODE_ENV) {
113
- throw new Error('Dev-only error');
114
- }
115
- `,
116
- errors: [{ messageId: 'guardedThrow' }],
117
- },
118
- // Should fail: Throw in loop inside NODE_ENV guard
119
- {
120
- code: `
121
- if (process.env.NODE_ENV !== 'production') {
122
- for (const item of items) {
123
- throw new Error('Invalid item');
124
- }
125
- }
126
- `,
127
- errors: [{ messageId: 'guardedThrow' }],
128
- },
129
- // Should fail: NODE_ENV combined with other conditions using &&
130
- {
131
- code: `
132
- if (process.env.NODE_ENV !== 'production' && value == null) {
133
- throw new TypeError('value is required');
134
- }
135
- `,
136
- errors: [{ messageId: 'guardedThrow' }],
137
- },
138
- // Should fail: NODE_ENV combined with other conditions using ||
139
- {
140
- code: `
141
- if (condition || process.env.NODE_ENV === 'test') {
142
- throw new Error('Test or condition error');
143
- }
144
- `,
145
- errors: [{ messageId: 'guardedThrow' }],
146
- },
147
- // Should fail: Unary not on process.env.NODE_ENV
148
- {
149
- code: `
150
- if (!process.env.NODE_ENV) {
151
- throw new Error('NODE_ENV not set');
152
- }
153
- `,
154
- errors: [{ messageId: 'guardedThrow' }],
155
- },
156
- // Should fail: NODE_ENV passed to a function
157
- {
158
- code: `
159
- if (fn(process.env.NODE_ENV)) {
160
- throw new Error('Function check failed');
161
- }
162
- `,
163
- errors: [{ messageId: 'guardedThrow' }],
164
- },
165
- // Should fail: Throw inside try/catch inside NODE_ENV guard
166
- {
167
- code: `
168
- if (process.env.NODE_ENV !== 'production') {
169
- try {
170
- doSomething();
171
- } catch (error) {
172
- throw new Error('caught inside guard');
173
- }
174
- }
175
- `,
176
- errors: [{ messageId: 'guardedThrow' }],
177
- },
178
- // Should fail: Throw deeply nested in control flow inside NODE_ENV guard
179
- {
180
- code: `
181
- if (process.env.NODE_ENV !== 'production') {
182
- if (value == null) {
183
- for (const item of items) {
184
- if (!item.valid) {
185
- throw new Error('invalid item');
186
- }
187
- }
188
- }
189
- }
190
- `,
191
- errors: [{ messageId: 'guardedThrow' }],
192
- },
193
- // Should fail: Throw inside switch/case inside NODE_ENV guard
194
- {
195
- code: `
196
- if (process.env.NODE_ENV !== 'production') {
197
- switch (type) {
198
- case 'a':
199
- throw new Error('invalid type a');
200
- }
201
- }
202
- `,
203
- errors: [{ messageId: 'guardedThrow' }],
204
- },
205
- ],
206
- });
@@ -1,33 +0,0 @@
1
- import eslint from 'eslint';
2
- import parser from '@typescript-eslint/parser';
3
- import rule from './no-presentation-role.mjs';
4
-
5
- const ruleTester = new eslint.RuleTester({
6
- languageOptions: {
7
- parser,
8
- parserOptions: {
9
- ecmaFeatures: { jsx: true },
10
- },
11
- },
12
- });
13
-
14
- ruleTester.run('no-presentation-role', rule, {
15
- valid: ['<div role="none" />', '<div role="button" />', '<div />', '<div role={presentation} />'],
16
- invalid: [
17
- {
18
- code: '<div role="presentation" />',
19
- errors: [{ messageId: 'noPresentation' }],
20
- output: '<div role="none" />',
21
- },
22
- {
23
- code: "<div role={'presentation'} />",
24
- errors: [{ messageId: 'noPresentation' }],
25
- output: '<div role="none" />',
26
- },
27
- {
28
- code: '<table role="presentation"><tr><td /></tr></table>',
29
- errors: [{ messageId: 'noPresentation' }],
30
- output: '<table role="none"><tr><td /></tr></table>',
31
- },
32
- ],
33
- });