async-disposable-stack-use-dispose.js (4795B)
1 // |jit-test| skip-if: !getBuildConfiguration("explicit-resource-management"); --enable-explicit-resource-management 2 3 load(libdir + "asserts.js"); 4 5 { 6 const disposed = []; 7 const stack = new AsyncDisposableStack(); 8 async function testDisposalsWithAsyncDisposableStack() { 9 const obj = { 10 [Symbol.asyncDispose]() { 11 disposed.push(1); 12 }, 13 }; 14 stack.use(obj); 15 assertEq(stack.disposed, false); 16 assertEq(await stack.disposeAsync(), undefined); 17 } 18 testDisposalsWithAsyncDisposableStack(); 19 drainJobQueue(); 20 assertEq(stack.disposed, true); 21 assertArrayEq(disposed, [1]); 22 23 // `use` should throw if the stack is already disposed. 24 assertThrowsInstanceOf(() => stack.use({ [Symbol.asyncDispose]: () => {} }), ReferenceError); 25 } 26 27 { 28 const disposed = []; 29 const stack = new AsyncDisposableStack(); 30 async function testAsyncDisposableStackMultipleDispose() { 31 for (let i = 0; i < 5; i++) { 32 stack.use({ 33 [Symbol.dispose]() { 34 disposed.push(i); 35 }, 36 }); 37 } 38 assertEq(stack.disposed, false); 39 await stack.disposeAsync(); 40 41 // Calling again shouldn't do anything. 42 await stack.disposeAsync(); 43 } 44 testAsyncDisposableStackMultipleDispose(); 45 drainJobQueue(); 46 assertEq(stack.disposed, true); 47 assertArrayEq(disposed, [4, 3, 2, 1, 0]); 48 } 49 50 { 51 const disposed = []; 52 const stack = new AsyncDisposableStack(); 53 async function testAsyncDisposableStackUseWithFallback() { 54 stack.use({ 55 [Symbol.asyncDispose]() { 56 disposed.push(1); 57 } 58 }); 59 stack.use({ 60 [Symbol.dispose]() { 61 disposed.push(2); 62 } 63 }); 64 stack.use({ 65 [Symbol.asyncDispose]: undefined, 66 [Symbol.dispose]() { 67 disposed.push(3); 68 } 69 }); 70 stack.use({ 71 [Symbol.asyncDispose]: null, 72 [Symbol.dispose]() { 73 disposed.push(4); 74 } 75 }); 76 stack.use({ 77 [Symbol.asyncDispose]() { 78 disposed.push(5); 79 }, 80 [Symbol.dispose]() { 81 // This shouldn't be called because @@asyncDispose exists. 82 disposed.push(6); 83 } 84 }); 85 assertEq(stack.disposed, false); 86 await stack.disposeAsync(); 87 } 88 testAsyncDisposableStackUseWithFallback(); 89 drainJobQueue(); 90 assertEq(stack.disposed, true); 91 assertArrayEq(disposed, [5, 4, 3, 2, 1]); 92 } 93 94 { 95 const disposed = []; 96 const stack = new AsyncDisposableStack(); 97 for (let i = 0; i < 5; i++) { 98 stack.use({ 99 [Symbol.asyncDispose]() { 100 disposed.push(i); 101 }, 102 }); 103 } 104 assertEq(stack.disposed, false); 105 async function testAsyncDisposableStackWithUsingDecl() { 106 { 107 await using stk = stack; 108 stk.use({ 109 [Symbol.asyncDispose]() { 110 disposed.push(5); 111 }, 112 }); 113 stk.use({ 114 [Symbol.dispose]() { 115 disposed.push(6); 116 } 117 }); 118 } 119 assertEq(stack.disposed, true); 120 { 121 // This should be no-op. 122 await using stk2 = stack; 123 } 124 assertEq(stack.disposed, true); 125 } 126 testAsyncDisposableStackWithUsingDecl(); 127 drainJobQueue(); 128 assertArrayEq(disposed, [6, 5, 4, 3, 2, 1, 0]); 129 } 130 131 { 132 const disposed = []; 133 const stack = new AsyncDisposableStack(); 134 async function testAsyncDisposableStackWithNullUndefineds() { 135 stack.use(undefined); 136 stack.use(null); 137 stack.use({ 138 [Symbol.asyncDispose]() { 139 disposed.push(1); 140 } 141 }); 142 await stack.disposeAsync(); 143 } 144 testAsyncDisposableStackWithNullUndefineds(); 145 drainJobQueue(); 146 assertArrayEq(disposed, [1]); 147 assertEq(stack.disposed, true); 148 } 149 150 { 151 const disposed = []; 152 const stack = new AsyncDisposableStack(); 153 let error; 154 stack.use({ 155 [Symbol.asyncDispose]() { 156 disposed.push(1); 157 158 // This method is called during disposal, and before the 159 // disposal process is started the stack's state is set to disposed. 160 // Thus, calling stack use here again would throw. 161 stack.use({ 162 [Symbol.asyncDispose]() { 163 disposed.push(2); 164 }, 165 }); 166 } 167 }); 168 stack.disposeAsync().catch((e) => { 169 error = e; 170 }); 171 drainJobQueue(); 172 assertEq(error instanceof ReferenceError, true); 173 assertArrayEq(disposed, [1]); 174 assertEq(stack.disposed, true); 175 } 176 177 { 178 assertThrowsInstanceOf(() => { 179 const stack = new AsyncDisposableStack(); 180 stack.use(1); 181 }, TypeError); 182 } 183 184 { 185 assertThrowsInstanceOf(() => { 186 const stack = new AsyncDisposableStack(); 187 stack.use({ 188 [Symbol.asyncDispose]: undefined 189 }); 190 }, TypeError); 191 192 assertThrowsInstanceOf(() => { 193 const stack = new AsyncDisposableStack(); 194 stack.use({ 195 [Symbol.asyncDispose]: null 196 }); 197 }, TypeError); 198 199 assertThrowsInstanceOf(() => { 200 const stack = new AsyncDisposableStack(); 201 stack.use({ 202 [Symbol.asyncDispose]: 1 203 }); 204 }, TypeError); 205 }