]>
git.proxmox.com Git - pve-eslint.git/blob - eslint/tests/lib/rules/require-atomic-updates.js
2 * @fileoverview disallow assignments that can lead to race conditions due to usage of `await` or `yield`
7 //------------------------------------------------------------------------------
9 //------------------------------------------------------------------------------
11 const rule
= require("../../../lib/rules/require-atomic-updates");
12 const { RuleTester
} = require("../../../lib/rule-tester");
14 //------------------------------------------------------------------------------
16 //------------------------------------------------------------------------------
18 const ruleTester
= new RuleTester({ parserOptions
: { ecmaVersion
: 2022 } });
20 const VARIABLE_ERROR
= {
21 messageId
: "nonAtomicUpdate",
22 data
: { value
: "foo" },
23 type
: "AssignmentExpression"
26 const STATIC_PROPERTY_ERROR
= {
27 messageId
: "nonAtomicObjectUpdate",
28 data
: { value
: "foo.bar", object
: "foo" },
29 type
: "AssignmentExpression"
32 const COMPUTED_PROPERTY_ERROR
= {
33 messageId
: "nonAtomicObjectUpdate",
34 data
: { value
: "foo[bar].baz", object
: "foo" },
35 type
: "AssignmentExpression"
38 const PRIVATE_PROPERTY_ERROR
= {
39 messageId
: "nonAtomicObjectUpdate",
40 data
: { value
: "foo.#bar", object
: "foo" },
41 type
: "AssignmentExpression"
44 ruleTester
.run("require-atomic-updates", rule
, {
47 "let foo; async function x() { foo += bar; }",
48 "let foo; async function x() { foo = foo + bar; }",
49 "let foo; async function x() { foo = await bar + foo; }",
50 "async function x() { let foo; foo += await bar; }",
51 "let foo; async function x() { foo = (await result)(foo); }",
52 "let foo; async function x() { foo = bar(await something, foo) }",
53 "function* x() { let foo; foo += yield bar; }",
54 "const foo = {}; async function x() { foo.bar = await baz; }",
55 "const foo = []; async function x() { foo[x] += 1; }",
56 "let foo; function* x() { foo = bar + foo; }",
57 "async function x() { let foo; bar(() => baz += 1); foo += await amount; }",
58 "let foo; async function x() { foo = condition ? foo : await bar; }",
59 "async function x() { let foo; bar(() => { let foo; blah(foo); }); foo += await result; }",
60 "let foo; async function x() { foo = foo + 1; await bar; }",
61 "async function x() { foo += await bar; }",
65 * Ensure rule doesn't take exponential time in the number of branches
66 * (see https://github.com/eslint/eslint/issues/10893)
69 async function foo() {
93 async function foo() {
119 // https://github.com/eslint/eslint/issues/11194
123 records = await a.records
128 // https://github.com/eslint/eslint/issues/11687
132 this.foo = doSomething();
140 // https://github.com/eslint/eslint/issues/11723
142 async function f(foo) {
143 let bar = await get(foo.id);
148 async function f(foo) {
149 let bar = await get(foo.id);
156 let bar = await get(foo.id);
161 // https://github.com/eslint/eslint/issues/11954
165 async function A(...args) {
167 await new Promise(resolve=>resolve())
173 // https://github.com/eslint/eslint/issues/14208
175 async function foo(e) {
178 async function run() {
182 for(const entry of input) {
183 const prop = props.find(a => a.id === entry.id) || null;
187 for(const entry of input) {
188 const prop = props.find(a => a.id === entry.id) || null;
191 for(const entry2 of input) {
192 const prop = props.find(a => a.id === entry2.id) || null;
198 async function run() {
213 async function run() {
222 async function a(foo) {
224 foo.bar = await something;
228 options
: [{ allowProperties
: true }]
238 options
: [{ allowProperties
: true }]
244 code
: "let foo; async function x() { foo += await amount; }",
245 errors
: [{ messageId
: "nonAtomicUpdate", data
: { value
: "foo" } }]
248 code
: "if (1); let foo; async function x() { foo += await amount; }",
249 errors
: [{ messageId
: "nonAtomicUpdate", data
: { value
: "foo" } }]
252 code
: "let foo; async function x() { while (condition) { foo += await amount; } }",
253 errors
: [VARIABLE_ERROR
]
256 code
: "let foo; async function x() { foo = foo + await amount; }",
257 errors
: [VARIABLE_ERROR
]
260 code
: "let foo; async function x() { foo = foo + (bar ? baz : await amount); }",
261 errors
: [VARIABLE_ERROR
]
264 code
: "let foo; async function x() { foo = foo + (bar ? await amount : baz); }",
265 errors
: [VARIABLE_ERROR
]
268 code
: "let foo; async function x() { foo = condition ? foo + await amount : somethingElse; }",
269 errors
: [VARIABLE_ERROR
]
272 code
: "let foo; async function x() { foo = (condition ? foo : await bar) + await bar; }",
273 errors
: [VARIABLE_ERROR
]
276 code
: "let foo; async function x() { foo += bar + await amount; }",
277 errors
: [VARIABLE_ERROR
]
280 code
: "async function x() { let foo; bar(() => foo); foo += await amount; }",
281 errors
: [VARIABLE_ERROR
]
284 code
: "let foo; function* x() { foo += yield baz }",
285 errors
: [VARIABLE_ERROR
]
288 code
: "let foo; async function x() { foo = bar(foo, await something) }",
289 errors
: [VARIABLE_ERROR
]
292 code
: "const foo = {}; async function x() { foo.bar += await baz }",
293 errors
: [STATIC_PROPERTY_ERROR
]
296 code
: "const foo = []; async function x() { foo[bar].baz += await result; }",
297 errors
: [COMPUTED_PROPERTY_ERROR
]
300 code
: "const foo = {}; class C { #bar; async wrap() { foo.#bar += await baz } }",
301 errors
: [PRIVATE_PROPERTY_ERROR
]
304 code
: "let foo; async function* x() { foo = (yield foo) + await bar; }",
305 errors
: [VARIABLE_ERROR
]
308 code
: "let foo; async function x() { foo = foo + await result(foo); }",
309 errors
: [VARIABLE_ERROR
]
312 code
: "let foo; async function x() { foo = await result(foo, await somethingElse); }",
313 errors
: [VARIABLE_ERROR
]
316 code
: "function* x() { let foo; yield async function y() { foo += await bar; } }",
317 errors
: [VARIABLE_ERROR
]
320 code
: "let foo; async function* x() { foo = await foo + (yield bar); }",
321 errors
: [VARIABLE_ERROR
]
324 code
: "let foo; async function x() { foo = bar + await foo; }",
325 errors
: [VARIABLE_ERROR
]
328 code
: "let foo = {}; async function x() { foo[bar].baz = await (foo.bar += await foo[bar].baz) }",
329 errors
: [COMPUTED_PROPERTY_ERROR
, STATIC_PROPERTY_ERROR
]
332 code
: "let foo = ''; async function x() { foo += await bar; }",
333 errors
: [VARIABLE_ERROR
]
336 code
: "let foo = 0; async function x() { foo = (a ? b : foo) + await bar; if (baz); }",
337 errors
: [VARIABLE_ERROR
]
340 code
: "let foo = 0; async function x() { foo = (a ? b ? c ? d ? foo : e : f : g : h) + await bar; if (baz); }",
341 errors
: [VARIABLE_ERROR
]
344 // https://github.com/eslint/eslint/issues/11723
347 async function f(foo) {
348 let buz = await get(foo.id);
352 errors
: [STATIC_PROPERTY_ERROR
]
355 // https://github.com/eslint/eslint/issues/15076
359 opts.spec = process.stdin;
361 const { exit_code } = await run(opts);
362 process.exitCode = exit_code;
364 process.exitCode = 1;
371 messageId
: "nonAtomicObjectUpdate",
372 data
: { value
: "process.exitCode", object
: "process" },
373 type
: "AssignmentExpression",
377 messageId
: "nonAtomicObjectUpdate",
378 data
: { value
: "process.exitCode", object
: "process" },
379 type
: "AssignmentExpression",
388 async function a(foo) {
390 foo.bar = await something;
394 errors
: [STATIC_PROPERTY_ERROR
]
404 errors
: [STATIC_PROPERTY_ERROR
]
408 async function a(foo) {
410 foo.bar = await something;
415 errors
: [STATIC_PROPERTY_ERROR
]
427 errors
: [STATIC_PROPERTY_ERROR
]
431 async function a(foo) {
433 foo.bar = await something;
437 options
: [{ allowProperties
: false }],
438 errors
: [STATIC_PROPERTY_ERROR
]
449 options
: [{ allowProperties
: false }],
450 errors
: [STATIC_PROPERTY_ERROR
]
457 foo = await something;
461 options
: [{ allowProperties
: true }],
462 errors
: [VARIABLE_ERROR
]
474 options
: [{ allowProperties
: true }],
475 errors
: [VARIABLE_ERROR
]