auto-git:

[add] tests/unit/quantized-environment-blend-cache.test.ts
This commit is contained in:
2026-04-22 13:46:44 +02:00
parent 76b104fee9
commit 81b633a78f

View File

@@ -0,0 +1,135 @@
import { Texture } from "three";
import { describe, expect, it, vi } from "vitest";
import {
createQuantizedEnvironmentBlendCacheKey,
getQuantizedEnvironmentBlendAmount,
QuantizedEnvironmentBlendCache,
quantizeEnvironmentBlendBucket
} from "../../src/rendering/quantized-environment-blend-cache";
describe("quantized environment blend cache helpers", () => {
it("quantizes twilight blend amounts into fixed buckets", () => {
expect(quantizeEnvironmentBlendBucket(0, 8)).toBe(0);
expect(quantizeEnvironmentBlendBucket(0.24, 8)).toBe(2);
expect(quantizeEnvironmentBlendBucket(0.51, 8)).toBe(4);
expect(quantizeEnvironmentBlendBucket(1, 8)).toBe(8);
expect(getQuantizedEnvironmentBlendAmount(5, 8)).toBeCloseTo(0.625);
});
it("keys cached blends by ordered source pair and bucket", () => {
const dayTexture = new Texture();
const nightTexture = new Texture();
expect(
createQuantizedEnvironmentBlendCacheKey(dayTexture, nightTexture, 3)
).not.toBe(
createQuantizedEnvironmentBlendCacheKey(nightTexture, dayTexture, 3)
);
expect(
createQuantizedEnvironmentBlendCacheKey(dayTexture, nightTexture, 2)
).not.toBe(
createQuantizedEnvironmentBlendCacheKey(dayTexture, nightTexture, 3)
);
});
});
describe("QuantizedEnvironmentBlendCache", () => {
it("queues exact bucket builds, reuses the nearest cached bucket while pending, and disposes cached entries", () => {
const scheduledBuilds: Array<() => void> = [];
const disposeSpies: Array<ReturnType<typeof vi.fn>> = [];
const buildBlendTexture = vi.fn(
(
_baseTexture: Texture,
_overlayTexture: Texture,
_blendAmount: number
) => {
const dispose = vi.fn();
disposeSpies.push(dispose);
return {
texture: new Texture(),
dispose
};
}
);
const onTextureReady = vi.fn();
const cache = new QuantizedEnvironmentBlendCache({
bucketCount: 8,
buildBlendTexture,
onTextureReady,
scheduleBuild: (callback) => {
scheduledBuilds.push(callback);
}
});
const dayTexture = new Texture();
const nightTexture = new Texture();
expect(cache.resolveBlendTexture(dayTexture, nightTexture, 0.26)).toBeNull();
expect(buildBlendTexture).not.toHaveBeenCalled();
expect(scheduledBuilds).toHaveLength(1);
scheduledBuilds.shift()?.();
expect(buildBlendTexture).toHaveBeenCalledWith(
dayTexture,
nightTexture,
0.25
);
expect(onTextureReady).toHaveBeenCalledTimes(1);
const firstBlendTexture = cache.resolveBlendTexture(
dayTexture,
nightTexture,
0.24
);
expect(firstBlendTexture).not.toBeNull();
expect(
cache.resolveBlendTexture(dayTexture, nightTexture, 0.62)
).toBe(firstBlendTexture);
expect(scheduledBuilds).toHaveLength(1);
scheduledBuilds.shift()?.();
const laterBlendTexture = cache.resolveBlendTexture(
dayTexture,
nightTexture,
0.62
);
expect(laterBlendTexture).not.toBe(firstBlendTexture);
expect(onTextureReady).toHaveBeenCalledTimes(2);
cache.clear();
expect(disposeSpies).toHaveLength(2);
expect(disposeSpies[0]).toHaveBeenCalledTimes(1);
expect(disposeSpies[1]).toHaveBeenCalledTimes(1);
});
it("returns the authored single-image environment at the quantized endpoints and disposes builder resources", () => {
const disposeBuildResources = vi.fn();
const buildBlendTexture = vi.fn();
const cache = new QuantizedEnvironmentBlendCache({
bucketCount: 8,
buildBlendTexture,
disposeBuildResources,
scheduleBuild: () => undefined
});
const dayTexture = new Texture();
const nightTexture = new Texture();
expect(cache.resolveBlendTexture(dayTexture, nightTexture, 0.01)).toBe(
dayTexture
);
expect(cache.resolveBlendTexture(dayTexture, nightTexture, 0.99)).toBe(
nightTexture
);
expect(buildBlendTexture).not.toHaveBeenCalled();
cache.dispose();
expect(disposeBuildResources).toHaveBeenCalledTimes(1);
});
});