X Tutup
import { LuaLibImportKind } from "../../src"; import * as util from "../util"; const usingTestLib = ` export const logs: string[] = []; function loggedDisposable(id: string): Disposable { logs.push(\`Creating \${id}\`); return { [Symbol.dispose]() { logs.push(\`Disposing \${id}\`); } } }`; test("using disposes object at end of function", () => { util.testModule` function func() { using a = loggedDisposable("a"); using b = loggedDisposable("b"); logs.push("function content"); } func(); ` .setTsHeader(usingTestLib) .expectToEqual({ logs: ["Creating a", "Creating b", "function content", "Disposing b", "Disposing a"] }); }); test("handles multi-variable declarations", () => { util.testModule` function func() { using a = loggedDisposable("a"), b = loggedDisposable("b"); logs.push("function content"); } func(); ` .setTsHeader(usingTestLib) .expectToEqual({ logs: ["Creating a", "Creating b", "function content", "Disposing b", "Disposing a"] }); }); test("using disposes object at end of nested block", () => { util.testModule` function func() { using a = loggedDisposable("a"); { using b = loggedDisposable("b"); logs.push("nested block"); } logs.push("function content"); } func(); ` .setTsHeader(usingTestLib) .expectToEqual({ logs: ["Creating a", "Creating b", "nested block", "Disposing b", "function content", "Disposing a"], }); }); test("using does not affect function return value", () => { util.testModule` function func() { using a = loggedDisposable("a"); using b = loggedDisposable("b"); logs.push("function content"); return "success"; } export const result = func(); ` .setTsHeader(usingTestLib) .expectToEqual({ result: "success", logs: ["Creating a", "Creating b", "function content", "Disposing b", "Disposing a"], }); }); test("using disposes even when error happens", () => { util.testModule` function func() { using a = loggedDisposable("a"); using b = loggedDisposable("b"); throw "test-induced exception"; } try { func(); } catch (e) { logs.push(\`caught exception: \${e}\`); } ` .setTsHeader(usingTestLib) .expectToEqual({ logs: [ "Creating a", "Creating b", "Disposing b", "Disposing a", "caught exception: test-induced exception", ], }); }); test("await using disposes object with await at end of function", () => { util.testModule` let disposeAsync; function loggedAsyncDisposable(id: string): AsyncDisposable { logs.push(\`Creating \${id}\`); return { [Symbol.asyncDispose]() { logs.push(\`Disposing async \${id}\`); return new Promise(resolve => { disposeAsync = () => { logs.push(\`Disposed \${id}\`); resolve(); }; }); } } } async function func() { await using a = loggedAsyncDisposable("a"); logs.push("function content"); return "function result"; } const p = func().then(r => logs.push("promise resolved", r)); logs.push("function returned"); disposeAsync(); ` .setTsHeader(usingTestLib) .setOptions({ luaLibImport: LuaLibImportKind.Inline }) .expectToEqual({ logs: [ "Creating a", "function content", "Disposing async a", "function returned", "Disposed a", "promise resolved", "function result", ], }); }); test("await using can handle non-async disposables", () => { util.testModule` async function func() { await using a = loggedDisposable("a"); logs.push("function content"); } func(); ` .setTsHeader(usingTestLib) .expectToEqual({ logs: ["Creating a", "function content", "Disposing a"] }); }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1571 test("await using no extra diagnostics (#1571)", () => { util.testModule` async function getResource(): Promise { return { [Symbol.asyncDispose]: async () => {} }; } async function someOtherAsync() {} async function main() { await using resource = await getResource(); await someOtherAsync(); } `.expectToHaveNoDiagnostics(); }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1584 test("works with disposable classes (#1584)", () => { util.testFunction` const log = []; class Scoped { action(): void { log.push("action") } [Symbol.dispose]() { log.push("cleanup") } } function TestScoped(): void { using s = new Scoped(); s.action(); } TestScoped(); return log; `.expectToEqual(["action", "cleanup"]); }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1632 test("works on root level (#1632)", () => { util.testModule` export let disposed = false; class A { [Symbol.dispose] = function (this: A) { disposed = true; } } using a = new A(); `.expectToEqual({ disposed: true, }); });
X Tutup