1import { assert, describe, it } from "@effect/vitest";
2import * as HostProcess from "@t3tools/shared/HostProcess";
3import * as Cause from "effect/Cause";
4import * as Effect from "effect/Effect";
5import * as Layer from "effect/Layer";
6import { beforeEach, vi } from "vite-plus/test";
7
8const { networkInterfacesMock } = vi.hoisted(() => ({
9 networkInterfacesMock: vi.fn(),
10}));
11
12vi.mock("node:os", () => ({
13 networkInterfaces: networkInterfacesMock,
14}));
15
16import * as DesktopNetworkInterfaces from "./DesktopNetworkInterfaces.ts";
17
18const layerTest = DesktopNetworkInterfaces.layer.pipe(
19 Layer.provide(Layer.succeed(HostProcess.Platform, "linux")),
20);
21
22describe("DesktopNetworkInterfaces", () => {
23 beforeEach(() => {
24 networkInterfacesMock.mockReset();
25 });
26
27 it.effect("reads network interfaces through the service", () => {
28 const interfaces = {
29 en0: [
30 {
31 address: "192.168.1.10",
32 family: "IPv4",
33 internal: false,
34 },
35 ],
36 };
37 networkInterfacesMock.mockReturnValueOnce(interfaces);
38
39 return Effect.gen(function* () {
40 const service = yield* DesktopNetworkInterfaces.DesktopNetworkInterfaces;
41 assert.strictEqual(yield* service.read, interfaces);
42 }).pipe(Effect.provide(layerTest));
43 });
44
45 it.effect("preserves network interface read failures as structured defects", () => {
46 const cause = new Error("network interface probe failed");
47 networkInterfacesMock.mockImplementationOnce(() => {
48 throw cause;
49 });
50
51 return Effect.gen(function* () {
52 const service = yield* DesktopNetworkInterfaces.DesktopNetworkInterfaces;
53 const exit = yield* Effect.exit(service.read);
54
55 assert.equal(exit._tag, "Failure");
56 if (exit._tag === "Failure") {
57 const error = Cause.squash(exit.cause);
58 assert.instanceOf(error, DesktopNetworkInterfaces.DesktopNetworkInterfacesReadError);
59 assert.equal(error.platform, "linux");
60 assert.strictEqual(error.cause, cause);
61 assert.equal(error.message, "Failed to read desktop network interfaces on linux.");
62 }
63 }).pipe(Effect.provide(layerTest));
64 });
65});