import { describe, it, expect } from "vitest";
import { Scope } from "./scope.js";
const numberType = { type: "primitiveType", value: "number" };
const stringType = { type: "primitiveType", value: "string" };
describe("Scope", () => {
    it("declares and looks up a variable in the same scope", () => {
        const scope = new Scope("function:foo");
        scope.declare("x", numberType);
        expect(scope.lookup("x")).toEqual(numberType);
    });
    it("returns undefined for an unknown variable", () => {
        const scope = new Scope("function:foo");
        expect(scope.lookup("missing")).toBeUndefined();
    });
    it("looks up variables from a parent scope through child().lookup()", () => {
        const parent = new Scope("function:foo");
        parent.declare("x", numberType);
        const child = parent.child();
        expect(child.lookup("x")).toEqual(numberType);
    });
    it("declare() on a child writes to the nearest function scope (function-scoped semantics)", () => {
        const parent = new Scope("function:foo");
        const child = parent.child();
        child.declare("y", stringType);
        expect(parent.lookup("y")).toEqual(stringType);
        expect(child.lookup("y")).toEqual(stringType);
    });
    it("has() reports presence including inherited bindings", () => {
        const parent = new Scope("function:foo");
        parent.declare("x", numberType);
        const child = parent.child();
        expect(child.has("x")).toBe(true);
        expect(child.has("missing")).toBe(false);
    });
    it("exposes the current scope key for type-alias resolution", () => {
        const scope = new Scope("function:foo");
        expect(scope.key).toBe("function:foo");
        const child = scope.child("block:if");
        expect(child.key).toBe("block:if");
    });
    it("isConst reflects whether a binding was declared as const", () => {
        const scope = new Scope("function:foo");
        scope.declare("c", numberType, true);
        scope.declare("v", numberType, false);
        scope.declare("d", numberType);
        expect(scope.isConst("c")).toBe(true);
        expect(scope.isConst("v")).toBe(false);
        expect(scope.isConst("d")).toBe(false);
        expect(scope.isConst("missing")).toBe(false);
    });
    it("isConst inherits from parent scopes", () => {
        const parent = new Scope("function:foo");
        parent.declare("c", numberType, true);
        const child = parent.child();
        expect(child.isConst("c")).toBe(true);
    });
});
