108 lines
3.7 KiB
TypeScript
108 lines
3.7 KiB
TypeScript
import { describe, test, expect } from "bun:test";
|
|
import { EffectCategory } from "../src/categories";
|
|
import type { EffectContext, EffectDefinition } from "../src/types";
|
|
|
|
import { skinSmoothEffectDefinition } from "../src/effects/skin-smooth";
|
|
import { faceBrightenEffectDefinition } from "../src/effects/face-brighten";
|
|
import { eyeEnhanceEffectDefinition } from "../src/effects/eye-enhance";
|
|
import { teethWhitenEffectDefinition } from "../src/effects/teeth-whiten";
|
|
import { blushEffectDefinition } from "../src/effects/blush";
|
|
import { slimFaceEffectDefinition } from "../src/effects/slim-face";
|
|
|
|
const defaultArgs = { width: 1920, height: 1080, time: 0 };
|
|
const mockContext: EffectContext = {
|
|
faceDetected: true,
|
|
cheekLeft: [0.3, 0.5],
|
|
cheekRight: [0.7, 0.5],
|
|
cheekRadius: 0.06,
|
|
jawPoints: [0.5, 0.65],
|
|
};
|
|
|
|
function validateBeautyEffect(def: EffectDefinition, type: string) {
|
|
test(`${type}: correct type and BEAUTY category`, () => {
|
|
expect(def.type).toBe(type);
|
|
expect(def.category).toBe(EffectCategory.BEAUTY);
|
|
});
|
|
|
|
test(`${type}: uniforms work without context (graceful fallback)`, () => {
|
|
const defaults: Record<string, number | string | boolean> = {};
|
|
for (const p of def.params) defaults[p.key] = p.default;
|
|
for (const pass of def.renderer.passes) {
|
|
const result = pass.uniforms({ effectParams: defaults, ...defaultArgs });
|
|
expect(typeof result).toBe("object");
|
|
}
|
|
});
|
|
|
|
test(`${type}: uniforms work with face context`, () => {
|
|
const defaults: Record<string, number | string | boolean> = {};
|
|
for (const p of def.params) defaults[p.key] = p.default;
|
|
for (const pass of def.renderer.passes) {
|
|
const result = pass.uniforms({ effectParams: defaults, ...defaultArgs, context: mockContext });
|
|
expect(typeof result).toBe("object");
|
|
}
|
|
});
|
|
}
|
|
|
|
describe("Skin Smooth", () => {
|
|
validateBeautyEffect(skinSmoothEffectDefinition, "skin-smooth");
|
|
test("has 2 passes (bilateral filter + mask)", () => {
|
|
expect(skinSmoothEffectDefinition.renderer.passes).toHaveLength(2);
|
|
});
|
|
});
|
|
|
|
describe("Face Brighten", () => {
|
|
validateBeautyEffect(faceBrightenEffectDefinition, "face-brighten");
|
|
test("single pass", () => {
|
|
expect(faceBrightenEffectDefinition.renderer.passes).toHaveLength(1);
|
|
});
|
|
});
|
|
|
|
describe("Eye Enhance", () => {
|
|
validateBeautyEffect(eyeEnhanceEffectDefinition, "eye-enhance");
|
|
test("has brightness and contrast params", () => {
|
|
expect(eyeEnhanceEffectDefinition.params.map((p) => p.key)).toEqual(["brightness", "contrast"]);
|
|
});
|
|
});
|
|
|
|
describe("Teeth Whiten", () => {
|
|
validateBeautyEffect(teethWhitenEffectDefinition, "teeth-whiten");
|
|
});
|
|
|
|
describe("Blush", () => {
|
|
validateBeautyEffect(blushEffectDefinition, "blush");
|
|
test("has color param", () => {
|
|
const colorParam = blushEffectDefinition.params.find((p) => p.key === "color");
|
|
expect(colorParam?.type).toBe("color");
|
|
});
|
|
test("uses context cheek positions when available", () => {
|
|
const pass = blushEffectDefinition.renderer.passes[0];
|
|
const result = pass.uniforms({
|
|
effectParams: { intensity: 50, color: "#ff9999" },
|
|
...defaultArgs,
|
|
context: mockContext,
|
|
});
|
|
expect(result.u_cheekLeft).toEqual([0.3, 0.5]);
|
|
});
|
|
test("falls back to defaults without context", () => {
|
|
const pass = blushEffectDefinition.renderer.passes[0];
|
|
const result = pass.uniforms({
|
|
effectParams: { intensity: 50, color: "#ff9999" },
|
|
...defaultArgs,
|
|
});
|
|
expect(result.u_cheekLeft).toEqual([0.35, 0.55]);
|
|
});
|
|
});
|
|
|
|
describe("Slim Face", () => {
|
|
validateBeautyEffect(slimFaceEffectDefinition, "slim-face");
|
|
test("uses jawPoints from context", () => {
|
|
const pass = slimFaceEffectDefinition.renderer.passes[0];
|
|
const result = pass.uniforms({
|
|
effectParams: { intensity: 50 },
|
|
...defaultArgs,
|
|
context: mockContext,
|
|
});
|
|
expect(result.u_jawCenter).toEqual([0.5, 0.65]);
|
|
});
|
|
});
|