fix: deep copy settings when duplicating an engine (#907)

This commit is contained in:
dualfroz committed 2026-09-26 09:42:46 +02:00
1 parent 3b3d5ed500
commit 01c5621cdb
3 files changed
+59 -5

No files matched your search

+2 -5
View File
@@ -44,6 +44,7 @@ import { commands } from "@/bindings";
import { Route } from "@/routes/engines"; import { Route } from "@/routes/engines";
import { enginesAtom } from "@/state/atoms"; import { enginesAtom } from "@/state/atoms";
import { import {
duplicateEngine,
type Engine, type Engine,
engineSchema, engineSchema,
type LocalEngine, type LocalEngine,
@@ -566,11 +567,7 @@ function EngineSettings({
leftSection={<IconCopy size="1rem" />} leftSection={<IconCopy size="1rem" />}
variant="default" variant="default"
onClick={() => { onClick={() => {
const duplicatedEngine: LocalEngine = { const duplicatedEngine = duplicateEngine(engine);
...engine,
id: crypto.randomUUID(),
name: `${engine.name} (Copy)`,
};
setEngines(async (prev) => { setEngines(async (prev) => {
const copy = [...(await prev)]; const copy = [...(await prev)];
copy.splice(selected + 1, 0, duplicatedEngine); copy.splice(selected + 1, 0, duplicatedEngine);
+8
View File
@@ -69,6 +69,14 @@ export type RemoteEngine = z.output<typeof remoteEngineSchema>;
export const engineSchema = z.union([localEngineSchema, remoteEngineSchema]); export const engineSchema = z.union([localEngineSchema, remoteEngineSchema]);
export type Engine = z.output<typeof engineSchema>; export type Engine = z.output<typeof engineSchema>;
export function duplicateEngine(engine: LocalEngine): LocalEngine {
return {
...structuredClone(engine),
id: crypto.randomUUID(),
name: `${engine.name} (Copy)`,
};
}
export function stopEngine(engine: LocalEngine, tab: string): Promise<void> { export function stopEngine(engine: LocalEngine, tab: string): Promise<void> {
return commands.stopEngine(engine.id, tab).then((r) => { return commands.stopEngine(engine.id, tab).then((r) => {
unwrap(r); unwrap(r);
+49
View File
@@ -0,0 +1,49 @@
import { expect, test } from "vitest";
import { duplicateEngine, type LocalEngine } from "../engines";
const stockfish: () => LocalEngine = () => ({
type: "local",
id: "stockfish",
name: "Stockfish",
version: "17",
path: "/usr/bin/stockfish",
go: { t: "Depth", c: 20 },
settings: [
{ name: "MultiPV", value: 1 },
{ name: "Threads", value: 4 },
{ name: "Hash", value: 16 },
],
});
test("duplicateEngine gives the copy a new id and name", () => {
const original = stockfish();
const copy = duplicateEngine(original);
expect(copy.id).not.toBe(original.id);
expect(copy.name).toBe("Stockfish (Copy)");
expect(copy.settings).toEqual(original.settings);
expect(copy.go).toEqual(original.go);
});
test("duplicateEngine does not share settings with the original", () => {
const original = stockfish();
const copy = duplicateEngine(original);
copy.settings!.find((s) => s.name === "Threads")!.value = 8;
copy.settings!.push({ name: "Ponder", value: true });
expect(original.settings).toEqual([
{ name: "MultiPV", value: 1 },
{ name: "Threads", value: 4 },
{ name: "Hash", value: 16 },
]);
});
test("duplicateEngine does not share the go mode with the original", () => {
const original = stockfish();
const copy = duplicateEngine(original);
(copy.go as { c: number }).c = 30;
expect(original.go).toEqual({ t: "Depth", c: 20 });
});