Skip to content

Commit f3265b9

Browse files
authored
no-thenable: Fix Object.fromEntries() check (#2130)
1 parent f10f1a6 commit f3265b9

File tree

4 files changed

+103
-55
lines changed

4 files changed

+103
-55
lines changed

rules/no-thenable.js

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -86,29 +86,35 @@ const cases = [
8686
},
8787
messageId: MESSAGE_ID_OBJECT,
8888
},
89-
// TODO[@fisker]: Bug, we are checking wrong pattern `Object.fromEntries(['then', …])`
9089
// `Object.fromEntries([['then', …]])`
9190
{
9291
selector: 'CallExpression',
9392
* getNodes(node, context) {
94-
if (!isMethodCall(node, {
95-
object: 'Object',
96-
method: 'fromEntries',
97-
argumentsLength: 1,
98-
optionalCall: false,
99-
optionalMember: false,
100-
})) {
93+
if (!(
94+
isMethodCall(node, {
95+
object: 'Object',
96+
method: 'fromEntries',
97+
argumentsLength: 1,
98+
optionalCall: false,
99+
optionalMember: false,
100+
})
101+
&& node.arguments[0].type === 'ArrayExpression'
102+
)) {
101103
return;
102104
}
103105

104-
const [firstArgument] = node.arguments;
105-
if (firstArgument.type !== 'ArrayExpression') {
106-
return;
107-
}
106+
for (const pairs of node.arguments[0].elements) {
107+
if (
108+
pairs?.type === 'ArrayExpression'
109+
&& pairs.elements[0]
110+
&& pairs.elements[0].type !== 'SpreadElement'
111+
) {
112+
const [key] = pairs.elements;
108113

109-
const [firstElement] = firstArgument.elements;
110-
if (isStringThen(firstElement, context)) {
111-
yield firstElement;
114+
if (isStringThen(key, context)) {
115+
yield key;
116+
}
117+
}
112118
}
113119
},
114120
messageId: MESSAGE_ID_OBJECT,

test/no-thenable.mjs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,17 @@ test.snapshot({
4949

5050
// `Object.fromEntries`
5151
'Object.fromEntries([then, 1])',
52-
'Object.fromEntries(["notThen", "then"])',
53-
'const NOT_THEN = "not-then";Object.fromEntries([NOT_THEN, 1])',
52+
'Object.fromEntries([,,])',
53+
'Object.fromEntries([[,,],[]])',
54+
'const NOT_THEN = "not-then";Object.fromEntries([[NOT_THEN, 1]])',
55+
'Object.fromEntries([[["then", 1]]])',
56+
'NotObject.fromEntries([["then", 1]])',
57+
'Object.notFromEntries([["then", 1]])',
58+
'Object.fromEntries?.([["then", 1]])',
59+
'Object?.fromEntries([["then", 1]])',
60+
'Object.fromEntries([[..."then", 1]])',
61+
'Object.fromEntries([["then", 1]], extraArgument)',
62+
'Object.fromEntries(...[["then", 1]])',
5463

5564
// `{Object,Reflect}.defineProperty`
5665
'Object.defineProperty(foo, then, 1)',
@@ -143,9 +152,11 @@ test.snapshot({
143152
'const THEN = "then";Reflect.defineProperty(foo, THEN, 1)',
144153

145154
// `Object.fromEntries`
146-
'Object.fromEntries(["then", 1])',
147-
'Object.fromEntries([`then`, 1])',
148-
'const THEN = "then";Object.fromEntries([THEN, 1])',
155+
'Object.fromEntries([["then", 1]])',
156+
'Object.fromEntries([["then"]])',
157+
'Object.fromEntries([[`then`, 1]])',
158+
'const THEN = "then";Object.fromEntries([[THEN, 1]])',
159+
'Object.fromEntries([foo, ["then", 1]])',
149160

150161
// `export`
151162
'const then = 1; export {then}',
@@ -177,5 +188,6 @@ test.snapshot({
177188
'export let {foo, ...then} = 1',
178189
'export var {foo, ...then} = 1',
179190
'export const {foo: {bar: [{baz: then}]}} = 1',
191+
'export const notThen = 1, then = 1',
180192
],
181193
});

0 commit comments

Comments
 (0)