Add tests for project time settings and runtime project time, update build-runtime-scene test
This commit is contained in:
@@ -298,9 +298,15 @@ describe("buildRuntimeSceneFromDocument", () => {
|
|||||||
y: 1.2,
|
y: 1.2,
|
||||||
z: 0.1
|
z: 0.1
|
||||||
};
|
};
|
||||||
|
document.time = {
|
||||||
|
startTimeOfDayHours: 18.5,
|
||||||
|
dayLengthMinutes: 16
|
||||||
|
};
|
||||||
|
|
||||||
const runtimeScene = buildRuntimeSceneFromDocument(document);
|
const runtimeScene = buildRuntimeSceneFromDocument(document);
|
||||||
|
|
||||||
|
expect(runtimeScene.time).toEqual(document.time);
|
||||||
|
expect(runtimeScene.time).not.toBe(document.time);
|
||||||
expect(runtimeScene.world).toEqual(document.world);
|
expect(runtimeScene.world).toEqual(document.world);
|
||||||
expect(runtimeScene.world).not.toBe(document.world);
|
expect(runtimeScene.world).not.toBe(document.world);
|
||||||
expect(runtimeScene.world.sunLight.direction).not.toBe(document.world.sunLight.direction);
|
expect(runtimeScene.world.sunLight.direction).not.toBe(document.world.sunLight.direction);
|
||||||
|
|||||||
32
tests/domain/project-time-settings.command.test.ts
Normal file
32
tests/domain/project-time-settings.command.test.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
|
||||||
|
import { createEditorStore } from "../../src/app/editor-store";
|
||||||
|
import { createSetProjectTimeSettingsCommand } from "../../src/commands/set-project-time-settings-command";
|
||||||
|
import { cloneProjectTimeSettings } from "../../src/document/project-time-settings";
|
||||||
|
|
||||||
|
describe("createSetProjectTimeSettingsCommand", () => {
|
||||||
|
it("updates project time settings and restores them through undo", () => {
|
||||||
|
const store = createEditorStore();
|
||||||
|
const originalTime = cloneProjectTimeSettings(
|
||||||
|
store.getState().projectDocument.time
|
||||||
|
);
|
||||||
|
const nextTime = {
|
||||||
|
startTimeOfDayHours: 18.5,
|
||||||
|
dayLengthMinutes: 12
|
||||||
|
};
|
||||||
|
|
||||||
|
store.executeCommand(
|
||||||
|
createSetProjectTimeSettingsCommand({
|
||||||
|
label: "Set project time",
|
||||||
|
time: nextTime
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(store.getState().projectDocument.time).toEqual(nextTime);
|
||||||
|
expect(store.getState().document.time).toEqual(nextTime);
|
||||||
|
|
||||||
|
expect(store.undo()).toBe(true);
|
||||||
|
expect(store.getState().projectDocument.time).toEqual(originalTime);
|
||||||
|
expect(store.getState().document.time).toEqual(originalTime);
|
||||||
|
});
|
||||||
|
});
|
||||||
62
tests/domain/runtime-project-time.test.ts
Normal file
62
tests/domain/runtime-project-time.test.ts
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
|
||||||
|
import { createDefaultWorldSettings } from "../../src/document/world-settings";
|
||||||
|
import {
|
||||||
|
advanceRuntimeClockState,
|
||||||
|
createRuntimeClockState,
|
||||||
|
resolveRuntimeDayNightWorldState
|
||||||
|
} from "../../src/runtime-three/runtime-project-time";
|
||||||
|
|
||||||
|
describe("runtime project time", () => {
|
||||||
|
it("advances and wraps the global clock using the authored day duration", () => {
|
||||||
|
const clock = createRuntimeClockState({
|
||||||
|
startTimeOfDayHours: 23.5,
|
||||||
|
dayLengthMinutes: 24
|
||||||
|
});
|
||||||
|
|
||||||
|
const advancedClock = advanceRuntimeClockState(clock, 60);
|
||||||
|
|
||||||
|
expect(advancedClock.timeOfDayHours).toBeCloseTo(0.5);
|
||||||
|
expect(advancedClock.dayCount).toBe(1);
|
||||||
|
expect(advancedClock.dayLengthMinutes).toBe(24);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("derives darker night lighting and background from the authored world", () => {
|
||||||
|
const world = createDefaultWorldSettings();
|
||||||
|
world.background = {
|
||||||
|
mode: "verticalGradient",
|
||||||
|
topColorHex: "#88ccff",
|
||||||
|
bottomColorHex: "#f2b774"
|
||||||
|
};
|
||||||
|
|
||||||
|
const noon = resolveRuntimeDayNightWorldState(world, {
|
||||||
|
timeOfDayHours: 12,
|
||||||
|
dayCount: 0,
|
||||||
|
dayLengthMinutes: 24
|
||||||
|
});
|
||||||
|
const midnight = resolveRuntimeDayNightWorldState(world, {
|
||||||
|
timeOfDayHours: 0,
|
||||||
|
dayCount: 0,
|
||||||
|
dayLengthMinutes: 24
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(midnight.sunLight.intensity).toBeLessThan(noon.sunLight.intensity);
|
||||||
|
expect(midnight.ambientLight.intensity).toBeLessThan(
|
||||||
|
noon.ambientLight.intensity
|
||||||
|
);
|
||||||
|
expect(noon.sunLight.direction.y).toBeGreaterThan(0);
|
||||||
|
expect(midnight.sunLight.direction.y).toBeLessThan(0);
|
||||||
|
|
||||||
|
if (
|
||||||
|
noon.background.mode !== "verticalGradient" ||
|
||||||
|
midnight.background.mode !== "verticalGradient"
|
||||||
|
) {
|
||||||
|
throw new Error("Expected a gradient background for the day/night test.");
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(midnight.background.topColorHex).not.toBe(noon.background.topColorHex);
|
||||||
|
expect(midnight.background.bottomColorHex).not.toBe(
|
||||||
|
noon.background.bottomColorHex
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
AUTHORED_OBJECT_STATE_SCENE_DOCUMENT_VERSION,
|
||||||
DEFAULT_PROJECT_NAME,
|
DEFAULT_PROJECT_NAME,
|
||||||
DEFAULT_SCENE_EDITOR_SNAP_STEP,
|
DEFAULT_SCENE_EDITOR_SNAP_STEP,
|
||||||
PLAYER_START_GAMEPAD_CAMERA_LOOK_SCENE_DOCUMENT_VERSION,
|
PLAYER_START_GAMEPAD_CAMERA_LOOK_SCENE_DOCUMENT_VERSION,
|
||||||
@@ -9,6 +10,7 @@ import {
|
|||||||
createEmptyProjectDocument,
|
createEmptyProjectDocument,
|
||||||
createEmptyProjectScene
|
createEmptyProjectScene
|
||||||
} from "../../src/document/scene-document";
|
} from "../../src/document/scene-document";
|
||||||
|
import { createDefaultProjectTimeSettings } from "../../src/document/project-time-settings";
|
||||||
import {
|
import {
|
||||||
createSceneEntryEntity,
|
createSceneEntryEntity,
|
||||||
createSceneExitEntity
|
createSceneExitEntity
|
||||||
@@ -106,12 +108,38 @@ describe("project document JSON", () => {
|
|||||||
normalStrength: 0.85
|
normalStrength: 0.85
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
document.time = {
|
||||||
|
startTimeOfDayHours: 18.5,
|
||||||
|
dayLengthMinutes: 16
|
||||||
|
};
|
||||||
|
|
||||||
const serializedDocument = serializeProjectDocument(document);
|
const serializedDocument = serializeProjectDocument(document);
|
||||||
|
|
||||||
expect(parseProjectDocumentJson(serializedDocument)).toEqual(document);
|
expect(parseProjectDocumentJson(serializedDocument)).toEqual(document);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("migrates pre-project-time multi-scene documents to default project time settings", () => {
|
||||||
|
const migratedDocument = parseProjectDocumentJson(
|
||||||
|
JSON.stringify({
|
||||||
|
version: AUTHORED_OBJECT_STATE_SCENE_DOCUMENT_VERSION,
|
||||||
|
name: "Legacy Project",
|
||||||
|
activeSceneId: "scene-main",
|
||||||
|
scenes: {
|
||||||
|
"scene-main": createEmptyProjectScene({
|
||||||
|
id: "scene-main",
|
||||||
|
name: "Legacy Entry"
|
||||||
|
})
|
||||||
|
},
|
||||||
|
materials: createEmptyProjectDocument().materials,
|
||||||
|
textures: {},
|
||||||
|
assets: {}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(migratedDocument.version).toBe(SCENE_DOCUMENT_VERSION);
|
||||||
|
expect(migratedDocument.time).toEqual(createDefaultProjectTimeSettings());
|
||||||
|
});
|
||||||
|
|
||||||
it("migrates pre-project-name multi-scene documents to Untitled Project", () => {
|
it("migrates pre-project-name multi-scene documents to Untitled Project", () => {
|
||||||
const migratedDocument = parseProjectDocumentJson(
|
const migratedDocument = parseProjectDocumentJson(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
|
|||||||
Reference in New Issue
Block a user