feat(tests): Add comprehensive test coverage for terrain resizing logic
This commit is contained in:
@@ -160,6 +160,31 @@ describe("terrain grid resizing", () => {
|
|||||||
expect(getTerrainHeightAtSample(resizedTerrain, 2, 2)).toBe(22);
|
expect(getTerrainHeightAtSample(resizedTerrain, 2, 2)).toBe(22);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("extends west and south when those cardinal resize directions are selected", () => {
|
||||||
|
const terrain = createTerrain({
|
||||||
|
id: "terrain-samples-extend-west-south",
|
||||||
|
position: { x: 10, y: 0, z: 20 },
|
||||||
|
sampleCountX: 3,
|
||||||
|
sampleCountZ: 3,
|
||||||
|
cellSize: 1,
|
||||||
|
heights: createIndexedHeights(3, 3)
|
||||||
|
});
|
||||||
|
|
||||||
|
const resizedTerrain = resizeTerrainGrid(terrain, {
|
||||||
|
sampleCountX: 5,
|
||||||
|
sampleCountZ: 5,
|
||||||
|
cellSize: terrain.cellSize,
|
||||||
|
resizeDirectionX: "west",
|
||||||
|
resizeDirectionZ: "south"
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(resizedTerrain.position).toEqual({ x: 8, y: 0, z: 18 });
|
||||||
|
expect(getTerrainHeightAtSample(resizedTerrain, 2, 2)).toBe(0);
|
||||||
|
expect(getTerrainHeightAtSample(resizedTerrain, 4, 4)).toBe(22);
|
||||||
|
expect(getTerrainHeightAtSample(resizedTerrain, 0, 2)).toBe(0);
|
||||||
|
expect(getTerrainHeightAtSample(resizedTerrain, 2, 0)).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
it("decreases Samples X/Z by cropping terrain instead of squashing existing data", () => {
|
it("decreases Samples X/Z by cropping terrain instead of squashing existing data", () => {
|
||||||
const terrain = createTerrain({
|
const terrain = createTerrain({
|
||||||
id: "terrain-samples-crop",
|
id: "terrain-samples-crop",
|
||||||
@@ -184,6 +209,33 @@ describe("terrain grid resizing", () => {
|
|||||||
expect(getTerrainHeightAtSample(resizedTerrain, 2, 2)).toBe(22);
|
expect(getTerrainHeightAtSample(resizedTerrain, 2, 2)).toBe(22);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("crops west and south when those cardinal resize directions are selected", () => {
|
||||||
|
const terrain = createTerrain({
|
||||||
|
id: "terrain-samples-crop-west-south",
|
||||||
|
sampleCountX: 5,
|
||||||
|
sampleCountZ: 5,
|
||||||
|
cellSize: 1,
|
||||||
|
heights: createIndexedHeights(5, 5)
|
||||||
|
});
|
||||||
|
|
||||||
|
const resizedTerrain = resizeTerrainGrid(terrain, {
|
||||||
|
sampleCountX: 3,
|
||||||
|
sampleCountZ: 3,
|
||||||
|
cellSize: terrain.cellSize,
|
||||||
|
resizeDirectionX: "west",
|
||||||
|
resizeDirectionZ: "south"
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(resizedTerrain.position).toEqual({
|
||||||
|
x: terrain.position.x + 2,
|
||||||
|
y: terrain.position.y,
|
||||||
|
z: terrain.position.z + 2
|
||||||
|
});
|
||||||
|
expect(getTerrainHeightAtSample(resizedTerrain, 0, 0)).toBe(22);
|
||||||
|
expect(getTerrainHeightAtSample(resizedTerrain, 1, 1)).toBe(33);
|
||||||
|
expect(getTerrainHeightAtSample(resizedTerrain, 2, 2)).toBe(44);
|
||||||
|
});
|
||||||
|
|
||||||
it("fills newly extended height samples from the nearest existing edge height", () => {
|
it("fills newly extended height samples from the nearest existing edge height", () => {
|
||||||
const terrain = createTerrain({
|
const terrain = createTerrain({
|
||||||
id: "terrain-samples-edge-fill",
|
id: "terrain-samples-edge-fill",
|
||||||
@@ -204,6 +256,37 @@ describe("terrain grid resizing", () => {
|
|||||||
expect(getTerrainHeightAtSample(resizedTerrain, 4, 4)).toBe(22);
|
expect(getTerrainHeightAtSample(resizedTerrain, 4, 4)).toBe(22);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("preserves paint weights at the same world positions with west and south resizing", () => {
|
||||||
|
const terrain = createTerrain({
|
||||||
|
id: "terrain-samples-paint-west-south",
|
||||||
|
position: { x: 10, y: 0, z: 20 },
|
||||||
|
sampleCountX: 3,
|
||||||
|
sampleCountZ: 3,
|
||||||
|
cellSize: 1,
|
||||||
|
paintWeights: createIndexedPaintWeights(3, 3)
|
||||||
|
});
|
||||||
|
|
||||||
|
const resizedTerrain = resizeTerrainGrid(terrain, {
|
||||||
|
sampleCountX: 5,
|
||||||
|
sampleCountZ: 5,
|
||||||
|
cellSize: terrain.cellSize,
|
||||||
|
resizeDirectionX: "west",
|
||||||
|
resizeDirectionZ: "south"
|
||||||
|
});
|
||||||
|
const originalOffset = getTerrainPaintWeightSampleOffset(terrain, 1, 1);
|
||||||
|
const resizedOffset = getTerrainPaintWeightSampleOffset(resizedTerrain, 3, 3);
|
||||||
|
|
||||||
|
expect(resizedTerrain.paintWeights[resizedOffset]).toBeCloseTo(
|
||||||
|
terrain.paintWeights[originalOffset] ?? 0
|
||||||
|
);
|
||||||
|
expect(resizedTerrain.paintWeights[resizedOffset + 1]).toBeCloseTo(
|
||||||
|
terrain.paintWeights[originalOffset + 1] ?? 0
|
||||||
|
);
|
||||||
|
expect(resizedTerrain.paintWeights[resizedOffset + 2]).toBeCloseTo(
|
||||||
|
terrain.paintWeights[originalOffset + 2] ?? 0
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it("keeps foliage masks and blocker masks valid after cell-size and sample-count edits", () => {
|
it("keeps foliage masks and blocker masks valid after cell-size and sample-count edits", () => {
|
||||||
const foliageLayerId = "foliage-layer-resize-valid";
|
const foliageLayerId = "foliage-layer-resize-valid";
|
||||||
const terrain = createTerrain({
|
const terrain = createTerrain({
|
||||||
@@ -234,7 +317,9 @@ describe("terrain grid resizing", () => {
|
|||||||
const extendedTerrain = resizeTerrainGrid(resolutionChangedTerrain, {
|
const extendedTerrain = resizeTerrainGrid(resolutionChangedTerrain, {
|
||||||
sampleCountX: 6,
|
sampleCountX: 6,
|
||||||
sampleCountZ: 4,
|
sampleCountZ: 4,
|
||||||
cellSize: resolutionChangedTerrain.cellSize
|
cellSize: resolutionChangedTerrain.cellSize,
|
||||||
|
resizeDirectionX: "west",
|
||||||
|
resizeDirectionZ: "south"
|
||||||
});
|
});
|
||||||
const resizedMask = getTerrainFoliageMask(extendedTerrain, foliageLayerId);
|
const resizedMask = getTerrainFoliageMask(extendedTerrain, foliageLayerId);
|
||||||
|
|
||||||
@@ -284,6 +369,35 @@ describe("terrain grid resizing", () => {
|
|||||||
expect(getTerrainFootprintDepth(resizedTerrain)).toBe(9);
|
expect(getTerrainFootprintDepth(resizedTerrain)).toBe(9);
|
||||||
expect(resizedTerrain.position).toEqual(terrain.position);
|
expect(resizedTerrain.position).toEqual(terrain.position);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("uses cardinal directions for non-divisible footprint and cell-size edits", () => {
|
||||||
|
const terrain = createTerrain({
|
||||||
|
id: "terrain-cell-size-non-divisible-west-south",
|
||||||
|
sampleCountX: 9,
|
||||||
|
sampleCountZ: 9,
|
||||||
|
cellSize: 1,
|
||||||
|
heights: createIndexedHeights(9, 9)
|
||||||
|
});
|
||||||
|
|
||||||
|
const resizedTerrain = resizeTerrainGrid(terrain, {
|
||||||
|
sampleCountX: terrain.sampleCountX,
|
||||||
|
sampleCountZ: terrain.sampleCountZ,
|
||||||
|
cellSize: 3,
|
||||||
|
resizeDirectionX: "west",
|
||||||
|
resizeDirectionZ: "south"
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(resizedTerrain.cellSize).toBe(3);
|
||||||
|
expect(resizedTerrain.sampleCountX).toBe(4);
|
||||||
|
expect(resizedTerrain.sampleCountZ).toBe(4);
|
||||||
|
expect(getTerrainFootprintWidth(resizedTerrain)).toBe(9);
|
||||||
|
expect(getTerrainFootprintDepth(resizedTerrain)).toBe(9);
|
||||||
|
expect(resizedTerrain.position).toEqual({
|
||||||
|
x: terrain.position.x - 1,
|
||||||
|
y: terrain.position.y,
|
||||||
|
z: terrain.position.z - 1
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("terrain material layers", () => {
|
describe("terrain material layers", () => {
|
||||||
|
|||||||
@@ -180,6 +180,29 @@ describe("Terrain foundation", () => {
|
|||||||
expect(updatedTerrain?.cellSize).toBe(2);
|
expect(updatedTerrain?.cellSize).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fireEvent.change(screen.getByTestId("terrain-grid-resize-direction-x"), {
|
||||||
|
target: { value: "west" }
|
||||||
|
});
|
||||||
|
fireEvent.change(screen.getByTestId("terrain-grid-resize-direction-z"), {
|
||||||
|
target: { value: "south" }
|
||||||
|
});
|
||||||
|
fireEvent.change(screen.getByTestId("terrain-grid-sample-count-x"), {
|
||||||
|
target: { value: "7" }
|
||||||
|
});
|
||||||
|
fireEvent.change(screen.getByTestId("terrain-grid-sample-count-z"), {
|
||||||
|
target: { value: "6" }
|
||||||
|
});
|
||||||
|
fireEvent.click(screen.getByTestId("terrain-grid-apply"));
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
const updatedTerrain = store.getState().document.terrains[createdTerrain.id];
|
||||||
|
|
||||||
|
expect(updatedTerrain?.sampleCountX).toBe(7);
|
||||||
|
expect(updatedTerrain?.sampleCountZ).toBe(6);
|
||||||
|
expect(updatedTerrain?.position.x).toBe(-8);
|
||||||
|
expect(updatedTerrain?.position.z).toBe(-6);
|
||||||
|
});
|
||||||
|
|
||||||
fireEvent.click(screen.getByTestId("terrain-collision-enabled"));
|
fireEvent.click(screen.getByTestId("terrain-collision-enabled"));
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user