import { describe, expect, it } from "vitest";
import { createAction } from "#lib/action.svelte.ts";
describe("createAction", () => {
it("derives ergonomic projections from one state", async () => {
let resolve!: (value: string) => void;
const action = createAction(() => new Promise<string>((done) => (resolve = done)));
expect(action.loading).toBe(false);
expect(action.data).toBeUndefined();
expect(action.error).toBeUndefined();
const running = action.run();
expect(action.loading).toBe(true);
resolve("done");
await running;
expect(action.data).toBe("done");
});
it("converts failures", async () => {
const action = createAction(
async () => {
throw new Error("nope");
},
(cause) => (cause instanceof Error ? cause.message : "unknown")
);
await action.run();
expect(action.error).toBe("nope");
});
it("ignores an older result after a newer run starts", async () => {
const resolvers: Array<(value: string) => void> = [];
const names: string[] = [];
const action = createAction(
(name: string) =>
new Promise<string>((resolve) => {
names.push(name);
resolvers.push(resolve);
})
);
const first = action.run("first");
const second = action.run("second");
expect(names).toEqual(["first", "second"]);
expect(action.args).toEqual(["second"]);
resolvers[0]("stale");
await first;
expect(action.loading).toBe(true);
resolvers[1]("current");
await second;
expect(action.data).toBe("current");
expect(action.args).toBeUndefined();
});
});