@mui/internal-code-infra 0.0.4-canary.72 → 0.0.4-canary.74

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 (53) hide show
  1. package/build/utils/git.d.mts +7 -0
  2. package/package.json +5 -3
  3. package/src/cli/cmdPublish.mjs +40 -5
  4. package/src/utils/git.mjs +11 -0
  5. package/src/brokenLinksChecker/__fixtures__/static-site/broken-links.html +0 -20
  6. package/src/brokenLinksChecker/__fixtures__/static-site/broken-targets.html +0 -22
  7. package/src/brokenLinksChecker/__fixtures__/static-site/example.md +0 -20
  8. package/src/brokenLinksChecker/__fixtures__/static-site/external-links.html +0 -21
  9. package/src/brokenLinksChecker/__fixtures__/static-site/ignored-page.html +0 -17
  10. package/src/brokenLinksChecker/__fixtures__/static-site/index.html +0 -29
  11. package/src/brokenLinksChecker/__fixtures__/static-site/invalid-html.html +0 -15
  12. package/src/brokenLinksChecker/__fixtures__/static-site/known-targets.json +0 -5
  13. package/src/brokenLinksChecker/__fixtures__/static-site/nested/page.html +0 -21
  14. package/src/brokenLinksChecker/__fixtures__/static-site/orphaned-page.html +0 -20
  15. package/src/brokenLinksChecker/__fixtures__/static-site/page-with-api-links.html +0 -20
  16. package/src/brokenLinksChecker/__fixtures__/static-site/page-with-custom-targets.html +0 -24
  17. package/src/brokenLinksChecker/__fixtures__/static-site/page-with-ignored-content.html +0 -28
  18. package/src/brokenLinksChecker/__fixtures__/static-site/page-with-known-target-links.html +0 -19
  19. package/src/brokenLinksChecker/__fixtures__/static-site/unclosed-tags.html +0 -1
  20. package/src/brokenLinksChecker/__fixtures__/static-site/valid.html +0 -20
  21. package/src/brokenLinksChecker/__fixtures__/static-site/with-anchors.html +0 -31
  22. package/src/brokenLinksChecker/index.test.ts +0 -301
  23. package/src/changelog/categorizeCommits.test.ts +0 -319
  24. package/src/changelog/filterCommits.test.ts +0 -363
  25. package/src/changelog/parseCommitLabels.test.ts +0 -509
  26. package/src/changelog/renderChangelog.test.ts +0 -378
  27. package/src/changelog/sortSections.test.ts +0 -199
  28. package/src/cli/cmdVale.test.mjs +0 -644
  29. package/src/eslint/mui/rules/add-undef-to-optional.test.mjs +0 -361
  30. package/src/eslint/mui/rules/consistent-production-guard.test.mjs +0 -162
  31. package/src/eslint/mui/rules/disallow-active-elements-as-key-event-target.test.mjs +0 -66
  32. package/src/eslint/mui/rules/disallow-react-api-in-server-components.test.mjs +0 -305
  33. package/src/eslint/mui/rules/docgen-ignore-before-comment.test.mjs +0 -52
  34. package/src/eslint/mui/rules/flatten-parentheses.test.mjs +0 -245
  35. package/src/eslint/mui/rules/mui-name-matches-component-name.test.mjs +0 -247
  36. package/src/eslint/mui/rules/no-empty-box.test.mjs +0 -40
  37. package/src/eslint/mui/rules/no-floating-cleanup.test.mjs +0 -141
  38. package/src/eslint/mui/rules/no-guarded-throw.test.mjs +0 -206
  39. package/src/eslint/mui/rules/no-presentation-role.test.mjs +0 -33
  40. package/src/eslint/mui/rules/no-styled-box.test.mjs +0 -73
  41. package/src/eslint/mui/rules/require-dev-wrapper.test.mjs +0 -265
  42. package/src/eslint/mui/rules/rules-of-use-theme-variants.test.mjs +0 -149
  43. package/src/eslint/mui/rules/straight-quotes.test.mjs +0 -67
  44. package/src/remark/firstBlockHeading.test.mjs +0 -107
  45. package/src/remark/gitDiff.test.mjs +0 -45
  46. package/src/remark/noSpaceInLinks.test.mjs +0 -22
  47. package/src/remark/straightQuotes.test.mjs +0 -25
  48. package/src/remark/tableAlignment.test.mjs +0 -28
  49. package/src/remark/terminalLanguage.test.mjs +0 -17
  50. package/src/utils/build.test.mjs +0 -1263
  51. package/src/utils/pnpm.test.mjs +0 -731
  52. package/src/utils/template.test.mjs +0 -133
  53. 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
- });