@@ -61,6 +61,12 @@ ruleTester.run("no-prototype-builtins", rule, {
61
61
endColumn : 19 ,
62
62
messageId : "prototypeBuildIn" ,
63
63
data : { prop : "hasOwnProperty" } ,
64
+ suggestions : [
65
+ {
66
+ messageId : "callObjectPrototype" ,
67
+ output : "Object.prototype.hasOwnProperty.call(foo, 'bar')"
68
+ }
69
+ ] ,
64
70
type : "CallExpression"
65
71
} ]
66
72
} ,
@@ -73,6 +79,12 @@ ruleTester.run("no-prototype-builtins", rule, {
73
79
endColumn : 18 ,
74
80
messageId : "prototypeBuildIn" ,
75
81
data : { prop : "isPrototypeOf" } ,
82
+ suggestions : [
83
+ {
84
+ messageId : "callObjectPrototype" ,
85
+ output : "Object.prototype.isPrototypeOf.call(foo, 'bar')"
86
+ }
87
+ ] ,
76
88
type : "CallExpression"
77
89
} ]
78
90
} ,
@@ -84,6 +96,12 @@ ruleTester.run("no-prototype-builtins", rule, {
84
96
endLine : 1 ,
85
97
endColumn : 25 ,
86
98
messageId : "prototypeBuildIn" ,
99
+ suggestions : [
100
+ {
101
+ messageId : "callObjectPrototype" ,
102
+ output : "Object.prototype.propertyIsEnumerable.call(foo, 'bar')"
103
+ }
104
+ ] ,
87
105
data : { prop : "propertyIsEnumerable" }
88
106
} ]
89
107
} ,
@@ -96,6 +114,12 @@ ruleTester.run("no-prototype-builtins", rule, {
96
114
endColumn : 23 ,
97
115
messageId : "prototypeBuildIn" ,
98
116
data : { prop : "hasOwnProperty" } ,
117
+ suggestions : [
118
+ {
119
+ messageId : "callObjectPrototype" ,
120
+ output : "Object.prototype.hasOwnProperty.call(foo.bar, 'bar')"
121
+ }
122
+ ] ,
99
123
type : "CallExpression"
100
124
} ]
101
125
} ,
@@ -108,6 +132,12 @@ ruleTester.run("no-prototype-builtins", rule, {
108
132
endColumn : 26 ,
109
133
messageId : "prototypeBuildIn" ,
110
134
data : { prop : "isPrototypeOf" } ,
135
+ suggestions : [
136
+ {
137
+ messageId : "callObjectPrototype" ,
138
+ output : "Object.prototype.isPrototypeOf.call(foo.bar.baz, 'bar')"
139
+ }
140
+ ] ,
111
141
type : "CallExpression"
112
142
} ]
113
143
} ,
@@ -120,6 +150,12 @@ ruleTester.run("no-prototype-builtins", rule, {
120
150
endColumn : 21 ,
121
151
messageId : "prototypeBuildIn" ,
122
152
data : { prop : "hasOwnProperty" } ,
153
+ suggestions : [
154
+ {
155
+ messageId : "callObjectPrototype" ,
156
+ output : "Object.prototype.hasOwnProperty.call(foo, 'bar')"
157
+ }
158
+ ] ,
123
159
type : "CallExpression"
124
160
} ]
125
161
} ,
@@ -133,6 +169,12 @@ ruleTester.run("no-prototype-builtins", rule, {
133
169
endColumn : 20 ,
134
170
messageId : "prototypeBuildIn" ,
135
171
data : { prop : "isPrototypeOf" } ,
172
+ suggestions : [
173
+ {
174
+ messageId : "callObjectPrototype" ,
175
+ output : "Object.prototype.isPrototypeOf.call(foo, 'bar').baz"
176
+ }
177
+ ] ,
136
178
type : "CallExpression"
137
179
} ]
138
180
} ,
@@ -145,30 +187,116 @@ ruleTester.run("no-prototype-builtins", rule, {
145
187
endColumn : 31 ,
146
188
messageId : "prototypeBuildIn" ,
147
189
data : { prop : "propertyIsEnumerable" } ,
190
+ suggestions : [
191
+ {
192
+ messageId : "callObjectPrototype" ,
193
+ output : String . raw `Object.prototype.propertyIsEnumerable.call(foo.bar, 'baz')`
194
+ }
195
+ ] ,
148
196
type : "CallExpression"
149
197
} ]
150
198
} ,
199
+ {
200
+
201
+ // Can't suggest Object.prototype when Object is shadowed
202
+ code : "(function(Object) {return foo.hasOwnProperty('bar');})" ,
203
+ errors : [ { messageId : "prototypeBuildIn" , data : { prop : "hasOwnProperty" } , suggestions : [ ] } ]
204
+ } ,
205
+ {
206
+ code : "foo.hasOwnProperty('bar')" ,
207
+ globals : {
208
+ Object : "off"
209
+ } ,
210
+ errors : [ { messageId : "prototypeBuildIn" , data : { prop : "hasOwnProperty" } , suggestions : [ ] } ] ,
211
+ name : "Can't suggest Object.prototype when there is no Object global variable"
212
+ } ,
151
213
152
214
// Optional chaining
153
215
{
154
216
code : "foo?.hasOwnProperty('bar')" ,
155
217
parserOptions : { ecmaVersion : 2020 } ,
156
- errors : [ { messageId : "prototypeBuildIn" , data : { prop : "hasOwnProperty" } } ]
218
+ errors : [ { messageId : "prototypeBuildIn" , data : { prop : "hasOwnProperty" } , suggestions : [ ] } ]
219
+ } ,
220
+ {
221
+ code : "foo?.bar.hasOwnProperty('baz')" ,
222
+ parserOptions : { ecmaVersion : 2020 } ,
223
+ errors : [ { messageId : "prototypeBuildIn" , data : { prop : "hasOwnProperty" } , suggestions : [ ] } ]
224
+ } ,
225
+ {
226
+ code : "foo.hasOwnProperty?.('bar')" ,
227
+ parserOptions : { ecmaVersion : 2020 } ,
228
+ errors : [ { messageId : "prototypeBuildIn" , data : { prop : "hasOwnProperty" } , suggestions : [ ] } ]
229
+ } ,
230
+ {
231
+
232
+ /*
233
+ * If hasOwnProperty is part of a ChainExpresion
234
+ * and the optional part is before it, then don't suggest the fix
235
+ */
236
+ code : "foo?.hasOwnProperty('bar').baz" ,
237
+ parserOptions : { ecmaVersion : 2020 } ,
238
+ errors : [ { messageId : "prototypeBuildIn" , data : { prop : "hasOwnProperty" } , suggestions : [ ] } ]
157
239
} ,
158
240
{
241
+
242
+ /*
243
+ * If hasOwnProperty is part of a ChainExpresion
244
+ * but the optional part is after it, then the fix is safe
245
+ */
246
+ code : "foo.hasOwnProperty('bar')?.baz" ,
247
+ parserOptions : { ecmaVersion : 2020 } ,
248
+ errors : [ {
249
+ messageId : "prototypeBuildIn" ,
250
+ data : { prop : "hasOwnProperty" } ,
251
+ suggestions : [
252
+ {
253
+ messageId : "callObjectPrototype" ,
254
+ output : "Object.prototype.hasOwnProperty.call(foo, 'bar')?.baz"
255
+ }
256
+ ]
257
+ } ]
258
+ } ,
259
+ {
260
+
261
+ code : "(a,b).hasOwnProperty('bar')" ,
262
+ parserOptions : { ecmaVersion : 2020 } ,
263
+ errors : [ {
264
+ messageId : "prototypeBuildIn" ,
265
+ data : { prop : "hasOwnProperty" } ,
266
+ suggestions : [
267
+
268
+ // Make sure the SequenceExpression has parentheses before other arguments
269
+ {
270
+ messageId : "callObjectPrototype" ,
271
+ output : "Object.prototype.hasOwnProperty.call((a,b), 'bar')"
272
+ }
273
+ ]
274
+ } ]
275
+ } ,
276
+ {
277
+
278
+ // No suggestion where no-unsafe-optional-chaining is reported on the call
159
279
code : "(foo?.hasOwnProperty)('bar')" ,
160
280
parserOptions : { ecmaVersion : 2020 } ,
161
- errors : [ { messageId : "prototypeBuildIn" , data : { prop : "hasOwnProperty" } } ]
281
+ errors : [ { messageId : "prototypeBuildIn" , data : { prop : "hasOwnProperty" } , suggestions : [ ] } ]
282
+
283
+ } ,
284
+ {
285
+ code : "(foo?.hasOwnProperty)?.('bar')" ,
286
+ parserOptions : { ecmaVersion : 2020 } ,
287
+ errors : [ { messageId : "prototypeBuildIn" , data : { prop : "hasOwnProperty" } , suggestions : [ ] } ]
162
288
} ,
163
289
{
164
290
code : "foo?.['hasOwnProperty']('bar')" ,
165
291
parserOptions : { ecmaVersion : 2020 } ,
166
- errors : [ { messageId : "prototypeBuildIn" , data : { prop : "hasOwnProperty" } } ]
292
+ errors : [ { messageId : "prototypeBuildIn" , data : { prop : "hasOwnProperty" } , suggestions : [ ] } ]
167
293
} ,
168
294
{
295
+
296
+ // No suggestion where no-unsafe-optional-chaining is reported on the call
169
297
code : "(foo?.[`hasOwnProperty`])('bar')" ,
170
298
parserOptions : { ecmaVersion : 2020 } ,
171
- errors : [ { messageId : "prototypeBuildIn" , data : { prop : "hasOwnProperty" } } ]
299
+ errors : [ { messageId : "prototypeBuildIn" , data : { prop : "hasOwnProperty" } , suggestions : [ ] } ]
172
300
}
173
301
]
174
302
} ) ;
0 commit comments