disposal-during-non-local-jump-with-async-iterator-close-and-throws.js (2787B)
1 // |jit-test| skip-if: !getBuildConfiguration("explicit-resource-management"); --enable-explicit-resource-management 2 3 load(libdir + "asserts.js"); 4 5 class CustomError1 extends Error {} 6 class CustomError2 extends Error {} 7 8 function createIterator(values, throwingNature) { 9 return { 10 [Symbol.asyncIterator]: () => ({ 11 i: 0, 12 async return() { 13 values.push("return"); 14 if (throwingNature === "return" || throwingNature === "both") { 15 throw new CustomError2(); 16 } 17 return { done: true }; 18 }, 19 async next() { 20 return { 21 value: { 22 val: this.i++, 23 [Symbol.dispose]() { 24 values.push(this.val); 25 if ((throwingNature === "disposal" || throwingNature === "both") && this.val === 3) { 26 throw new CustomError1(); 27 } 28 } 29 }, 30 done: false 31 } 32 } 33 }) 34 } 35 } 36 37 { 38 const values = []; 39 const iterator = createIterator(values, "disposal"); 40 41 async function testDisposalThrowsAreThrown() { 42 for await (using d of iterator) { 43 if (d.val === 3) { 44 break; 45 } 46 } 47 } 48 49 assertThrowsInstanceOfAsync(testDisposalThrowsAreThrown, CustomError1); 50 assertArrayEq(values, [0, 1, 2, 3, "return"]); 51 } 52 53 { 54 const values = []; 55 const iterator = createIterator(values, "return"); 56 57 async function testReturnThrowsAreThrown() { 58 for await (using d of iterator) { 59 if (d.val === 3) { 60 break; 61 } 62 } 63 } 64 65 assertThrowsInstanceOfAsync(testReturnThrowsAreThrown, CustomError2); 66 assertArrayEq(values, [0, 1, 2, 3, "return"]); 67 } 68 69 { 70 const values = []; 71 const iterator = createIterator(values, "both"); 72 73 async function testReturnErrorsAreIgnoredIfDisposalThrows() { 74 for await (using d of iterator) { 75 if (d.val === 3) { 76 break; 77 } 78 } 79 } 80 81 assertThrowsInstanceOfAsync(testReturnErrorsAreIgnoredIfDisposalThrows, CustomError1); 82 assertArrayEq(values, [0, 1, 2, 3, "return"]); 83 } 84 85 { 86 let values = []; 87 88 async function testThrowsWithNonlocalJumpsWithLabels(iteratorThrowingNature) { 89 const iter = createIterator(values, iteratorThrowingNature); 90 outer: { 91 for await (using d of iter) { 92 if (d.val === 3) { 93 break outer; 94 } 95 } 96 } 97 } 98 99 assertThrowsInstanceOfAsync(() => testThrowsWithNonlocalJumpsWithLabels("disposal"), CustomError1); 100 assertArrayEq(values, [0, 1, 2, 3, "return"]); 101 102 values = []; 103 104 assertThrowsInstanceOfAsync(() => testThrowsWithNonlocalJumpsWithLabels("return"), CustomError2); 105 assertArrayEq(values, [0, 1, 2, 3, "return"]); 106 107 values = []; 108 assertThrowsInstanceOfAsync(() => testThrowsWithNonlocalJumpsWithLabels("both"), CustomError1); 109 assertArrayEq(values, [0, 1, 2, 3, "return"]); 110 }