IKHSAN
EN Read in EnglishID

homeio

Publik

Fork dari doctor-io/homeio

Branch
main
Commit terakhir
958d74616 Oktober 2026

service.test.ts

Buka raw
import { mkdtemp, writeFile } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { beforeEach, describe, expect, it } from "vitest";
import { readTailLines } from "@/lib/server/modules/logs/service";

let dir: string;

async function logFile(content: string) {
  const filePath = path.join(dir, "home-server.log");
  await writeFile(filePath, content, "utf8");
  return filePath;
}

function numberedLines(count: number, width = 0) {
  return Array.from({ length: count }, (_, i) => `{"n":${i + 1},"pad":"${"x".repeat(width)}"}`);
}

describe("readTailLines", () => {
  beforeEach(async () => {
    dir = await mkdtemp(path.join(os.tmpdir(), "homeio-logs-"));
  });

  it("returns the last lines of a small file", async () => {
    const file = await logFile(`${numberedLines(10).join("\n")}\n`);

    expect(await readTailLines(file, 3)).toEqual(numberedLines(10).slice(-3));
  });

  it("returns every line when the file has fewer than asked", async () => {
    const file = await logFile("one\ntwo\n");

    expect(await readTailLines(file, 500)).toEqual(["one", "two"]);
  });

  it("reads only the end of a file much larger than one chunk", async () => {
    // ~9 MB: 60k lines of ~150 bytes, crossing many 64 KB chunk boundaries.
    const lines = numberedLines(60_000, 130);
    const file = await logFile(`${lines.join("\n")}\n`);

    expect(await readTailLines(file, 500)).toEqual(lines.slice(-500));
  });

  it("keeps the last line when the file does not end with a newline", async () => {
    const file = await logFile("one\ntwo\nthree");

    expect(await readTailLines(file, 2)).toEqual(["two", "three"]);
  });

  it("skips empty lines", async () => {
    const file = await logFile("one\n\n  \ntwo\n\n");

    expect(await readTailLines(file, 5)).toEqual(["one", "two"]);
  });

  it("keeps multi-byte characters whole across chunk boundaries", async () => {
    // 3-byte characters, so some of them straddle a 64 KB boundary.
    const lines = Array.from({ length: 3_000 }, (_, i) => `${i} ${"€".repeat(40)}`);
    const file = await logFile(`${lines.join("\n")}\n`);

    expect(await readTailLines(file, 2_000)).toEqual(lines.slice(-2_000));
  });

  it("returns nothing for a missing file", async () => {
    expect(await readTailLines(path.join(dir, "missing.log"), 500)).toEqual([]);
  });
});
byte
2.359
baris
68
Jenis
ts
Commit terakhir
16 Oktober 2026