import { describe, expect, it } from "vitest"; import { areWorldSettingsEqual, changeWorldBackgroundMode, cloneWorldSettings, createDefaultWorldCelestialOrbitAuthoringSettings, createDefaultWorldShaderSkySettings, createWorldCelestialOrbitSettingsFromPeakDirection, createDefaultWorldSettings } from "../../src/document/world-settings"; describe("world settings helpers", () => { it("clones world settings without retaining nested references", () => { const source = createDefaultWorldSettings(); const clone = cloneWorldSettings(source); expect(clone).toEqual(source); expect(clone).not.toBe(source); expect(clone.background).not.toBe(source.background); expect(clone.shaderSky).not.toBe(source.shaderSky); expect(clone.shaderSky.celestial).not.toBe(source.shaderSky.celestial); expect(clone.shaderSky.clouds).not.toBe(source.shaderSky.clouds); expect(clone.shaderSky.aurora).not.toBe(source.shaderSky.aurora); expect(clone.celestialOrbits).not.toBe(source.celestialOrbits); expect(clone.celestialOrbits.sun).not.toBe(source.celestialOrbits.sun); expect(clone.sunLight.direction).not.toBe(source.sunLight.direction); expect(clone.advancedRendering).not.toBe(source.advancedRendering); expect(clone.advancedRendering.shadows).not.toBe( source.advancedRendering.shadows ); expect(clone.advancedRendering.dynamicGlobalIllumination).not.toBe( source.advancedRendering.dynamicGlobalIllumination ); expect(clone.advancedRendering.whiteboxBevel).not.toBe( source.advancedRendering.whiteboxBevel ); }); it("switches a solid background into a gradient while preserving the authored color as the top edge", () => { const gradient = changeWorldBackgroundMode( { mode: "solid", colorHex: "#334455" }, "verticalGradient" ); expect(gradient).toEqual({ mode: "verticalGradient", topColorHex: "#334455", bottomColorHex: "#141a22" }); }); it("switches and clones image backgrounds by asset id", () => { const imageBackground = changeWorldBackgroundMode( { mode: "solid", colorHex: "#334455" }, "image", "asset-background-panorama" ); expect(imageBackground).toEqual({ mode: "image", assetId: "asset-background-panorama", environmentIntensity: 0.5 }); const nextImageBackground = changeWorldBackgroundMode( imageBackground, "image", "asset-background-panorama-2" ); expect(nextImageBackground).toEqual({ mode: "image", assetId: "asset-background-panorama-2", environmentIntensity: 0.5 }); const world = createDefaultWorldSettings(); world.background = nextImageBackground; const clonedWorld = cloneWorldSettings(world); expect(clonedWorld.background).toEqual(nextImageBackground); expect(clonedWorld.background).not.toBe(world.background); expect(areWorldSettingsEqual(world, clonedWorld)).toBe(true); }); it("switches into shader mode and restores the shader day gradient when switching back out", () => { const shaderBackground = changeWorldBackgroundMode( { mode: "verticalGradient", topColorHex: "#335577", bottomColorHex: "#99ccff" }, "shader" ); expect(shaderBackground).toEqual({ mode: "shader" }); const restoredGradient = changeWorldBackgroundMode( shaderBackground, "verticalGradient", undefined, undefined, { ...createDefaultWorldShaderSkySettings(), dayTopColorHex: "#335577", dayBottomColorHex: "#99ccff" } ); expect(restoredGradient).toEqual({ mode: "verticalGradient", topColorHex: "#335577", bottomColorHex: "#99ccff" }); }); it("compares authored world settings by value", () => { const left = createDefaultWorldSettings(); const right = cloneWorldSettings(left); expect(areWorldSettingsEqual(left, right)).toBe(true); right.sunLight.direction.x = right.sunLight.direction.x + 0.25; expect(areWorldSettingsEqual(left, right)).toBe(false); right.sunLight.direction.x = left.sunLight.direction.x; right.advancedRendering.bloom.intensity = right.advancedRendering.bloom.intensity + 0.1; expect(areWorldSettingsEqual(left, right)).toBe(false); }); it("treats water reflection mode as part of authored world equality", () => { const left = createDefaultWorldSettings(); const right = cloneWorldSettings(left); right.advancedRendering.waterReflectionMode = "all"; expect(areWorldSettingsEqual(left, right)).toBe(false); }); it("treats whitebox bevel settings as part of authored world equality", () => { const left = createDefaultWorldSettings(); const right = cloneWorldSettings(left); right.advancedRendering.whiteboxBevel.enabled = true; expect(areWorldSettingsEqual(left, right)).toBe(false); }); it("treats dynamic global illumination settings as part of authored world equality", () => { const left = createDefaultWorldSettings(); const right = cloneWorldSettings(left); right.advancedRendering.dynamicGlobalIllumination.enabled = true; expect(areWorldSettingsEqual(left, right)).toBe(false); }); it("treats the scene project-time lighting toggle as part of authored world equality", () => { const left = createDefaultWorldSettings(); const right = cloneWorldSettings(left); right.projectTimeLightingEnabled = false; expect(areWorldSettingsEqual(left, right)).toBe(false); }); it("treats the celestial body toggle as part of authored world equality", () => { const left = createDefaultWorldSettings(); const right = cloneWorldSettings(left); right.showCelestialBodies = true; expect(areWorldSettingsEqual(left, right)).toBe(false); }); it("treats shader sky horizon height as part of authored world equality", () => { const left = createDefaultWorldSettings(); const right = cloneWorldSettings(left); right.shaderSky.horizonHeight = 0.08; expect(areWorldSettingsEqual(left, right)).toBe(false); }); it("treats shader sky star horizon offset as part of authored world equality", () => { const left = createDefaultWorldSettings(); const right = cloneWorldSettings(left); right.shaderSky.stars.horizonFadeOffset = 0.08; expect(areWorldSettingsEqual(left, right)).toBe(false); }); it("treats shader sky aurora settings as part of authored world equality", () => { const left = createDefaultWorldSettings(); const right = cloneWorldSettings(left); right.shaderSky.aurora.enabled = true; expect(areWorldSettingsEqual(left, right)).toBe(false); }); it("treats celestial orbit settings as part of authored world equality", () => { const left = createDefaultWorldSettings(); const right = cloneWorldSettings(left); right.celestialOrbits.moon.azimuthDegrees = right.celestialOrbits.moon.azimuthDegrees + 12; expect(areWorldSettingsEqual(left, right)).toBe(false); }); it("derives default celestial orbit settings from a legacy sun direction", () => { const direction = { x: -0.6, y: 1, z: 0.35 }; const defaults = createDefaultWorldCelestialOrbitAuthoringSettings(direction); const derivedSunOrbit = createWorldCelestialOrbitSettingsFromPeakDirection(direction); expect(defaults.sun).toEqual(derivedSunOrbit); expect(defaults.moon).toEqual(derivedSunOrbit); }); });