332 lines
7.9 KiB
TypeScript
332 lines
7.9 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import { createEditorStore } from "../../src/app/editor-store";
|
|
import { createCreateBoxBrushCommand } from "../../src/commands/create-box-brush-command";
|
|
import { createMoveBoxBrushCommand } from "../../src/commands/move-box-brush-command";
|
|
import { createRotateBoxBrushCommand } from "../../src/commands/rotate-box-brush-command";
|
|
import { createResizeBoxBrushCommand } from "../../src/commands/resize-box-brush-command";
|
|
import { createSetBoxBrushNameCommand } from "../../src/commands/set-box-brush-name-command";
|
|
import { createSetBoxBrushVolumeSettingsCommand } from "../../src/commands/set-box-brush-volume-settings-command";
|
|
|
|
describe("box brush commands", () => {
|
|
it("creates a canonical box brush and supports undo/redo", () => {
|
|
const store = createEditorStore();
|
|
|
|
store.executeCommand(
|
|
createCreateBoxBrushCommand({
|
|
center: {
|
|
x: 1.2,
|
|
y: 1.1,
|
|
z: -0.6
|
|
},
|
|
size: {
|
|
x: 2.2,
|
|
y: 2.7,
|
|
z: 3.6
|
|
}
|
|
})
|
|
);
|
|
|
|
const brush = Object.values(store.getState().document.brushes)[0];
|
|
|
|
expect(brush).toBeDefined();
|
|
expect(brush.kind).toBe("box");
|
|
expect(brush.center).toEqual({
|
|
x: 1,
|
|
y: 1,
|
|
z: -1
|
|
});
|
|
expect(brush.rotationDegrees).toEqual({
|
|
x: 0,
|
|
y: 0,
|
|
z: 0
|
|
});
|
|
expect(brush.size).toEqual({
|
|
x: 2,
|
|
y: 3,
|
|
z: 4
|
|
});
|
|
expect(Object.keys(brush.faces)).toEqual(["posX", "negX", "posY", "negY", "posZ", "negZ"]);
|
|
expect(brush.faces.posX).toEqual({
|
|
materialId: null,
|
|
uv: {
|
|
offset: {
|
|
x: 0,
|
|
y: 0
|
|
},
|
|
scale: {
|
|
x: 1,
|
|
y: 1
|
|
},
|
|
rotationQuarterTurns: 0,
|
|
flipU: false,
|
|
flipV: false
|
|
}
|
|
});
|
|
expect(store.getState().selection).toEqual({
|
|
kind: "brushes",
|
|
ids: [brush.id]
|
|
});
|
|
|
|
expect(store.undo()).toBe(true);
|
|
expect(store.getState().document.brushes).toEqual({});
|
|
|
|
expect(store.redo()).toBe(true);
|
|
expect(store.getState().document.brushes[brush.id]).toEqual(brush);
|
|
});
|
|
|
|
it("moves and resizes a box brush through undoable commands", () => {
|
|
const store = createEditorStore();
|
|
|
|
store.executeCommand(createCreateBoxBrushCommand());
|
|
|
|
const createdBrush = Object.values(store.getState().document.brushes)[0];
|
|
|
|
store.executeCommand(
|
|
createMoveBoxBrushCommand({
|
|
brushId: createdBrush.id,
|
|
center: {
|
|
x: 2.4,
|
|
y: 3.2,
|
|
z: -1.7
|
|
}
|
|
})
|
|
);
|
|
store.executeCommand(
|
|
createResizeBoxBrushCommand({
|
|
brushId: createdBrush.id,
|
|
size: {
|
|
x: 4.2,
|
|
y: 1.2,
|
|
z: 0.2
|
|
}
|
|
})
|
|
);
|
|
|
|
expect(store.getState().document.brushes[createdBrush.id].center).toEqual({
|
|
x: 2,
|
|
y: 3,
|
|
z: -2
|
|
});
|
|
expect(store.getState().document.brushes[createdBrush.id].size).toEqual({
|
|
x: 4,
|
|
y: 1,
|
|
z: 1
|
|
});
|
|
|
|
expect(store.undo()).toBe(true);
|
|
expect(store.getState().document.brushes[createdBrush.id].size).toEqual({
|
|
x: 2,
|
|
y: 2,
|
|
z: 2
|
|
});
|
|
|
|
expect(store.undo()).toBe(true);
|
|
expect(store.getState().document.brushes[createdBrush.id].center).toEqual({
|
|
x: 0,
|
|
y: 1,
|
|
z: 0
|
|
});
|
|
|
|
expect(store.redo()).toBe(true);
|
|
expect(store.redo()).toBe(true);
|
|
expect(store.getState().document.brushes[createdBrush.id].center).toEqual({
|
|
x: 2,
|
|
y: 3,
|
|
z: -2
|
|
});
|
|
expect(store.getState().document.brushes[createdBrush.id].size).toEqual({
|
|
x: 4,
|
|
y: 1,
|
|
z: 1
|
|
});
|
|
});
|
|
|
|
it("preserves floating-point move, rotate, and scale authoring when snapping is disabled", () => {
|
|
const store = createEditorStore();
|
|
|
|
store.executeCommand(
|
|
createCreateBoxBrushCommand({
|
|
center: {
|
|
x: 1.25,
|
|
y: 1.5,
|
|
z: -0.75
|
|
},
|
|
size: {
|
|
x: 2.5,
|
|
y: 3.25,
|
|
z: 4.75
|
|
},
|
|
snapToGrid: false
|
|
})
|
|
);
|
|
|
|
const createdBrush = Object.values(store.getState().document.brushes)[0];
|
|
|
|
store.executeCommand(
|
|
createMoveBoxBrushCommand({
|
|
brushId: createdBrush.id,
|
|
center: {
|
|
x: 2.125,
|
|
y: 3.375,
|
|
z: -1.625
|
|
},
|
|
snapToGrid: false
|
|
})
|
|
);
|
|
store.executeCommand(
|
|
createRotateBoxBrushCommand({
|
|
brushId: createdBrush.id,
|
|
rotationDegrees: {
|
|
x: 12.5,
|
|
y: 37.5,
|
|
z: -8.25
|
|
}
|
|
})
|
|
);
|
|
store.executeCommand(
|
|
createResizeBoxBrushCommand({
|
|
brushId: createdBrush.id,
|
|
size: {
|
|
x: 3.5,
|
|
y: 1.75,
|
|
z: 5.125
|
|
},
|
|
snapToGrid: false
|
|
})
|
|
);
|
|
|
|
expect(store.getState().document.brushes[createdBrush.id]).toMatchObject({
|
|
center: {
|
|
x: 2.125,
|
|
y: 3.375,
|
|
z: -1.625
|
|
},
|
|
rotationDegrees: {
|
|
x: 12.5,
|
|
y: 37.5,
|
|
z: -8.25
|
|
},
|
|
size: {
|
|
x: 3.5,
|
|
y: 1.75,
|
|
z: 5.125
|
|
}
|
|
});
|
|
|
|
expect(store.undo()).toBe(true);
|
|
expect(store.getState().document.brushes[createdBrush.id].size).toEqual({
|
|
x: 2.5,
|
|
y: 3.25,
|
|
z: 4.75
|
|
});
|
|
|
|
expect(store.undo()).toBe(true);
|
|
expect(store.getState().document.brushes[createdBrush.id].rotationDegrees).toEqual({
|
|
x: 0,
|
|
y: 0,
|
|
z: 0
|
|
});
|
|
|
|
expect(store.undo()).toBe(true);
|
|
expect(store.getState().document.brushes[createdBrush.id].center).toEqual({
|
|
x: 1.25,
|
|
y: 1.5,
|
|
z: -0.75
|
|
});
|
|
|
|
expect(store.redo()).toBe(true);
|
|
expect(store.redo()).toBe(true);
|
|
expect(store.redo()).toBe(true);
|
|
expect(store.getState().document.brushes[createdBrush.id]).toMatchObject({
|
|
center: {
|
|
x: 2.125,
|
|
y: 3.375,
|
|
z: -1.625
|
|
},
|
|
rotationDegrees: {
|
|
x: 12.5,
|
|
y: 37.5,
|
|
z: -8.25
|
|
},
|
|
size: {
|
|
x: 3.5,
|
|
y: 1.75,
|
|
z: 5.125
|
|
}
|
|
});
|
|
});
|
|
|
|
it("renames a box brush through an undoable command", () => {
|
|
const store = createEditorStore();
|
|
|
|
store.executeCommand(createCreateBoxBrushCommand());
|
|
|
|
const createdBrush = Object.values(store.getState().document.brushes)[0];
|
|
|
|
store.executeCommand(
|
|
createSetBoxBrushNameCommand({
|
|
brushId: createdBrush.id,
|
|
name: "Entry Room"
|
|
})
|
|
);
|
|
|
|
expect(store.getState().document.brushes[createdBrush.id].name).toBe("Entry Room");
|
|
|
|
expect(store.undo()).toBe(true);
|
|
expect(store.getState().document.brushes[createdBrush.id].name).toBeUndefined();
|
|
|
|
expect(store.redo()).toBe(true);
|
|
expect(store.getState().document.brushes[createdBrush.id].name).toBe("Entry Room");
|
|
});
|
|
|
|
it("updates box volume settings through an undoable command", () => {
|
|
const store = createEditorStore();
|
|
|
|
store.executeCommand(createCreateBoxBrushCommand());
|
|
|
|
const createdBrush = Object.values(store.getState().document.brushes)[0];
|
|
|
|
store.executeCommand(
|
|
createSetBoxBrushVolumeSettingsCommand({
|
|
brushId: createdBrush.id,
|
|
volume: {
|
|
mode: "light",
|
|
light: {
|
|
colorHex: "#ffd9a6",
|
|
intensity: 1.75,
|
|
padding: 0.45,
|
|
falloff: "smoothstep"
|
|
}
|
|
}
|
|
})
|
|
);
|
|
|
|
expect(store.getState().document.brushes[createdBrush.id].volume).toEqual({
|
|
mode: "light",
|
|
light: {
|
|
colorHex: "#ffd9a6",
|
|
intensity: 1.75,
|
|
padding: 0.45,
|
|
falloff: "smoothstep"
|
|
}
|
|
});
|
|
|
|
expect(store.undo()).toBe(true);
|
|
expect(store.getState().document.brushes[createdBrush.id].volume).toEqual({
|
|
mode: "none"
|
|
});
|
|
|
|
expect(store.redo()).toBe(true);
|
|
expect(store.getState().document.brushes[createdBrush.id].volume).toEqual({
|
|
mode: "light",
|
|
light: {
|
|
colorHex: "#ffd9a6",
|
|
intensity: 1.75,
|
|
padding: 0.45,
|
|
falloff: "smoothstep"
|
|
}
|
|
});
|
|
});
|
|
});
|