豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit 6406493

Browse files
feat(no-conditional-in-test): ban optional chaining (#1933)
1 parent 5698ed5 commit 6406493

File tree

3 files changed

+234
-4
lines changed

3 files changed

+234
-4
lines changed

docs/rules/no-conditional-in-test.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ devoted to it.
1212
## Rule details
1313

1414
This rule reports on any use of a conditional statement such as `if`, `switch`,
15-
and ternary expressions.
15+
ternary expressions, and optional chaining.
1616

1717
Examples of **incorrect** code for this rule:
1818

@@ -36,7 +36,11 @@ it('bar', () => {
3636
expect(fixtures.length).toBeGreaterThan(-1);
3737
});
3838

39-
it('baz', async () => {
39+
it('baz', () => {
40+
const value = obj?.bar;
41+
});
42+
43+
it('qux', async () => {
4044
const promiseValue = () => {
4145
return something instanceof Promise
4246
? something
@@ -77,7 +81,11 @@ const promiseValue = something => {
7781
return something instanceof Promise ? something : Promise.resolve(something);
7882
};
7983

80-
it('baz', async () => {
84+
it('baz', () => {
85+
const value = obj!.bar;
86+
});
87+
88+
it('qux', async () => {
8189
await expect(promiseValue()).resolves.toBe(1);
8290
});
8391
```

src/rules/__tests__/no-conditional-in-test.test.ts

Lines changed: 222 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { FlatCompatRuleTester as RuleTester, espreeParser } from './test-utils';
55
const ruleTester = new RuleTester({
66
parser: espreeParser,
77
parserOptions: {
8-
ecmaVersion: 2015,
8+
ecmaVersion: 2020,
99
},
1010
});
1111

@@ -949,3 +949,224 @@ ruleTester.run('if statements', rule, {
949949
},
950950
],
951951
});
952+
953+
ruleTester.run('optional chaining', rule, {
954+
valid: [
955+
'const x = obj?.foo',
956+
dedent`
957+
const foo = obj?.bar;
958+
959+
it('foo', () => {
960+
expect(foo).toBe(undefined);
961+
});
962+
`,
963+
dedent`
964+
describe('foo', () => {
965+
const val = obj?.bar;
966+
})
967+
`,
968+
dedent`
969+
describe('foo', () => {
970+
beforeEach(() => {
971+
const val = obj?.bar;
972+
});
973+
})
974+
`,
975+
dedent`
976+
describe('foo', () => {
977+
afterEach(() => {
978+
const val = obj?.bar;
979+
});
980+
})
981+
`,
982+
dedent`
983+
const values = something.map(thing => thing?.foo);
984+
985+
it('valid', () => {
986+
expect(values).toStrictEqual(['foo']);
987+
});
988+
`,
989+
dedent`
990+
describe('valid', () => {
991+
const values = something.map(thing => thing?.foo);
992+
it('still valid', () => {
993+
expect(values).toStrictEqual(['foo']);
994+
});
995+
});
996+
`,
997+
],
998+
invalid: [
999+
{
1000+
code: dedent`
1001+
it('foo', () => {
1002+
const value = obj?.bar;
1003+
})
1004+
`,
1005+
errors: [
1006+
{
1007+
messageId: 'conditionalInTest',
1008+
column: 17,
1009+
line: 2,
1010+
},
1011+
],
1012+
},
1013+
{
1014+
code: dedent`
1015+
it('foo', () => {
1016+
obj?.foo?.bar;
1017+
})
1018+
`,
1019+
errors: [
1020+
{
1021+
messageId: 'conditionalInTest',
1022+
column: 3,
1023+
line: 2,
1024+
},
1025+
],
1026+
},
1027+
{
1028+
code: dedent`
1029+
it('foo', () => {
1030+
obj?.foo();
1031+
})
1032+
`,
1033+
errors: [
1034+
{
1035+
messageId: 'conditionalInTest',
1036+
column: 3,
1037+
line: 2,
1038+
},
1039+
],
1040+
},
1041+
{
1042+
code: dedent`
1043+
it('foo', () => {
1044+
obj?.[key];
1045+
})
1046+
`,
1047+
errors: [
1048+
{
1049+
messageId: 'conditionalInTest',
1050+
column: 3,
1051+
line: 2,
1052+
},
1053+
],
1054+
},
1055+
{
1056+
code: dedent`
1057+
it.skip('foo', () => {
1058+
obj?.bar;
1059+
})
1060+
`,
1061+
errors: [
1062+
{
1063+
messageId: 'conditionalInTest',
1064+
column: 3,
1065+
line: 2,
1066+
},
1067+
],
1068+
},
1069+
{
1070+
code: dedent`
1071+
it.only('foo', () => {
1072+
obj?.bar;
1073+
})
1074+
`,
1075+
errors: [
1076+
{
1077+
messageId: 'conditionalInTest',
1078+
column: 3,
1079+
line: 2,
1080+
},
1081+
],
1082+
},
1083+
{
1084+
code: dedent`
1085+
test('foo', () => {
1086+
obj?.bar;
1087+
})
1088+
`,
1089+
errors: [
1090+
{
1091+
messageId: 'conditionalInTest',
1092+
column: 3,
1093+
line: 2,
1094+
},
1095+
],
1096+
},
1097+
{
1098+
code: dedent`
1099+
xtest('foo', () => {
1100+
obj?.bar;
1101+
})
1102+
`,
1103+
errors: [
1104+
{
1105+
messageId: 'conditionalInTest',
1106+
column: 3,
1107+
line: 2,
1108+
},
1109+
],
1110+
},
1111+
{
1112+
code: dedent`
1113+
fit('foo', () => {
1114+
obj?.bar;
1115+
})
1116+
`,
1117+
errors: [
1118+
{
1119+
messageId: 'conditionalInTest',
1120+
column: 3,
1121+
line: 2,
1122+
},
1123+
],
1124+
},
1125+
{
1126+
code: dedent`
1127+
xit('foo', () => {
1128+
obj?.bar;
1129+
})
1130+
`,
1131+
errors: [
1132+
{
1133+
messageId: 'conditionalInTest',
1134+
column: 3,
1135+
line: 2,
1136+
},
1137+
],
1138+
},
1139+
{
1140+
code: dedent`
1141+
describe('foo', () => {
1142+
it('bar', () => {
1143+
obj?.bar;
1144+
})
1145+
})
1146+
`,
1147+
errors: [
1148+
{
1149+
messageId: 'conditionalInTest',
1150+
column: 5,
1151+
line: 3,
1152+
},
1153+
],
1154+
},
1155+
{
1156+
code: dedent`
1157+
it('is invalid', () => {
1158+
const values = something.map(thing => thing?.foo);
1159+
1160+
expect(values).toStrictEqual(['foo']);
1161+
});
1162+
`,
1163+
errors: [
1164+
{
1165+
messageId: 'conditionalInTest',
1166+
column: 41,
1167+
line: 2,
1168+
},
1169+
],
1170+
},
1171+
],
1172+
});

src/rules/no-conditional-in-test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export default createRule({
4141
SwitchStatement: maybeReportConditional,
4242
ConditionalExpression: maybeReportConditional,
4343
LogicalExpression: maybeReportConditional,
44+
ChainExpression: maybeReportConditional,
4445
};
4546
},
4647
});

0 commit comments

Comments
 (0)