Завершить инженерный кандидат Stage 5

This commit is contained in:
2026-08-19 02:04:45 +03:00
parent b840684ef3
commit cde886ca96
45 changed files with 3236 additions and 98 deletions
@@ -0,0 +1,81 @@
package com.projectsacrifice.game;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import org.junit.Test;
public final class VersionedSessionCodecTest {
@Test
public void currentSnapshotRoundTripsEveryPuzzleCriticalField() {
GameSessionSnapshot original = sampleSnapshot();
VersionedSessionCodec.DecodeResult decoded =
VersionedSessionCodec.decode(VersionedSessionCodec.encode(original));
assertEquals(VersionedSessionCodec.Status.RESTORED, decoded.status());
GameSessionSnapshot restored = decoded.snapshot();
assertEquals(5, restored.levelNumber());
assertEquals(12.75f, restored.elapsedSeconds(), 0f);
assertEquals(2, restored.deaths());
assertEquals(640f, restored.player().x(), 0f);
assertFalse(restored.player().alive());
assertEquals(2, restored.bodies().size());
assertTrue(restored.bodies().get(0).pinned());
assertTrue(restored.bodies().get(1).conductive());
assertEquals(Arrays.asList(1.25f, 3.5f), restored.platformMotionTimes());
assertTrue(restored.toggleSignals().get("gate"));
assertEquals(2.25f, restored.timedSignals().get("clock"), 0f);
assertTrue(restored.previousSwitchContacts().get("gate@420.0"));
}
@Test
public void legacyV1MigratesWithSafeEmptyEdgeContacts() {
VersionedSessionCodec.DecodeResult decoded = VersionedSessionCodec.decode(
VersionedSessionCodec.encodeLegacyV1(sampleSnapshot()));
assertEquals(VersionedSessionCodec.Status.MIGRATED, decoded.status());
assertEquals(VersionedSessionCodec.CURRENT_VERSION,
decoded.snapshot().saveVersion());
assertTrue(decoded.snapshot().previousSwitchContacts().isEmpty());
assertEquals(2, decoded.snapshot().bodies().size());
}
@Test
public void corruptAndFutureSnapshotsFailClosed() {
VersionedSessionCodec.DecodeResult corrupt =
VersionedSessionCodec.decode(new byte[] {1, 2, 3});
VersionedSessionCodec.DecodeResult future =
VersionedSessionCodec.decode(VersionedSessionCodec.encodeVersionForTest(99));
assertEquals(VersionedSessionCodec.Status.CORRUPT, corrupt.status());
assertNull(corrupt.snapshot());
assertEquals(VersionedSessionCodec.Status.UNSUPPORTED, future.status());
assertNull(future.snapshot());
}
private static GameSessionSnapshot sampleSnapshot() {
return GameSessionSnapshot.builder(5)
.elapsedSeconds(12.75f)
.deaths(2)
.respawnSeconds(0.4f)
.player(new GameSessionSnapshot.PlayerData(
640f, 780f, 120f, -40f, false, false,
0.1f, 0.08f, -1, -1))
.addBody(new GameSessionSnapshot.BodyData(
500f, 826f, 72f, 54f, 0f, 0f,
false, false, true, true, -1, "SPIKE"))
.addBody(new GameSessionSnapshot.BodyData(
720f, 826f, 72f, 54f, 0f, 0f,
false, true, true, true, -1, "ELECTRIC"))
.platformMotionTimes(Arrays.asList(1.25f, 3.5f))
.toggleSignal("gate", true)
.timedSignal("clock", 2.25f)
.previousSwitchContact("gate@420.0", true)
.build();
}
}