Initial Commit
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
import { describe, expect, it } from "@suaveplan/testing/runner";
|
||||
import z from "zod";
|
||||
import { AbstractAudioFxPlugin } from "../base/audio-fx-plugin.js";
|
||||
import {
|
||||
AUDIO_FX_CODES,
|
||||
type AudioFxError,
|
||||
} from "../error-codes/error-codes.js";
|
||||
import { PluginRegistry } from "./registry.js";
|
||||
|
||||
const SCHEMA = z.object({}).strict();
|
||||
const STEREO_IO = {
|
||||
inputs: [{ count: 2 as const }],
|
||||
outputs: [{ count: "preserve" as const }],
|
||||
};
|
||||
|
||||
class FixturePlugin extends AbstractAudioFxPlugin {
|
||||
public constructor(id: string) {
|
||||
super({
|
||||
metadata: { id, name: id, version: "1.0.0", category: "utility" },
|
||||
schema: SCHEMA,
|
||||
io: STEREO_IO,
|
||||
parameters: [],
|
||||
supportedSchemaVersion: 1,
|
||||
});
|
||||
}
|
||||
protected processBlock(
|
||||
input: Float32Array[],
|
||||
output: Float32Array[]
|
||||
): void {
|
||||
for (let ch = 0; ch < input.length; ch++) {
|
||||
output[ch]!.set(input[ch]!);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
describe("PluginRegistry: register + create", () => {
|
||||
it("registers a factory and creates fresh instances", {
|
||||
timeout: 5_000,
|
||||
}, () => {
|
||||
const r = new PluginRegistry();
|
||||
r.register("fx-a", () => new FixturePlugin("fx-a"));
|
||||
const a = r.create("fx-a");
|
||||
const b = r.create("fx-a");
|
||||
expect(a.metadata.id).toBe("fx-a");
|
||||
expect(b.metadata.id).toBe("fx-a");
|
||||
expect(a).not.toBe(b);
|
||||
});
|
||||
|
||||
it("has(pluginType) reflects registration state", {
|
||||
timeout: 5_000,
|
||||
}, () => {
|
||||
const r = new PluginRegistry();
|
||||
expect(r.has("fx-a")).toBe(false);
|
||||
r.register("fx-a", () => new FixturePlugin("fx-a"));
|
||||
expect(r.has("fx-a")).toBe(true);
|
||||
});
|
||||
|
||||
it("list() returns registered types in insertion order", {
|
||||
timeout: 5_000,
|
||||
}, () => {
|
||||
const r = new PluginRegistry();
|
||||
r.register("fx-b", () => new FixturePlugin("fx-b"));
|
||||
r.register("fx-a", () => new FixturePlugin("fx-a"));
|
||||
r.register("fx-c", () => new FixturePlugin("fx-c"));
|
||||
expect(r.list()).toEqual(["fx-b", "fx-a", "fx-c"]);
|
||||
});
|
||||
|
||||
it("re-registering a type overwrites the previous factory", {
|
||||
timeout: 5_000,
|
||||
}, () => {
|
||||
const r = new PluginRegistry();
|
||||
r.register("fx-a", () => new FixturePlugin("fx-a"));
|
||||
r.register("fx-a", () => new FixturePlugin("fx-a-2"));
|
||||
expect(r.create("fx-a").metadata.id).toBe("fx-a-2");
|
||||
expect(r.list()).toEqual(["fx-a"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("PluginRegistry: missing factory rejection", () => {
|
||||
it("create() rejects an unregistered type with CHAIN_SLOT_NOT_FOUND", {
|
||||
timeout: 5_000,
|
||||
}, () => {
|
||||
const r = new PluginRegistry();
|
||||
try {
|
||||
r.create("fx-missing");
|
||||
} catch (error) {
|
||||
expect((error as AudioFxError).code).toBe(
|
||||
AUDIO_FX_CODES.CHAIN_SLOT_NOT_FOUND
|
||||
);
|
||||
expect((error as AudioFxError).context).toEqual({
|
||||
pluginType: "fx-missing",
|
||||
});
|
||||
return;
|
||||
}
|
||||
throw new Error("expected CHAIN_SLOT_NOT_FOUND");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user