diff --git a/docs/eve-migration-roadmap.md b/docs/eve-migration-roadmap.md index c65d38f..9c47641 100644 --- a/docs/eve-migration-roadmap.md +++ b/docs/eve-migration-roadmap.md @@ -550,16 +550,20 @@ Recently cut: `interactiveWorldSurfaces[]` records. The Aetheria consumer smoke asserts the advertised web, Unity UI Toolkit, and Unity scene lowering targets without importing Aetheria or Eve internals. -- EveUnity test lifecycle now carries a structured Unity EditMode runner - contract. `packages/org.gamecult.eve.unity-uitoolkit/eve-runtime-capability.json` - names the runner script, consumer Unity project, default Unity editor path, - package name, test assembly, platform, result artifacts, and temporary - `testables` manifest mutation. The lifecycle smoke validates the runner - script and Aetheria project, parity compares the contract against the ledger, - and the runtime-owner consumer smoke asserts exported test fields. This is - Unity package consumption proof for CultLib-produced assemblies; the test - contract names those CultLib-owned NuGet/precompiled assembly inputs - explicitly. CultLib remains the owner of the .NET/NuGet dependency story. +- EveUnity test lifecycle now carries structured Unity EditMode runner + contracts. `packages/org.gamecult.eve.unity-uitoolkit/eve-runtime-capability.json` + and `runtimes/incubating/eve-unity-scene/eve-runtime-capability.json` name + runner scripts, the Aetheria consumer Unity project, package names, test + assemblies, platform, result artifacts, and temporary `testables` manifest + mutation. The shared runner restores Aetheria's `Packages/manifest.json` + after each run, while `scripts/run-aetheria-unity-scene-editmode-tests.ps1` + selects `org.gamecult.eve.unity-scene` and + `GameCult.Eve.UnityScene.Tests`. Lifecycle smokes validate the runner scripts + and Aetheria project, parity compares the contracts against the ledger, and + runtime-owner consumer smoke asserts exported test fields. UI Toolkit still + carries the CultLib-managed precompiled assembly dependency proof; Unity + Scene now carries a generic playable-world EditMode proof through the real + Aetheria consumer project. - EveUnity release lifecycle now carries a structured UPM release contract. `packages/org.gamecult.eve.unity-uitoolkit/eve-runtime-capability.json` names the package root, version source, tag pattern, artifact kind, and @@ -973,6 +977,15 @@ Recently cut: resolves those assemblies after it leaves Eve incubation, not inventing a dependency system for CultLib. This proves the incubating test lifecycle; it does not make Eve own Unity's final runtime lifecycle. +- Aetheria now has the same repeatable Unity EditMode evidence for the + EveUnity scene runtime. `scripts/run-aetheria-unity-scene-editmode-tests.ps1` + temporarily adds `org.gamecult.eve.unity-scene` to Aetheria's Unity + `testables`, runs `GameCult.Eve.UnityScene.Tests`, writes XML and log + artifacts under `artifacts/aetheria-unity-scene-editmode`, and restores + `Packages/manifest.json`. This proves the generic playable-world host, + bootstrap, input, camera, scene sink, and command-envelope tests compile and + run through the Aetheria consumer project without making the Unity client + Aetheria-specific. - Aetheria now has repeatable Unity package consumer-build evidence for the Eve UI Toolkit runtime. `scripts/run-aetheria-unity-package-smoke.ps1` verifies Aetheria's Unity `Packages/manifest.json` consumes Eve's surface and diff --git a/docs/parity-testing-harness.md b/docs/parity-testing-harness.md index 592992b..340de80 100644 --- a/docs/parity-testing-harness.md +++ b/docs/parity-testing-harness.md @@ -425,6 +425,17 @@ The exported runtime lifecycle records that runner contract so EveUnity can inherit the Unity-specific test proof without making Eve responsible for CultLib package distribution. +Unity scene EditMode test smoke: + +```powershell +powershell -ExecutionPolicy Bypass -File .\scripts\run-aetheria-unity-scene-editmode-tests.ps1 +``` + +That wrapper uses the same manifest-restore runner, but selects +`org.gamecult.eve.unity-scene` and `GameCult.Eve.UnityScene.Tests`. It proves +the generic playable-world Unity client body through the Aetheria consumer +project while keeping Aetheria as provider authority. + Unity runtime lifecycle evidence: `packages/org.gamecult.eve.unity-uitoolkit/eve-runtime-capability.json` diff --git a/packages/org.gamecult.eve.unity-uitoolkit/Runtime/TeXMathUiToolkitProjectionAdapter.cs.meta b/packages/org.gamecult.eve.unity-uitoolkit/Runtime/TeXMathUiToolkitProjectionAdapter.cs.meta new file mode 100644 index 0000000..0bcd3dd --- /dev/null +++ b/packages/org.gamecult.eve.unity-uitoolkit/Runtime/TeXMathUiToolkitProjectionAdapter.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: d6c655fae0c77064490eba9c3ed1fb4c \ No newline at end of file diff --git a/packages/org.gamecult.eve.unity-uitoolkit/eveunity-split-handoff.json.meta b/packages/org.gamecult.eve.unity-uitoolkit/eveunity-split-handoff.json.meta new file mode 100644 index 0000000..442eefb --- /dev/null +++ b/packages/org.gamecult.eve.unity-uitoolkit/eveunity-split-handoff.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d50f4f5a379d8ab4ba6217c2af18ded0 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/runtimes/incubating/eve-unity-scene/Runtime.meta b/runtimes/incubating/eve-unity-scene/Runtime.meta new file mode 100644 index 0000000..f5f6f4b --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1ed3bb976c01b68498f8da912b8ddf2d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/runtimes/incubating/eve-unity-scene/Runtime/EveUnityGameObjectPlayableWorldSceneSink.cs.meta b/runtimes/incubating/eve-unity-scene/Runtime/EveUnityGameObjectPlayableWorldSceneSink.cs.meta new file mode 100644 index 0000000..493007b --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/Runtime/EveUnityGameObjectPlayableWorldSceneSink.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: e924fe3501e6e584392cb405f916c9c9 \ No newline at end of file diff --git a/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldAssetManifest.cs.meta b/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldAssetManifest.cs.meta new file mode 100644 index 0000000..43c845c --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldAssetManifest.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 0a1f1e9cabc1b044dbf58bc878a6d09a \ No newline at end of file diff --git a/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs b/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs index e46c410..a78caf9 100644 --- a/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs +++ b/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientBootstrap.cs @@ -131,6 +131,7 @@ namespace GameCult.Eve.UnityScene } var cameraObject = new GameObject("Eve Unity Playable World Camera"); + cameraObject.transform.SetParent(transform, false); cameraObject.AddComponent(); cameraTransform = cameraObject.transform; return cameraTransform; diff --git a/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientHost.cs b/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientHost.cs index c57f633..30da84a 100644 --- a/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientHost.cs +++ b/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldClientHost.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using GameCult.Eve.Surface; using UnityEngine; @@ -172,15 +173,16 @@ namespace GameCult.Eve.UnityScene private void RefreshProviderSources() { - RefreshProvider(providerSurfaceDocuments); - RefreshProvider(assetManifestDocuments); - RefreshProvider(receiptSource); - RefreshProvider(commandSink); + var refreshed = new HashSet(); + RefreshProvider(providerSurfaceDocuments, refreshed); + RefreshProvider(assetManifestDocuments, refreshed); + RefreshProvider(receiptSource, refreshed); + RefreshProvider(commandSink, refreshed); } - private static void RefreshProvider(MonoBehaviour? behaviour) + private static void RefreshProvider(MonoBehaviour? behaviour, ISet refreshed) { - if (behaviour is IEveUnityProviderRefreshSource refreshSource) + if (behaviour is IEveUnityProviderRefreshSource refreshSource && refreshed.Add(behaviour)) refreshSource.Refresh(); } diff --git a/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldLiveClient.cs.meta b/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldLiveClient.cs.meta new file mode 100644 index 0000000..ef9f199 --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldLiveClient.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 3b46f9972e945ca4daa29473de0bfb9b \ No newline at end of file diff --git a/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldPresenter.cs.meta b/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldPresenter.cs.meta new file mode 100644 index 0000000..97b6682 --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldPresenter.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 1df1c82e51d1ee04c96247cdff61101a \ No newline at end of file diff --git a/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldRuntime.cs.meta b/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldRuntime.cs.meta new file mode 100644 index 0000000..57fd452 --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/Runtime/EveUnityPlayableWorldRuntime.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 9323e6fa0b61837499fa84b30e597e92 \ No newline at end of file diff --git a/runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneClientSession.cs.meta b/runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneClientSession.cs.meta new file mode 100644 index 0000000..5919fc3 --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneClientSession.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: d2b8fac8eb072f8419afa594928840ef \ No newline at end of file diff --git a/runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneProviderConnection.cs.meta b/runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneProviderConnection.cs.meta new file mode 100644 index 0000000..d594d36 --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneProviderConnection.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 9e93e937d561d4941b5080a454091f7a \ No newline at end of file diff --git a/runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneSurfaceLowerer.cs.meta b/runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneSurfaceLowerer.cs.meta new file mode 100644 index 0000000..0b26f1f --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/Runtime/EveUnitySceneSurfaceLowerer.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 32422132e752b9a4f8a45b2a5cb01217 \ No newline at end of file diff --git a/runtimes/incubating/eve-unity-scene/Runtime/GameCult.Eve.UnityScene.asmdef.meta b/runtimes/incubating/eve-unity-scene/Runtime/GameCult.Eve.UnityScene.asmdef.meta new file mode 100644 index 0000000..dcd39b3 --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/Runtime/GameCult.Eve.UnityScene.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a5b5eeaa1ac2b24409cf4718616ebbe3 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/runtimes/incubating/eve-unity-scene/Runtime/NornGraphUnitySceneProjectionAdapter.cs.meta b/runtimes/incubating/eve-unity-scene/Runtime/NornGraphUnitySceneProjectionAdapter.cs.meta new file mode 100644 index 0000000..15f16c2 --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/Runtime/NornGraphUnitySceneProjectionAdapter.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: bbe1659cc5c50ff4e9ab6f2ef0ed82c3 \ No newline at end of file diff --git a/runtimes/incubating/eve-unity-scene/Runtime/SaiVisualNovelUnitySceneProjectionAdapter.cs.meta b/runtimes/incubating/eve-unity-scene/Runtime/SaiVisualNovelUnitySceneProjectionAdapter.cs.meta new file mode 100644 index 0000000..989da6e --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/Runtime/SaiVisualNovelUnitySceneProjectionAdapter.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: fc79e8d0b375f3d41ad7809e2129ca6c \ No newline at end of file diff --git a/runtimes/incubating/eve-unity-scene/Runtime/TeXMathUnitySceneProjectionAdapter.cs.meta b/runtimes/incubating/eve-unity-scene/Runtime/TeXMathUnitySceneProjectionAdapter.cs.meta new file mode 100644 index 0000000..dd5310c --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/Runtime/TeXMathUnitySceneProjectionAdapter.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 0184a5155baa9774f9ed133ad871b735 \ No newline at end of file diff --git a/runtimes/incubating/eve-unity-scene/Tests.meta b/runtimes/incubating/eve-unity-scene/Tests.meta new file mode 100644 index 0000000..cffd388 --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/Tests.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b37c64ab7abc96a468018e86c041d431 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/runtimes/incubating/eve-unity-scene/Tests/Editor.meta b/runtimes/incubating/eve-unity-scene/Tests/Editor.meta new file mode 100644 index 0000000..532aea7 --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/Tests/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ac7339c6ff81f6f48864df2308ebeed2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs b/runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs index 22aae62..28fe06e 100644 --- a/runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs +++ b/runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs @@ -423,7 +423,7 @@ namespace GameCult.Eve.UnityScene.Tests var bootstrap = hostObject.AddComponent(); bootstrap.ConfigureProvider(provider); - hostObject.SetActive(true); + bootstrap.Mount(); Assert.That(bootstrap.Host, Is.Not.Null); Assert.That(bootstrap.Host!.ActiveWorld, Is.Not.Null); diff --git a/runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs.meta b/runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs.meta new file mode 100644 index 0000000..ef6d6e2 --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: d2b3006d5699924498750dbf5f087435 \ No newline at end of file diff --git a/runtimes/incubating/eve-unity-scene/Tests/Editor/GameCult.Eve.UnityScene.Tests.asmdef.meta b/runtimes/incubating/eve-unity-scene/Tests/Editor/GameCult.Eve.UnityScene.Tests.asmdef.meta new file mode 100644 index 0000000..d045f6a --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/Tests/Editor/GameCult.Eve.UnityScene.Tests.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 10e7994adb919944aadc88f960300bc4 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/runtimes/incubating/eve-unity-scene/eve-runtime-capability.json b/runtimes/incubating/eve-unity-scene/eve-runtime-capability.json index 78e9bde..a976af9 100644 --- a/runtimes/incubating/eve-unity-scene/eve-runtime-capability.json +++ b/runtimes/incubating/eve-unity-scene/eve-runtime-capability.json @@ -162,18 +162,18 @@ }, "test": { "ownerRepo": "EveUnity", - "status": "provider-shell-contract-skeleton", + "status": "unity-scene-editmode-batchmode", "testContract": { "ownerRepo": "EveUnity", - "runnerKind": "unity-scene-provider-shell-smoke", - "runnerScript": "scripts/run-eveunity-scene-provider-shell-smoke.ps1", + "runnerKind": "unity-editmode-batchmode", + "runnerScript": "scripts/run-aetheria-unity-scene-editmode-tests.ps1", "consumerProject": "E:\\Projects\\Aetheria", "packageName": "org.gamecult.eve.unity-scene", "testAssembly": "GameCult.Eve.UnityScene.Tests", - "testPlatform": "EditMode contract skeleton", - "resultsArtifact": "artifacts/eveunity-scene-provider-shell/{stamp}/provider-shell-results.json", - "logArtifact": "artifacts/eveunity-scene-provider-shell/{stamp}/provider-shell.log", - "manifestMutation": "None; the scene lowerer consumes provider advertisements and must not mutate provider product manifests." + "testPlatform": "EditMode", + "resultsArtifact": "artifacts/aetheria-unity-scene-editmode/{stamp}/unity-editmode-results.xml", + "logArtifact": "artifacts/aetheria-unity-scene-editmode/{stamp}/unity-editmode.log", + "manifestMutation": "Temporarily adds org.gamecult.eve.unity-scene to Aetheria Unity testables, runs GameCult.Eve.UnityScene.Tests, and restores Packages/manifest.json." }, "evidencePaths": [ "runtimes/incubating/eve-unity-scene/package.json", @@ -198,10 +198,12 @@ "runtimes/incubating/eve-unity-scene/Tests/Editor/EveUnitySceneSurfaceLowererTests.cs", "runtimes/incubating/eve-unity-scene/eveunity-scene-split-handoff.json", "scripts/run-eveunity-scene-split-handoff-smoke.ps1", - "scripts/run-eveunity-scene-provider-shell-smoke.ps1" + "scripts/run-eveunity-scene-provider-shell-smoke.ps1", + "scripts/run-aetheria-unity-editmode-tests.ps1", + "scripts/run-aetheria-unity-scene-editmode-tests.ps1" ], "pendingProofs": [ - "Unity scene provider-advertisement smoke runs from EveUnity with real Unity scene/frame objects and no Aetheria imports.", + "Unity scene EditMode runner is owned by EveUnity rather than Eve incubation.", "Live CultMesh/CultNet provider subscription adapter implements IEveUnitySceneProviderSurfaceDocumentSource/IEveUnitySceneProviderSurfaceSource and feeds EveUnitySceneClientSession snapshots from provider-owned documents instead of Eve-local fixture documents." ] }, diff --git a/runtimes/incubating/eve-unity-scene/eve-runtime-capability.json.meta b/runtimes/incubating/eve-unity-scene/eve-runtime-capability.json.meta new file mode 100644 index 0000000..b672c6f --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/eve-runtime-capability.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 16a73a75d0939424bad58c752f0f8a3e +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/runtimes/incubating/eve-unity-scene/eveunity-scene-split-handoff.json.meta b/runtimes/incubating/eve-unity-scene/eveunity-scene-split-handoff.json.meta new file mode 100644 index 0000000..a253ee8 --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/eveunity-scene-split-handoff.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0a5262acca13bee44bb5cac30a93f8dd +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/runtimes/incubating/eve-unity-scene/package.json.meta b/runtimes/incubating/eve-unity-scene/package.json.meta new file mode 100644 index 0000000..f41eec4 --- /dev/null +++ b/runtimes/incubating/eve-unity-scene/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 8eaedcd0b70a6574c8ddb12c84b444a5 +PackageManifestImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/scripts/run-aetheria-unity-editmode-tests.ps1 b/scripts/run-aetheria-unity-editmode-tests.ps1 index 5fbd4f4..b0522fe 100644 --- a/scripts/run-aetheria-unity-editmode-tests.ps1 +++ b/scripts/run-aetheria-unity-editmode-tests.ps1 @@ -1,7 +1,9 @@ param( [string] $AetheriaRoot = "E:\Projects\Aetheria", [string] $UnityExe = "C:\Program Files\Unity\Hub\Editor\6000.4.2f1\Editor\Unity.exe", - [string] $OutputRoot = "" + [string] $OutputRoot = "", + [string] $PackageName = "org.gamecult.eve.unity-uitoolkit", + [string] $TestAssembly = "GameCult.Eve.UnityUIToolkit.Tests" ) $ErrorActionPreference = "Stop" @@ -10,6 +12,12 @@ $eveRoot = Split-Path -Parent $PSScriptRoot if ([string]::IsNullOrWhiteSpace($OutputRoot)) { $OutputRoot = Join-Path $eveRoot "artifacts\aetheria-unity-editmode" } +if ([string]::IsNullOrWhiteSpace($PackageName)) { + throw "Unity EditMode package name must not be empty" +} +if ([string]::IsNullOrWhiteSpace($TestAssembly)) { + throw "Unity EditMode test assembly must not be empty" +} if (-not (Test-Path -LiteralPath $AetheriaRoot)) { throw "Aetheria repo not found: $AetheriaRoot" @@ -29,7 +37,6 @@ New-Item -ItemType Directory -Force -Path $runRoot | Out-Null $resultsPath = Join-Path $runRoot "unity-editmode-results.xml" $logPath = Join-Path $runRoot "unity-editmode.log" -$packageName = "org.gamecult.eve.unity-uitoolkit" $originalManifest = Get-Content -Raw -LiteralPath $manifestPath $manifestRestored = $false @@ -43,9 +50,12 @@ function Restore-Manifest { try { $manifest = $originalManifest | ConvertFrom-Json - $testables = @($manifest.testables) - if ($testables -notcontains $packageName) { - $testables += $packageName + $testables = @() + if ($null -ne $manifest.testables) { + $testables = @($manifest.testables) | Where-Object { $null -ne $_ -and -not [string]::IsNullOrWhiteSpace([string] $_) } + } + if ($testables -notcontains $PackageName) { + $testables += $PackageName if ($manifest.PSObject.Properties.Name -contains "testables") { $manifest.testables = $testables } else { @@ -59,7 +69,7 @@ try { "-projectPath", $AetheriaRoot, "-runTests", "-testPlatform", "EditMode", - "-assemblyNames", "GameCult.Eve.UnityUIToolkit.Tests", + "-assemblyNames", $TestAssembly, "-testResults", $resultsPath, "-logFile", $logPath ) @@ -94,6 +104,6 @@ if ($failed -gt 0) { throw "Unity EditMode tests failed: $failed failed, $passed passed, $total total. Results: $resultsPath" } -Write-Host "Unity EditMode tests passed: $passed passed, $total total" +Write-Host "Unity EditMode tests passed for ${TestAssembly}: $passed passed, $total total" Write-Host "Unity EditMode results: $resultsPath" Write-Host "Unity EditMode log: $logPath" diff --git a/scripts/run-aetheria-unity-scene-editmode-tests.ps1 b/scripts/run-aetheria-unity-scene-editmode-tests.ps1 new file mode 100644 index 0000000..86d8c28 --- /dev/null +++ b/scripts/run-aetheria-unity-scene-editmode-tests.ps1 @@ -0,0 +1,19 @@ +param( + [string] $AetheriaRoot = "E:\Projects\Aetheria", + [string] $UnityExe = "C:\Program Files\Unity\Hub\Editor\6000.4.2f1\Editor\Unity.exe", + [string] $OutputRoot = "" +) + +$ErrorActionPreference = "Stop" + +$eveRoot = Split-Path -Parent $PSScriptRoot +if ([string]::IsNullOrWhiteSpace($OutputRoot)) { + $OutputRoot = Join-Path $eveRoot "artifacts\aetheria-unity-scene-editmode" +} + +& (Join-Path $PSScriptRoot "run-aetheria-unity-editmode-tests.ps1") ` + -AetheriaRoot $AetheriaRoot ` + -UnityExe $UnityExe ` + -OutputRoot $OutputRoot ` + -PackageName "org.gamecult.eve.unity-scene" ` + -TestAssembly "GameCult.Eve.UnityScene.Tests" diff --git a/scripts/run-eveunity-scene-lifecycle-smoke.ps1 b/scripts/run-eveunity-scene-lifecycle-smoke.ps1 index dcbb4c7..e9e58cd 100644 --- a/scripts/run-eveunity-scene-lifecycle-smoke.ps1 +++ b/scripts/run-eveunity-scene-lifecycle-smoke.ps1 @@ -1,5 +1,6 @@ param( - [string] $CapabilityManifestPath = "runtimes\incubating\eve-unity-scene\eve-runtime-capability.json" + [string] $CapabilityManifestPath = "runtimes\incubating\eve-unity-scene\eve-runtime-capability.json", + [switch] $RunUnityEditMode ) $ErrorActionPreference = "Stop" @@ -39,7 +40,7 @@ if ($manifest.incubation.splitHandoff.manifestPath -ne "runtimes/incubating/eve- throw "EveUnity scene manifest missing split handoff path" } -foreach ($feature in @("providerAdvertisements", "commandTransport", "providerSurfaceSession", "providerSurfaceSource", "providerSurfaceDocumentSource", "livePlayableWorldClient", "providerCommandReceipts", "providerAssetManifestDocumentSource", "sceneGraphProjection", "playableWorldProjection", "playableWorldRuntimeHost", "playableWorldScenePresentation", "unityGameObjectSceneSink", "providerAssetManifestResolution", "providerAssetManifestSource", "embeddedDocuments")) { +foreach ($feature in @("providerAdvertisements", "commandTransport", "providerSurfaceSession", "providerSurfaceSource", "providerSurfaceDocumentSource", "livePlayableWorldClient", "providerCommandReceipts", "providerAssetManifestDocumentSource", "playableWorldClientHost", "playableWorldClientBootstrap", "playableWorldInputDriver", "playableWorldCameraRig", "sceneGraphProjection", "playableWorldProjection", "playableWorldRuntimeHost", "playableWorldScenePresentation", "unityGameObjectSceneSink", "providerAssetManifestResolution", "providerAssetManifestSource", "embeddedDocuments")) { if (-not (@($manifest.supportedFeatures) -contains $feature)) { throw "EveUnity scene manifest missing provider-shell feature: $feature" } @@ -182,6 +183,18 @@ foreach ($field in @("ownerRepo", "runnerKind", "runnerScript", "consumerProject throw "EveUnity scene test contract missing $field" } } +if ($testContract.runnerKind -ne "unity-editmode-batchmode") { + throw "EveUnity scene test contract has unexpected runner kind: $($testContract.runnerKind)" +} +if ($testContract.packageName -ne "org.gamecult.eve.unity-scene") { + throw "EveUnity scene test contract has unexpected package name: $($testContract.packageName)" +} +if ($testContract.testAssembly -ne "GameCult.Eve.UnityScene.Tests") { + throw "EveUnity scene test contract has unexpected test assembly: $($testContract.testAssembly)" +} +if ($testContract.testPlatform -ne "EditMode") { + throw "EveUnity scene test contract has unexpected test platform: $($testContract.testPlatform)" +} foreach ($pathProperty in @("runnerScript", "consumerProject")) { $candidate = $testContract.$pathProperty $absolutePath = if ([System.IO.Path]::IsPathRooted($candidate)) { @@ -193,6 +206,12 @@ foreach ($pathProperty in @("runnerScript", "consumerProject")) { throw "EveUnity scene test contract $pathProperty does not exist: $candidate" } } +$runnerSource = Get-Content -LiteralPath (Join-Path $projectRoot $testContract.runnerScript) -Raw +foreach ($expectedText in @($testContract.packageName, $testContract.testAssembly, "run-aetheria-unity-editmode-tests.ps1")) { + if (-not $runnerSource.Contains($expectedText)) { + throw "EveUnity scene test runner script missing expected text: $expectedText" + } +} $captureContract = $manifest.lifecycle.capture.captureContract foreach ($field in @("ownerRepo", "runtimeId", "targetId", "requestSchema", "requestBuilder", "advertisementPath", "captureKind", "artifactKind", "artifactPattern", "conformanceAttachment", "requiredProvider", "requiredSurface", "authority", "publishProof")) { @@ -227,4 +246,11 @@ foreach ($pathProperty in @("requestBuilder", "advertisementPath")) { & (Join-Path $projectRoot "scripts\run-eveunity-scene-capture-contract-smoke.ps1") & (Join-Path $projectRoot "scripts\run-eveunity-scene-capture-smoke.ps1") +if ($RunUnityEditMode) { + & (Join-Path $projectRoot "scripts\run-aetheria-unity-scene-editmode-tests.ps1") + if ($LASTEXITCODE -ne 0) { + throw "Aetheria Unity scene EditMode smoke failed with exit code $LASTEXITCODE" + } +} + Write-Host "EveUnity scene lifecycle smoke passed: $absoluteManifestPath" diff --git a/scripts/run-eveunity-scene-provider-shell-smoke.ps1 b/scripts/run-eveunity-scene-provider-shell-smoke.ps1 index fb95248..5fa97ae 100644 --- a/scripts/run-eveunity-scene-provider-shell-smoke.ps1 +++ b/scripts/run-eveunity-scene-provider-shell-smoke.ps1 @@ -20,7 +20,7 @@ $manifest = Get-Content -LiteralPath $absoluteManifestPath -Raw | ConvertFrom-Js if ($manifest.runtimeId -ne "unity-scene") { throw "Unexpected EveUnity scene runtime id: $($manifest.runtimeId)" } -if ($manifest.lifecycle.test.status -ne "provider-shell-contract-skeleton") { +if ($manifest.lifecycle.test.status -ne "unity-scene-editmode-batchmode") { throw "Unexpected EveUnity scene provider shell status: $($manifest.lifecycle.test.status)" } diff --git a/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 b/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 index bd52574..ad59c4c 100644 --- a/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 +++ b/scripts/run-runtime-owner-conformance-consumer-smoke.ps1 @@ -236,10 +236,10 @@ node $consumerScript $consumerExport ` --expect-runtime-lifecycle-field "unity-uitoolkit:capture:captureContract.additionalProviderSurfaces.1.providerId:aetheria" ` --expect-runtime-lifecycle-field "unity-uitoolkit:capture:captureContract.additionalProviderSurfaces.1.surfaceId:aetheria.daemon.editor" ` --expect-runtime-lifecycle-status unity-scene:release:unity-scene-upm-artifact-smoke ` - --expect-runtime-lifecycle-status unity-scene:test:provider-shell-contract-skeleton ` + --expect-runtime-lifecycle-status unity-scene:test:unity-scene-editmode-batchmode ` --expect-runtime-lifecycle-status unity-scene:capture:pending-unity-scene-capture ` --expect-runtime-lifecycle-pending "unity-scene:release:Unity scene package release" ` - --expect-runtime-lifecycle-pending "unity-scene:test:Unity scene provider-advertisement smoke" ` + --expect-runtime-lifecycle-pending "unity-scene:test:Unity scene EditMode runner" ` --expect-runtime-lifecycle-pending "unity-scene:capture:Unity scene screenshot or frame-capture PNG artifact" ` --expect-runtime-lifecycle-field "unity-scene:release:releaseContract.packageName:org.gamecult.eve.unity-scene" ` --expect-runtime-lifecycle-field "unity-scene:release:releaseContract.artifactKind:upm-package" ` @@ -252,8 +252,10 @@ node $consumerScript $consumerExport ` --expect-runtime-lifecycle-field "unity-scene:release:releaseContract.requiredPackageDependencies.0.packageName:org.gamecult.eve.surface" ` --expect-runtime-lifecycle-field "unity-scene:release:releaseContract.requiredPackageDependencies.0.ownerRepo:Eve" ` --expect-runtime-lifecycle-field "unity-scene:release:releaseContract.requiredPackageDependencies.0.packageManager:upm" ` - --expect-runtime-lifecycle-field "unity-scene:test:testContract.runnerKind:unity-scene-provider-shell-smoke" ` - --expect-runtime-lifecycle-field "unity-scene:test:testContract.runnerScript:scripts/run-eveunity-scene-provider-shell-smoke.ps1" ` + --expect-runtime-lifecycle-field "unity-scene:test:testContract.runnerKind:unity-editmode-batchmode" ` + --expect-runtime-lifecycle-field "unity-scene:test:testContract.runnerScript:scripts/run-aetheria-unity-scene-editmode-tests.ps1" ` + --expect-runtime-lifecycle-field "unity-scene:test:testContract.testPlatform:EditMode" ` + --expect-runtime-lifecycle-field "unity-scene:test:testContract.testAssembly:GameCult.Eve.UnityScene.Tests" ` --expect-runtime-lifecycle-field "unity-scene:capture:captureContract.captureKind:unity-scene-frame-png" ` --expect-runtime-lifecycle-field "unity-scene:capture:captureContract.targetId:unity-scene" ` --expect-runtime-lifecycle-field "unity-scene:capture:captureContract.requestSchema:gamecult.eve.runtime_capture_request.v1" ` diff --git a/tools/parity/parity-manifest.json b/tools/parity/parity-manifest.json index cb9164b..75f3bab 100644 --- a/tools/parity/parity-manifest.json +++ b/tools/parity/parity-manifest.json @@ -656,7 +656,8 @@ "runtimes/incubating/eve-unity-scene/eve-runtime-capability.json", "scripts/run-eveunity-scene-lifecycle-smoke.ps1", "scripts/run-eveunity-scene-release-artifact-smoke.ps1", - "scripts/run-eveunity-scene-provider-shell-smoke.ps1" + "scripts/run-eveunity-scene-provider-shell-smoke.ps1", + "scripts/run-aetheria-unity-scene-editmode-tests.ps1" ] }, { @@ -675,7 +676,7 @@ ], "pendingProofs": [ "Tagged UPM release is cut from EveUnity rather than Eve incubation.", - "Unity batchmode EditMode runner is owned by EveUnity rather than Eve incubation.", + "Unity batchmode EditMode runners are owned by EveUnity rather than Eve incubation.", "Unity batchmode or editor capture artifact is attached to the runtime conformance report.", "Unity scene runtime body graduates to EveUnity outside Aetheria product code.", "Unity scene screenshot or frame-capture PNG artifact is attached to the runtime conformance report."