import type { Props } from "@alloy-js/core"; import { refkey, render, StatementList } from "@alloy-js/core"; import { describe, expect, it } from "vitest"; import { FunctionExpression } from "../src/components/FunctionExpression.jsx"; import { VarDeclaration } from "../src/index.js"; import type { ParameterDescriptor } from "../src/parameter-descriptor.js"; import { TestFile } from "./utils.js"; it("create basic function", () => { expect( , ).toRenderTo(` function () {} `); }); it("can be an async function", () => { expect( , ).toRenderTo(` async function () {} `); }); it("can be an async function with returnType", () => { expect( , ).toRenderTo(` async function (): Promise {} `); }); it("can be an async function with returnType element", () => { function Foo(_props?: Props) { return <>Foo; } expect( } /> , ).toRenderTo(` async function (): Promise {} `); }); it("supports parameters by element", () => { const decl = ( return a + b; a, b ); expect({decl}).toRenderTo(` function (a, b) { return a + b; } `); }); it("supports type parameters by descriptor object", () => { const decl = ( ); expect({decl}).toRenderTo(` function () {} `); }); it("supports type parameters by descriptor array", () => { const decl = ( ); expect({decl}).toRenderTo(` function () {} `); }); it("supports type parameters by element", () => { const decl = ( a, b ); expect({decl}).toRenderTo(` function () {} `); }); describe("symbols", () => { it("creates a nested scope", () => { const innerRefkey = refkey(); const outerRefkey = refkey(); const decl = ( {innerRefkey} 1 2 {outerRefkey} ); expect({decl}).toRenderTo(` function () { refme; const refme = 1; }; const refme = 2; refme; `); }); it("throws an error when trying to access a symbol in a nested function scope", () => { const innerRefkey = refkey(); const decl = ( <> 1 ;{innerRefkey} ); expect(() => render({decl}, { insertFinalNewLine: false }), ).toThrow(/Cannot reference a symbol/); }); it("creates symbols for parameters", () => { const rk = refkey(); const decl = ( {rk} ); expect({decl}).toRenderTo(` function (sym: any) { function () { sym } } `); }); it("creates symbols for parameters and addresses conflicts", () => { const decl = ( 1; ); expect({decl}).toRenderTo(` function (conflict: any) { const conflict_2 = 1; } `); }); it("create optional parameters", () => { const paramDesc: ParameterDescriptor = { name: "foo", refkey: refkey(), type: "any", optional: true, }; const decl = ( console.log(foo); ); expect({decl}).toRenderTo(` function (foo?: any) { console.log(foo); } `); }); it("create rest parameters", () => { const paramDesc: ParameterDescriptor = { name: "foo", refkey: refkey(), type: "any[]", rest: true, }; const decl = ( console.log(foo); ); expect({decl}).toRenderTo(` function (...foo: any[]) { console.log(foo); } `); }); });