add auto-updater
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
import path from "node:path";
|
||||
import { describe, expect, test } from "vitest";
|
||||
|
||||
import {
|
||||
GitUpdateService,
|
||||
type CommandResult,
|
||||
type CommandRunner,
|
||||
} from "../../src/updater/git-update-service.js";
|
||||
|
||||
function result(stdout = "", code = 0, stderr = ""): CommandResult {
|
||||
return { code, stdout, stderr };
|
||||
}
|
||||
|
||||
function fakeRunner(responses: Map<string, CommandResult>): CommandRunner {
|
||||
return async (command, args) =>
|
||||
responses.get(`${command} ${args.join(" ")}`) ??
|
||||
result("", 1, "unexpected command");
|
||||
}
|
||||
|
||||
describe("GitUpdateService", () => {
|
||||
test("checks the currently checked-out branch", async () => {
|
||||
const root = path.resolve(".");
|
||||
const runner = fakeRunner(
|
||||
new Map([
|
||||
["git branch --show-current", result("feature/demo\n")],
|
||||
[
|
||||
"git fetch --quiet origin +refs/heads/feature/demo:refs/remotes/origin/feature/demo",
|
||||
result(),
|
||||
],
|
||||
["git rev-parse HEAD", result("aaa\n")],
|
||||
["git rev-parse refs/remotes/origin/feature/demo", result("bbb\n")],
|
||||
["git status --porcelain", result()],
|
||||
["git merge-base --is-ancestor aaa bbb", result()],
|
||||
["git log -1 --format=%s bbb", result("Useful update\n")],
|
||||
]),
|
||||
);
|
||||
|
||||
const update = await new GitUpdateService(root, runner).check();
|
||||
|
||||
expect(update).toMatchObject({
|
||||
status: "available",
|
||||
branch: "feature/demo",
|
||||
currentCommit: "aaa",
|
||||
targetCommit: "bbb",
|
||||
canApply: true,
|
||||
});
|
||||
});
|
||||
|
||||
test("reports an available update but blocks applying over local changes", async () => {
|
||||
const root = path.resolve(".");
|
||||
const runner = fakeRunner(
|
||||
new Map([
|
||||
["git branch --show-current", result("main\n")],
|
||||
[
|
||||
"git fetch --quiet origin +refs/heads/main:refs/remotes/origin/main",
|
||||
result(),
|
||||
],
|
||||
["git rev-parse HEAD", result("aaa\n")],
|
||||
["git rev-parse refs/remotes/origin/main", result("bbb\n")],
|
||||
["git status --porcelain", result(" M src/example.ts\n")],
|
||||
["git merge-base --is-ancestor aaa bbb", result()],
|
||||
["git log -1 --format=%s bbb", result("Update\n")],
|
||||
]),
|
||||
);
|
||||
|
||||
const update = await new GitUpdateService(root, runner).check();
|
||||
|
||||
expect(update).toMatchObject({ status: "available", canApply: false });
|
||||
});
|
||||
|
||||
test("does not replace commits when the local branch is ahead", async () => {
|
||||
const root = path.resolve(".");
|
||||
const runner = fakeRunner(
|
||||
new Map([
|
||||
["git branch --show-current", result("main\n")],
|
||||
[
|
||||
"git fetch --quiet origin +refs/heads/main:refs/remotes/origin/main",
|
||||
result(),
|
||||
],
|
||||
["git rev-parse HEAD", result("bbb\n")],
|
||||
["git rev-parse refs/remotes/origin/main", result("aaa\n")],
|
||||
["git status --porcelain", result()],
|
||||
["git merge-base --is-ancestor bbb aaa", result("", 1)],
|
||||
["git merge-base --is-ancestor aaa bbb", result()],
|
||||
]),
|
||||
);
|
||||
|
||||
await expect(
|
||||
new GitUpdateService(root, runner).check(),
|
||||
).resolves.toMatchObject({
|
||||
status: "up-to-date",
|
||||
branch: "main",
|
||||
currentCommit: "bbb",
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user