test: verify playground native boundaries and preserve final evidence gates
This commit is contained in:
@@ -35,7 +35,95 @@ namespace MagnetismHeroes.Tests
|
||||
public Quaternion cameraRotation;
|
||||
}
|
||||
private GameApp _app;
|
||||
[Serializable] private sealed class NativeFixtures
|
||||
{
|
||||
public string sourceCommit, sourceDirty, utc, origin;
|
||||
public NativeStage[] stages;
|
||||
public NativeRestore[] restores;
|
||||
public NativeDrag[] drags;
|
||||
}
|
||||
[Serializable] private sealed class NativeStage
|
||||
{
|
||||
public int stage;
|
||||
public string theme;
|
||||
public Vector3 min, max;
|
||||
public PuzzleState initial;
|
||||
}
|
||||
[Serializable] private sealed class NativeRestore
|
||||
{
|
||||
public string name, slot, origin;
|
||||
public int stage;
|
||||
public PuzzleState puzzleSource, puzzleExpected;
|
||||
public FreePlayState freeSource, freeExpected;
|
||||
public float editorEntryMilliseconds;
|
||||
}
|
||||
[Serializable] private sealed class NativeDrag
|
||||
{
|
||||
public string name, ballId, kind = "boundary";
|
||||
public FreePlayState source, expected;
|
||||
public Vector3 requested;
|
||||
public Vector2 start, end;
|
||||
}
|
||||
private Store _store;
|
||||
[Serializable] private sealed class MatchedBenchmark
|
||||
{
|
||||
public string sourceCommit, sourceDirty, utc, method, loadOrder;
|
||||
public int stage, balls, groups, activeProps, width = 2400, height = 1080, warmups = 8, sampleCount = 30;
|
||||
public Vector3 cameraPosition;
|
||||
public Quaternion cameraRotation;
|
||||
public float fieldOfView;
|
||||
public double[] renderCpuMilliseconds;
|
||||
public long allocatedMemory, textureMemory;
|
||||
}
|
||||
[Serializable] private sealed class BenchmarkSceneryScan { public int stage, activeProps, renderers, residentTriangles; }
|
||||
[Serializable] private sealed class BenchmarkSceneryReport { public string sourceCommit, utc; public BenchmarkSceneryScan[] stages; public int[] maximumPropStages; }
|
||||
|
||||
[UnityTest] public IEnumerator MatchedPlaygroundResourceBenchmark()
|
||||
{
|
||||
string directory = Environment.GetEnvironmentVariable("MAGNETISM_BENCHMARK_EVIDENCE") ?? Path.GetFullPath("artifacts/verification/PlaygroundInteraction/EditorBenchmark");
|
||||
Directory.CreateDirectory(directory);
|
||||
var scans = new System.Collections.Generic.List<BenchmarkSceneryScan>();
|
||||
foreach (int stage in Enumerable.Range(1, 30))
|
||||
{
|
||||
_app.StartStage(stage); _app.Voice.Clear(); yield return null; yield return null;
|
||||
var filters = _app.Environment.GetComponentsInChildren<MeshFilter>();
|
||||
scans.Add(new BenchmarkSceneryScan { stage = stage,
|
||||
activeProps = _app.Environment.transform.Cast<Transform>().Count(child => child.gameObject.activeInHierarchy && child.name != "PlacementSafetySphere"),
|
||||
renderers = _app.Environment.GetComponentsInChildren<Renderer>().Count(value => value.enabled),
|
||||
residentTriangles = filters.Sum(value => Enumerable.Range(0, value.sharedMesh.subMeshCount).Sum(index => (int)value.sharedMesh.GetIndexCount(index)) / 3) });
|
||||
}
|
||||
var maximumPropStages = scans.Where(value => value.activeProps == scans.Max(item => item.activeProps)).Select(value => value.stage).ToArray();
|
||||
File.WriteAllText(Path.Combine(directory, "actual-thirty-scenery-scan.json"), JsonUtility.ToJson(new BenchmarkSceneryReport { sourceCommit = Environment.GetEnvironmentVariable("MAGNETISM_PROOF_COMMIT"), utc = DateTime.UtcNow.ToString("O"), stages = scans.ToArray(), maximumPropStages = maximumPropStages }, true));
|
||||
Assert.That(maximumPropStages.Intersect(new[] { 1, 16, 21 }), Is.Not.Empty, "Fixed matched stages must include an actually observed maximum-prop scene.");
|
||||
var camera = _app.Presenter.Camera; var canvas = _app.GetComponentInChildren<Canvas>();
|
||||
var target = RenderTexture.GetTemporary(2400, 1080, 24);
|
||||
var previousTarget = camera.targetTexture; var previousMode = canvas.renderMode; var previousCamera = canvas.worldCamera; float previousPlane = canvas.planeDistance, previousAspect = camera.aspect;
|
||||
try
|
||||
{
|
||||
camera.targetTexture = target; camera.aspect = 2400f / 1080; canvas.renderMode = RenderMode.ScreenSpaceCamera; canvas.worldCamera = camera; canvas.planeDistance = .5f;
|
||||
foreach (int stage in new[] { 1, 16, 21 }) foreach (bool singles in new[] { true, false })
|
||||
{
|
||||
_app.StartStage(stage); _app.Voice.Clear(); yield return null; yield return null;
|
||||
var balls = Enumerable.Range(0, 10).Select(index => new BallState { id = "benchmark-" + index, position = new Position3((index % 5 - 2) * 1.6f, .8f + index / 5 * 1.8f, 0) }).ToArray();
|
||||
var groups = singles ? balls.Select(ball => new GroupState { id = ball.id, ballIds = new[] { ball.id } }).ToArray() : new[] { new GroupState { id = "benchmark-ten", ballIds = balls.Select(ball => ball.id).ToArray() } };
|
||||
_app.Presenter.Render(BoardRules.CreateFreePlay(new FreePlayState { sourceStageId = stage, balls = balls, groups = groups }));
|
||||
var rotation = Quaternion.Euler(25, 30, 0); _app.Orbit.Apply(new CameraState { target = new Position3(0, .6f, 0), distance = 12, rotation = new Rotation4(rotation.x, rotation.y, rotation.z, rotation.w) });
|
||||
yield return null; yield return null; Canvas.ForceUpdateCanvases();
|
||||
for (int index = 0; index < 8; index++) { camera.Render(); yield return null; }
|
||||
var samples = new double[30];
|
||||
for (int index = 0; index < samples.Length; index++) { var watch = System.Diagnostics.Stopwatch.StartNew(); camera.Render(); watch.Stop(); samples[index] = watch.Elapsed.TotalMilliseconds; yield return null; }
|
||||
Assert.That(samples.All(value => value > 0), Is.True); Assert.That(_app.Presenter.Balls.Count, Is.EqualTo(10));
|
||||
File.WriteAllText(Path.Combine(directory, "stage" + stage + (singles ? "-ten-singles" : "-ten-group") + ".json"), JsonUtility.ToJson(new MatchedBenchmark {
|
||||
sourceCommit = Environment.GetEnvironmentVariable("MAGNETISM_PROOF_COMMIT"), sourceDirty = Environment.GetEnvironmentVariable("MAGNETISM_PROOF_DIRTY"), utc = DateTime.UtcNow.ToString("O"),
|
||||
method = "Standalone matched PlayMode filter; actual Main scene. 8 warmups and 30 Camera.Render CPU wall samples separated by frames; allocated/texture memory includes Editor. These values are not Android frame timing, GPU time or real-device performance.",
|
||||
loadOrder = "Main, scan original stages1..30, stage1 singles/group, stage16 singles/group, stage21 singles/group; actual-thirty-scenery-scan.json proves maximum-prop coverage",
|
||||
stage = stage, balls = balls.Length, groups = groups.Length, activeProps = _app.Environment.transform.Cast<Transform>().Count(child => child.gameObject.activeInHierarchy && child.name != "PlacementSafetySphere"),
|
||||
cameraPosition = camera.transform.position, cameraRotation = camera.transform.rotation, fieldOfView = camera.fieldOfView, renderCpuMilliseconds = samples,
|
||||
allocatedMemory = Profiler.GetTotalAllocatedMemoryLong(), textureMemory = Resources.FindObjectsOfTypeAll<Texture>().Sum(item => Profiler.GetRuntimeMemorySizeLong(item)) }, true));
|
||||
}
|
||||
}
|
||||
finally { camera.targetTexture = previousTarget; camera.aspect = previousAspect; canvas.renderMode = previousMode; canvas.worldCamera = previousCamera; canvas.planeDistance = previousPlane; RenderTexture.ReleaseTemporary(target); }
|
||||
}
|
||||
private string _evidence;
|
||||
[UnitySetUp] public IEnumerator SetUp()
|
||||
{
|
||||
@@ -51,6 +139,165 @@ namespace MagnetismHeroes.Tests
|
||||
}
|
||||
[UnityTearDown] public IEnumerator TearDown() { Object.Destroy(_app.gameObject); yield return null; }
|
||||
|
||||
[UnityTest] public IEnumerator ExportActualMainPlaygroundNativeBoundaryFixtures()
|
||||
{
|
||||
var stages = new System.Collections.Generic.List<NativeStage>();
|
||||
var restores = new System.Collections.Generic.List<NativeRestore>();
|
||||
var drags = new System.Collections.Generic.List<NativeDrag>();
|
||||
foreach (int stage in Enumerable.Range(1, 30))
|
||||
{
|
||||
_app.StartStage(stage); _app.Voice.Clear(); yield return null;
|
||||
stages.Add(new NativeStage { stage = stage, theme = _app.Environment.Theme,
|
||||
min = _app.Environment.PlaygroundBounds.min, max = _app.Environment.PlaygroundBounds.max,
|
||||
initial = new BoardRules(_app.Session.Definitions.Single(value => value.Id == stage)).ToPuzzleState(GameSession.DefaultCamera()) });
|
||||
if (new[] {1, 2, 6, 7, 11, 12, 16, 17, 21, 22, 26, 27}.Contains(stage))
|
||||
CaptureViews("playground-stage" + stage, "Actual Main initial board; labelled unlocked-stage fixture, not normal progression");
|
||||
}
|
||||
foreach (var entry in new[] { (name: "safe-free", stage: 1, point: new Vector3(0, 4, 0)),
|
||||
(name: "boundary-free", stage: 1, point: new Vector3(30, 4, 0)),
|
||||
(name: "tree-interior", stage: 6, point: Vector3.zero), (name: "rock-interior", stage: 21, point: Vector3.zero) })
|
||||
{
|
||||
_app.StartStage(entry.stage); yield return null; Physics.SyncTransforms();
|
||||
Vector3 point = entry.point;
|
||||
if (entry.point == Vector3.zero)
|
||||
{
|
||||
string asset = entry.name.StartsWith("tree") ? "RoundCanopyTree" : "SlateBoulder";
|
||||
var meshes = _app.Environment.GetComponentsInChildren<MeshCollider>().Where(value => value.enabled && value.transform.GetComponentsInParent<Transform>().Any(parent => parent.name.Contains(asset))).ToArray();
|
||||
Assert.That(meshes, Is.Not.Empty, "Native interior fixture must use an actual scenery collider.");
|
||||
var collider = meshes.OrderByDescending(value => value.bounds.size.sqrMagnitude).First();
|
||||
Assert.That(collider.sharedMesh.isReadable, Is.False);
|
||||
point = collider.bounds.center;
|
||||
Assert.That(_app.Presenter.IsSafePosition(BoardPresenter.ToPosition(point)), Is.False, "Actual approved mesh interior starts unsafe.");
|
||||
}
|
||||
var source = new FreePlayState { sourceStageId = entry.stage, camera = GameSession.DefaultCamera(),
|
||||
balls = new[] { new BallState { id = "native-" + entry.name, position = BoardPresenter.ToPosition(point) } },
|
||||
groups = new[] { new GroupState { id = "native-group", ballIds = new[] { "native-" + entry.name } } } };
|
||||
_store.Saved.latestFreePlay = source; _app.Initialize(_store);
|
||||
var watch = System.Diagnostics.Stopwatch.StartNew(); _app.ContinueFreePlay(); watch.Stop(); yield return null;
|
||||
Assert.That(_app.Session.Screen, Is.EqualTo(SessionScreen.FreePlay)); Assert.That(_app.Presenter.IsSafeBoard(_app.Session.Board), Is.True);
|
||||
restores.Add(new NativeRestore { name = entry.name, stage = entry.stage, slot = "free", freeSource = source,
|
||||
freeExpected = _app.Session.Board.ToFreePlayState(_app.Orbit.Snapshot()), editorEntryMilliseconds = (float)watch.Elapsed.TotalMilliseconds,
|
||||
origin = "Actual unchanged Main scenery; injected position only; original imports remain unreadable; expected result observed through GameApp entry" });
|
||||
}
|
||||
var legacy = new FreePlayState { sourceStageId = 9,
|
||||
camera = new CameraState { target = new Position3(0, .6f, 0), distance = 11, rotation = new Rotation4(-.022557568f, .96225017f, .08418597f, .2578342f) },
|
||||
balls = new[] { new BallState { id = "s09-b01", position = new Position3(-1.0351909f, .8f, .60371524f) },
|
||||
new BallState { id = "s09-b02", position = new Position3(-.03519098f, .8f, .60371524f) },
|
||||
new BallState { id = "s09-b03", position = new Position3(-3.9800465f, .8f, 1.649168f) },
|
||||
new BallState { id = "s09-b04", position = new Position3(.964809f, .8f, .60371524f) },
|
||||
new BallState { id = "s09-b05", position = new Position3(-2.9800465f, .8f, 1.649168f) } },
|
||||
groups = new[] { new GroupState { id = "s09-g01", ballIds = new[] { "s09-b01", "s09-b02", "s09-b04" } }, new GroupState { id = "s09-g01-split", ballIds = new[] { "s09-b03", "s09-b05" } } } };
|
||||
var wide = new FreePlayState { sourceStageId = 6, camera = GameSession.DefaultCamera(),
|
||||
balls = new[] { new BallState { id = "wide-a", position = new Position3(-30, 4, 0) }, new BallState { id = "wide-b", position = new Position3(30, 4, 0) } },
|
||||
groups = new[] { new GroupState { id = "wide-group", ballIds = new[] { "wide-a", "wide-b" } } } };
|
||||
var multi = JsonUtility.FromJson<FreePlayState>(JsonUtility.ToJson(wide));
|
||||
multi.sourceStageId = 1; multi.groups = new[] { new GroupState { id = "left", ballIds = new[] { "wide-a" } }, new GroupState { id = "right", ballIds = new[] { "wide-b" } } };
|
||||
foreach (var entry in new[] { (name: "legacy-nine", source: legacy), (name: "impossible-free", source: wide), (name: "multiple-repairs", source: multi) })
|
||||
{
|
||||
_store.Saved.latestFreePlay = entry.source; _app.Initialize(_store);
|
||||
var watch = System.Diagnostics.Stopwatch.StartNew(); _app.ContinueFreePlay(); watch.Stop(); yield return null;
|
||||
Assert.That(_app.Session.Screen, Is.EqualTo(SessionScreen.FreePlay)); Assert.That(_app.Presenter.IsSafeBoard(_app.Session.Board), Is.True);
|
||||
restores.Add(new NativeRestore { name = entry.name, stage = entry.source.sourceStageId, slot = "free", freeSource = entry.source,
|
||||
freeExpected = _app.Session.Board.ToFreePlayState(_app.Orbit.Snapshot()), editorEntryMilliseconds = (float)watch.Elapsed.TotalMilliseconds,
|
||||
origin = entry.name == "legacy-nine" ? "Exact original Content stage9 3+2 record and underground camera; original failure retained in T4 integration-fix" : "Separate injected boundary record; impossible variant exceeds rigid domain, multiple variant has two independent repairable friends" });
|
||||
}
|
||||
var puzzle = new PuzzleState { stageId = 2, camera = GameSession.DefaultCamera(),
|
||||
balls = new[] { new BallState { id = "native-count-a", position = new Position3(30, 4, 0) }, new BallState { id = "native-count-b", position = new Position3(31, 4, 0) } },
|
||||
groups = new[] { new GroupState { id = "native-count-group", ballIds = new[] { "native-count-a", "native-count-b" } } },
|
||||
collectedBallIds = new[] { "native-count-a" }, countedBallIds = new[] { "native-count-a" } };
|
||||
foreach (bool impossible in new[] { false, true })
|
||||
{
|
||||
if (impossible) { puzzle = JsonUtility.FromJson<PuzzleState>(JsonUtility.ToJson(puzzle)); puzzle.balls[0].position.x = -30; puzzle.balls[1].position.x = 30; }
|
||||
_store.Saved.puzzleStates = new[] { puzzle }; _app.Initialize(_store); _app.StartStage(2); yield return null;
|
||||
Assert.That(_app.Session.Screen, Is.EqualTo(SessionScreen.Puzzle)); Assert.That(_app.Presenter.IsSafeBoard(_app.Session.Board), Is.True);
|
||||
restores.Add(new NativeRestore { name = impossible ? "impossible-puzzle" : "counting-position-only", stage = 2, slot = "puzzle", puzzleSource = puzzle,
|
||||
puzzleExpected = _app.Session.Board.ToPuzzleState(_app.Orbit.Snapshot()), origin = "Separate injected two-ball Counting record; preserved partial collect/count; impossible variant changes x span to 60" });
|
||||
}
|
||||
_store.Saved.puzzleStates = Array.Empty<PuzzleState>();
|
||||
foreach (int count in new[] { 1, 10 }) foreach (int axis in Enumerable.Range(0, 3)) foreach (int sign in new[] { -1, 1 })
|
||||
{
|
||||
_app.StartStage(1); yield return null;
|
||||
var bounds = _app.Environment.PlaygroundBounds;
|
||||
var points = Enumerable.Range(0, count).Select(index => new Vector3((index % 5 - (count == 1 ? 0 : 2)), 4, index / 5)).ToArray();
|
||||
var lower = points.Aggregate(Vector3.Min); var upper = points.Aggregate(Vector3.Max);
|
||||
float offset = sign < 0 ? bounds.min[axis] + .5f + 1.2f - lower[axis] : bounds.max[axis] - .5f - 1.2f - upper[axis];
|
||||
var translation = Vector3.zero; translation[axis] = offset;
|
||||
points = points.Select(point => point + translation).ToArray();
|
||||
Assert.That(points.All(point => _app.Presenter.IsSafePosition(BoardPresenter.ToPosition(point))), Is.True);
|
||||
string id = "native-drag-0"; var rotation = Quaternion.Euler(0, axis == 2 ? 90 : 0, 0);
|
||||
var focus = points[0] - Vector3.up * .65f;
|
||||
var camera = new CameraState { target = BoardPresenter.ToPosition(focus), distance = 14, rotation = new Rotation4(rotation.x, rotation.y, rotation.z, rotation.w) };
|
||||
var source = new FreePlayState { sourceStageId = 1, camera = camera,
|
||||
balls = points.Select((point, index) => new BallState { id = "native-drag-" + index, position = BoardPresenter.ToPosition(point) }).ToArray(),
|
||||
groups = new[] { new GroupState { id = "native-drag-group", ballIds = Enumerable.Range(0, count).Select(index => "native-drag-" + index).ToArray() } } };
|
||||
_store.Saved.latestFreePlay = source; _app.Initialize(_store); _app.ContinueFreePlay(); yield return null;
|
||||
_app.Orbit.Camera.aspect = 2400f / 1080;
|
||||
var requested = Vector3.zero; requested[axis] = sign * 3;
|
||||
var start = _app.Orbit.Camera.WorldToViewportPoint(points[0]); var end = _app.Orbit.Camera.WorldToViewportPoint(points[0] + requested);
|
||||
var actual = _app.Environment.ConstrainTranslation(points, requested, _app.Presenter.transform);
|
||||
Assert.That(actual.magnitude, Is.InRange(1.19f, 1.21f), "Actual boundary clipping must stop at the .5 sphere margin.");
|
||||
_app.CommitMove("native-drag-group", BoardPresenter.ToPosition(actual)); yield return null;
|
||||
drags.Add(new NativeDrag { name = "boundary-" + count + "-" + axis + "-" + sign, ballId = id, source = source,
|
||||
expected = _app.Session.Board.ToFreePlayState(_app.Orbit.Snapshot()), requested = requested,
|
||||
start = new Vector2(start.x * 2400, (1 - start.y) * 1080), end = new Vector2(end.x * 2400, (1 - end.y) * 1080) });
|
||||
}
|
||||
_app.StartStage(1); yield return null; Physics.SyncTransforms();
|
||||
var arch = _app.Environment.GetComponentsInChildren<MeshCollider>().First(value => value.enabled && value.GetComponentsInParent<Transform>().Any(parent => parent.name.Contains("OpenStoneArch")));
|
||||
var foliage = _app.Environment.transform.Cast<Transform>().Where(value => value.gameObject.activeInHierarchy && value.name.Contains("GrassTuftMint") && value.GetComponentsInChildren<Collider>().Length == 0).ToArray();
|
||||
Assert.That(foliage, Is.Not.Empty);
|
||||
foreach (string kind in new[] { "thin-obstacle", "foliage-pass", "two-plus-three" })
|
||||
{
|
||||
var sourcePoint = new Vector3(-3, 3, 0); var requested = Vector3.right * 4;
|
||||
if (kind == "thin-obstacle") { sourcePoint = new Vector3(arch.bounds.min.x - 1.5f, 1.5f, arch.bounds.center.z); requested = Vector3.right * (arch.bounds.size.x + 3); }
|
||||
if (kind == "foliage-pass")
|
||||
{
|
||||
bool found = false;
|
||||
foreach (var plant in foliage)
|
||||
{
|
||||
var center = plant.GetComponentInChildren<Renderer>().bounds.center; sourcePoint = new Vector3(center.x - 2, .8f, center.z);
|
||||
if (!_app.Presenter.IsSafePosition(BoardPresenter.ToPosition(sourcePoint))) continue;
|
||||
if (Vector3.Distance(_app.Environment.ConstrainTranslation(new[] { sourcePoint }, requested, _app.Presenter.transform), requested) > .001f) continue;
|
||||
found = true; break;
|
||||
}
|
||||
Assert.That(found, Is.True, "Actual small foliage path must cross visible plant and remain unobstructed.");
|
||||
}
|
||||
var balls = new System.Collections.Generic.List<BallState> { new BallState { id = "native-contact-a", position = BoardPresenter.ToPosition(sourcePoint) } };
|
||||
var groups = new System.Collections.Generic.List<GroupState> { new GroupState { id = "native-contact-source", ballIds = new[] { "native-contact-a" } } };
|
||||
if (kind == "thin-obstacle")
|
||||
{
|
||||
balls.Add(new BallState { id = "native-contact-b", position = BoardPresenter.ToPosition(sourcePoint + requested) });
|
||||
groups.Add(new GroupState { id = "native-contact-target", ballIds = new[] { "native-contact-b" } });
|
||||
}
|
||||
if (kind == "two-plus-three")
|
||||
{
|
||||
balls = Enumerable.Range(0, 5).Select(index => new BallState { id = "native-contact-" + index, position = new Position3(index - 3, 3, 0) }).ToList();
|
||||
groups = new System.Collections.Generic.List<GroupState> { new GroupState { id = "native-contact-source", ballIds = balls.Take(2).Select(ball => ball.id).ToArray() }, new GroupState { id = "native-contact-target", ballIds = balls.Skip(2).Select(ball => ball.id).ToArray() } };
|
||||
// Source/target begin separated rather than already touching.
|
||||
foreach (var ball in balls.Skip(2)) ball.position.x += 1;
|
||||
}
|
||||
var camera = new CameraState { target = BoardPresenter.ToPosition(sourcePoint - Vector3.up * .65f), distance = 14 };
|
||||
var source = new FreePlayState { sourceStageId = 1, camera = camera, balls = balls.ToArray(), groups = groups.ToArray() };
|
||||
_store.Saved.latestFreePlay = source; _app.Initialize(_store); _app.ContinueFreePlay(); yield return null;
|
||||
Assert.That(_app.Presenter.IsSafeBoard(_app.Session.Board), Is.True); _app.Orbit.Camera.aspect = 2400f / 1080;
|
||||
var start = _app.Orbit.Camera.WorldToViewportPoint(sourcePoint); var end = _app.Orbit.Camera.WorldToViewportPoint(sourcePoint + requested);
|
||||
_app.Presenter.PreviewGroup("native-contact-source", requested);
|
||||
var actual = _app.Presenter.DropDelta; var merge = _app.Presenter.MergeCandidate;
|
||||
if (kind == "foliage-pass") Assert.That(Vector3.Distance(actual, requested), Is.LessThan(.001f));
|
||||
if (kind == "thin-obstacle") { Assert.That(actual.x, Is.GreaterThan(.1f).And.LessThan(requested.x - 1)); Assert.That(merge, Is.Null); }
|
||||
if (kind == "two-plus-three") Assert.That(merge, Is.EqualTo("native-contact-target"));
|
||||
_app.CommitMove("native-contact-source", BoardPresenter.ToPosition(actual), merge); yield return null;
|
||||
drags.Add(new NativeDrag { name = kind, kind = kind, ballId = source.balls[0].id, source = source, expected = _app.Session.Board.ToFreePlayState(_app.Orbit.Snapshot()), requested = requested,
|
||||
start = new Vector2(start.x * 2400, (1 - start.y) * 1080), end = new Vector2(end.x * 2400, (1 - end.y) * 1080) });
|
||||
}
|
||||
var directory = Environment.GetEnvironmentVariable("MAGNETISM_NATIVE_FIXTURES") ?? Path.GetFullPath("artifacts/verification/PlaygroundInteraction/NativeFixtures");
|
||||
Directory.CreateDirectory(directory);
|
||||
File.WriteAllText(Path.Combine(directory, "native-fixtures.json"), JsonUtility.ToJson(new NativeFixtures {
|
||||
sourceCommit = Environment.GetEnvironmentVariable("MAGNETISM_PROOF_COMMIT"), sourceDirty = Environment.GetEnvironmentVariable("MAGNETISM_PROOF_DIRTY"),
|
||||
utc = DateTime.UtcNow.ToString("O"), origin = "Actual Main scene, unchanged geometry, separately labelled boundary fixtures. Editor oracle is not Android pass.",
|
||||
stages = stages.ToArray(), restores = restores.ToArray(), drags = drags.ToArray() }, true));
|
||||
Assert.That(stages.Count, Is.EqualTo(30)); Assert.That(restores.Count, Is.EqualTo(9)); Assert.That(drags.Count, Is.EqualTo(15));
|
||||
}
|
||||
|
||||
private void AssertEquipmentFollowsRepresentatives(BoardRules board)
|
||||
{
|
||||
_app.Presenter.SendMessage("LateUpdate");
|
||||
|
||||
Reference in New Issue
Block a user