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);
}
`);
});
});