Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  slots.test.ts

  Sprache: JAVA
 

Spracherkennung für: .ts vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

import { describe, expect, it } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import {
  applyExclusiveSlotSelection,
  hasKind,
  kindsEqual,
  normalizeKinds,
  slotKeysForPluginKind,
} from "./slots.js";
import type { PluginKind } from "./types.js";

describe("applyExclusiveSlotSelection", () => {
  const createMemoryConfig = (plugins?: OpenClawConfig["plugins"]): OpenClawConfig => ({
    plugins: {
      ...plugins,
      entries: {
        ...plugins?.entries,
        memory: {
          enabled: true,
          ...plugins?.entries?.memory,
        },
      },
    },
  });

  const runMemorySelection = (config: OpenClawConfig, selectedId = "memory") =>
    applyExclusiveSlotSelection({
      config,
      selectedId,
      selectedKind: "memory",
      registry: {
        plugins: [
          { id: "memory-core", kind: "memory" },
          { id: "memory", kind: "memory" },
        ],
      },
    });

  function expectMemorySelectionState(
    result: ReturnType<typeof applyExclusiveSlotSelection>,
    params: {
      changed: boolean;
      selectedId?: string;
      disabledCompetingPlugin?: boolean;
    },
  ) {
    expect(result.changed).toBe(params.changed);
    if (params.selectedId) {
      expect(result.config.plugins?.slots?.memory).toBe(params.selectedId);
    }
    if (params.disabledCompetingPlugin != null) {
      expect(result.config.plugins?.entries?.["memory-core"]?.enabled).toBe(
        params.disabledCompetingPlugin,
      );
    }
  }

  function expectSelectionWarnings(
    warnings: string[],
    params: {
      contains?: readonly string[];
      excludes?: readonly string[];
    },
  ) {
    if (params.contains?.length) {
      expect(warnings).toEqual(expect.arrayContaining([...params.contains]));
    }
    for (const warning of params.excludes ?? []) {
      expect(warnings).not.toEqual(expect.arrayContaining([warning]));
    }
  }

  function expectUnchangedSelection(result: ReturnType<typeof applyExclusiveSlotSelection>) {
    expect(result.changed).toBe(false);
    expect(result.warnings).toHaveLength(0);
  }

  function buildSelectionRegistry(
    plugins: ReadonlyArray<{ id: string; kind?: PluginKind | PluginKind[] }>,
  ) {
    return {
      plugins: [...plugins],
    };
  }

  function expectUnchangedSelectionCase(params: {
    config: OpenClawConfig;
    selectedId: string;
    selectedKind?: PluginKind | PluginKind[];
    registry?: { plugins: ReadonlyArray<{ id: string; kind?: PluginKind | PluginKind[] }> };
  }) {
    const result = applyExclusiveSlotSelection({
      config: params.config,
      selectedId: params.selectedId,
      ...(params.selectedKind ? { selectedKind: params.selectedKind } : {}),
      ...(params.registry
        ? {
            registry: buildSelectionRegistry(params.registry.plugins),
          }
        : {}),
    });

    expectUnchangedSelection(result);
    expect(result.config).toBe(params.config);
  }

  function expectChangedSelectionCase(params: {
    config: OpenClawConfig;
    selectedId?: string;
    expectedDisabled?: boolean;
    warningChecks: {
      contains?: readonly string[];
      excludes?: readonly string[];
    };
  }) {
    const result = runMemorySelection(params.config, params.selectedId);

    expectMemorySelectionState(result, {
      changed: true,
      selectedId: params.selectedId ?? "memory",
      ...(params.expectedDisabled != null
        ? { disabledCompetingPlugin: params.expectedDisabled }
        : {}),
    });
    expectSelectionWarnings(result.warnings, params.warningChecks);
  }

  it.each([
    {
      name: "selects the slot and disables other entries for the same kind",
      config: createMemoryConfig({
        slots: { memory: "memory-core" },
        entries: { "memory-core": { enabled: true } },
      }),
      expectedDisabled: false,
      warningChecks: {
        contains: [
          'Exclusive slot "memory" switched from "memory-core" to "memory".',
          'Disabled other "memory" slot plugins: memory-core.',
        ],
      },
    },
    {
      name: "warns when the slot falls back to a default",
      config: createMemoryConfig(),
      warningChecks: {
        contains: ['Exclusive slot "memory" switched from "memory-core" to "memory".'],
      },
    },
    {
      name: "keeps disabled competing plugins disabled without adding disable warnings",
      config: createMemoryConfig({
        entries: {
          "memory-core": { enabled: false },
        },
      }),
      expectedDisabled: false,
      warningChecks: {
        contains: ['Exclusive slot "memory" switched from "memory-core" to "memory".'],
        excludes: ['Disabled other "memory" slot plugins: memory-core.'],
      },
    },
  ] as const)("$name", ({ config, expectedDisabled, warningChecks }) => {
    expectChangedSelectionCase({
      config,
      ...(expectedDisabled != null ? { expectedDisabled } : {}),
      warningChecks,
    });
  });

  it.each([
    {
      name: "does nothing when the slot already matches",
      config: createMemoryConfig({
        slots: { memory: "memory" },
      }),
      selectedId: "memory",
      selectedKind: "memory",
      registry: { plugins: [{ id: "memory", kind: "memory" }] },
    },
    {
      name: "skips changes when no exclusive slot applies",
      config: {} as OpenClawConfig,
      selectedId: "custom",
    },
  ] as const)("$name", ({ config, selectedId, selectedKind, registry }) => {
    expectUnchangedSelectionCase({
      config,
      selectedId,
      ...(selectedKind ? { selectedKind } : {}),
      ...(registry ? { registry: buildSelectionRegistry(registry.plugins) } : {}),
    });
  });

  it("applies slot selection for each kind in a multi-kind array", () => {
    const config: OpenClawConfig = {
      plugins: {
        slots: { memory: "memory-core", contextEngine: "legacy" },
        entries: {
          "memory-core": { enabled: true },
          legacy: { enabled: true },
        },
      },
    };
    const result = applyExclusiveSlotSelection({
      config,
      selectedId: "dual-plugin",
      selectedKind: ["memory", "context-engine"],
      registry: buildSelectionRegistry([
        { id: "memory-core", kind: "memory" },
        { id: "legacy", kind: "context-engine" },
        { id: "dual-plugin", kind: ["memory", "context-engine"] },
      ]),
    });
    expect(result.changed).toBe(true);
    expect(result.config.plugins?.slots?.memory).toBe("dual-plugin");
    expect(result.config.plugins?.slots?.contextEngine).toBe("dual-plugin");
    expect(result.config.plugins?.entries?.["memory-core"]?.enabled).toBe(false);
    expect(result.config.plugins?.entries?.legacy?.enabled).toBe(false);
  });

  it("does not disable a dual-kind plugin that still owns another slot", () => {
    const config: OpenClawConfig = {
      plugins: {
        slots: { memory: "dual-plugin", contextEngine: "dual-plugin" },
        entries: {
          "dual-plugin": { enabled: true },
        },
      },
    };
    const result = applyExclusiveSlotSelection({
      config,
      selectedId: "new-memory",
      selectedKind: "memory",
      registry: buildSelectionRegistry([
        { id: "dual-plugin", kind: ["memory", "context-engine"] },
        { id: "new-memory", kind: "memory" },
      ]),
    });
    expect(result.changed).toBe(true);
    expect(result.config.plugins?.slots?.memory).toBe("new-memory");
    // dual-plugin still owns contextEngine — must NOT be disabled
    expect(result.config.plugins?.entries?.["dual-plugin"]?.enabled).not.toBe(false);
  });

  it("does not disable a dual-kind plugin that owns another slot via default", () => {
    // contextEngine is NOT explicitly set — defaults to "legacy"
    const config: OpenClawConfig = {
      plugins: {
        slots: { memory: "legacy" },
        entries: {
          legacy: { enabled: true },
        },
      },
    };
    const result = applyExclusiveSlotSelection({
      config,
      selectedId: "new-memory",
      selectedKind: "memory",
      registry: buildSelectionRegistry([
        { id: "legacy", kind: ["memory", "context-engine"] },
        { id: "new-memory", kind: "memory" },
      ]),
    });
    expect(result.changed).toBe(true);
    expect(result.config.plugins?.slots?.memory).toBe("new-memory");
    // legacy still owns contextEngine via default — must NOT be disabled
    expect(result.config.plugins?.entries?.legacy?.enabled).not.toBe(false);
  });
});

describe("normalizeKinds", () => {
  it("returns empty array for undefined", () => {
    expect(normalizeKinds(undefined)).toEqual([]);
  });

  it("wraps a single kind in an array", () => {
    expect(normalizeKinds("memory")).toEqual(["memory"]);
  });

  it("returns an array kind as-is", () => {
    expect(normalizeKinds(["memory", "context-engine"])).toEqual(["memory", "context-engine"]);
  });
});

describe("hasKind", () => {
  it("returns false for undefined kind", () => {
    expect(hasKind(undefined, "memory")).toBe(false);
  });

  it("matches a single kind string", () => {
    expect(hasKind("memory", "memory")).toBe(true);
    expect(hasKind("memory", "context-engine")).toBe(false);
  });

  it("matches within a kind array", () => {
    expect(hasKind(["memory", "context-engine"], "memory")).toBe(true);
    expect(hasKind(["memory", "context-engine"], "context-engine")).toBe(true);
  });
});

describe("slotKeysForPluginKind", () => {
  it("returns empty for undefined", () => {
    expect(slotKeysForPluginKind(undefined)).toEqual([]);
  });

  it("returns single slot key for single kind", () => {
    expect(slotKeysForPluginKind("memory")).toEqual(["memory"]);
  });

  it("returns multiple slot keys for multi-kind", () => {
    expect(slotKeysForPluginKind(["memory", "context-engine"])).toEqual([
      "memory",
      "contextEngine",
    ]);
  });
});

describe("kindsEqual", () => {
  it("treats undefined as equal to undefined", () => {
    expect(kindsEqual(undefined, undefined)).toBe(true);
  });

  it("matches identical strings", () => {
    expect(kindsEqual("memory", "memory")).toBe(true);
  });

  it("rejects different strings", () => {
    expect(kindsEqual("memory", "context-engine")).toBe(false);
  });

  it("matches arrays in different order", () => {
    expect(kindsEqual(["memory", "context-engine"], ["context-engine", "memory"])).toBe(true);
  });

  it("matches string against single-element array", () => {
    expect(kindsEqual("memory", ["memory"])).toBe(true);
  });

  it("rejects mismatched lengths", () => {
    expect(kindsEqual("memory", ["memory", "context-engine"])).toBe(false);
  });
});

¤ Dauer der Verarbeitung: 0.19 Sekunden  (vorverarbeitet am  2026-04-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge