test: make prerequisite lanes fail honestly

This commit is contained in:
Erik 2026-08-18 12:09:41 +02:00
parent dfc841b779
commit 6faeb4a103
113 changed files with 424 additions and 336 deletions

View file

@ -100,7 +100,22 @@ generator (the former chat/radar-only generators were redundant):
$env:ACDREAM_REGENERATE_UI_FIXTURES = '1' $env:ACDREAM_REGENERATE_UI_FIXTURES = '1'
$env:ACDREAM_DAT_DIR = 'C:\path\to\Asherons Call' $env:ACDREAM_DAT_DIR = 'C:\path\to\Asherons Call'
dotnet test tests/AcDream.App.Tests/AcDream.App.Tests.csproj -c Release ` dotnet test tests/AcDream.App.Tests/AcDream.App.Tests.csproj -c Release `
--filter 'Lane=Manual' --filter 'Lane=Manual&ManualTask=FixtureGeneration'
```
The retained live-DAT probes are manual evidence, not InstalledDat regression
contracts. Run each opt-in family independently so a probe command can never
regenerate fixtures as a side effect:
```powershell
$env:ACDREAM_DAT_DIR = 'C:\path\to\Asherons Call'
$env:ACDREAM_PROBE_LIVE_MOUNT = '1'
dotnet test tests/AcDream.App.Tests/AcDream.App.Tests.csproj -c Release `
--filter 'Lane=Manual&ManualTask=LiveMountProbe'
$env:ACDREAM_PROBE_POWERBAR = '1'
dotnet test tests/AcDream.App.Tests/AcDream.App.Tests.csproj -c Release `
--filter 'Lane=Manual&ManualTask=PowerbarProbe'
``` ```
Known failures (`Status=KnownFailure`) are never part of a green release total. Known failures (`Status=KnownFailure`) are never part of a green release total.
@ -114,9 +129,9 @@ investigation output, and several methods require installed DATs:
```powershell ```powershell
dotnet test tests/AcDream.App.Tests/AcDream.App.Tests.csproj -c Release ` dotnet test tests/AcDream.App.Tests/AcDream.App.Tests.csproj -c Release `
--filter 'Purpose=Diagnostic' --filter 'Purpose=Diagnostic&Lane!=Manual'
dotnet test tests/AcDream.Core.Tests/AcDream.Core.Tests.csproj -c Release ` dotnet test tests/AcDream.Core.Tests/AcDream.Core.Tests.csproj -c Release `
--filter 'Purpose=Diagnostic' --filter 'Purpose=Diagnostic&Lane!=Manual'
``` ```
Operating-system contracts are likewise explicit. Run `Lane=Windows` on a Operating-system contracts are likewise explicit. Run `Lane=Windows` on a

View file

@ -38,27 +38,27 @@ pwsh ./tools/audit-test-inventory.ps1
The generated JSON lives under ignored `artifacts/test-audit/`; it is not a The generated JSON lives under ignored `artifacts/test-audit/`; it is not a
second 6.8 MB checked-in source of truth. The script and this reviewed ledger second 6.8 MB checked-in source of truth. The script and this reviewed ledger
are durable, while paths and line numbers regenerate after every batch. The are durable, while paths and line numbers regenerate after every batch. The
inventory at commit `8f490240` reports: inventory refreshed for Batch G reports:
| Syntax signal | Current count | | Syntax signal | Current count |
|---|---:| |---|---:|
| Tracked/parsed C# test files | 1,256 / 1,256 | | Tracked/parsed C# test files | 1,256 / 1,256 |
| Attributed test methods (not expanded theory cases) | 11,455 | | Attributed test methods (not expanded theory cases) | 11,450 |
| Methods containing at least one empty `return;` | 399 | | Methods containing at least one empty `return;` | 138 |
| Empty-return sites | 426 | | Empty-return sites | 143 |
| Prerequisite-return candidates | 282 | | Direct / same-file-helper prerequisite-return candidates | 2 / 1 |
| Mechanical output-only candidates | 47 | | Mechanical output-only candidates | 2 |
| Methods directly using `Thread.Sleep` / `Task.Delay` | 20 / 23 | | Reviewed diagnostic methods | 51 |
| Methods directly using `Thread.Sleep` / `Task.Delay` | 15 / 23 |
| Methods directly reading environment variables | 47 | | Methods directly reading environment variables | 47 |
| Methods directly reading `.cs` source text | 63 | | Methods directly reading `.cs` source text | 63 |
The 282 prerequisite-return count is intentionally a review candidate set, not The three remaining prerequisite-return candidates are all reviewed branch
a claim that all 399 methods are broken. It comprises 109 App, 125 Core, 29 false positives: the two Windows/Linux factory assertions and the launcher's
Content, 12 Launcher.Core, three Core.Net, three Bake, and one Headless method. cross-platform directory-link helper. Every true prerequisite return found by
The classifier includes external-asset, opt-in, and platform gates; behavioral the inventory now fails explicitly inside its selected non-hermetic lane. The
early exits inside callback tests remain outside that candidate set. Every remaining 143 empty returns are behavioral control flow, callback exits, or
candidate still requires source inspection because `Directory.Exists`, for the three platform branches; they are not missing-prerequisite passes.
example, can also be the behavior under test.
The output-only classifier follows same-file helper calls, but it cannot decide The output-only classifier follows same-file helper calls, but it cannot decide
whether an assertion merely establishes probe setup. The reviewed diagnostic whether an assertion merely establishes probe setup. The reviewed diagnostic
@ -95,17 +95,16 @@ Installed-DAT skip distribution:
| `TooltipLiveDatTests` | 7 | | `TooltipLiveDatTests` | 7 |
| `UiButtonCorpusSweepTests` | 3 | | `UiButtonCorpusSweepTests` | 3 |
There are also 11 source sites that throw `SkipException.ForSkip` conditionally. The 11 source sites that conditionally threw `SkipException.ForSkip` were not
They are not part of the current 77 because their prerequisites happened to be part of the R2 77 because their prerequisites happened to be available on that
available on the R2 gate machine. R3 must retain their per-test reason and machine. Batch G preserves their reasons but replaces the misleading dynamic-
assign them to the installed-DAT, prepared-package, system-font, or other skip exception with explicit lane-prerequisite failures. No static skip or
explicit prerequisite lane; a future machine may report them as additional `SkipException.ForSkip` remains in current test source.
skips.
The lane vocabulary is deliberately orthogonal: The lane vocabulary is deliberately orthogonal:
- `Lane` states the execution environment (`InstalledDat`, `PreparedPackage`, - `Lane` states the execution environment (`InstalledDat`, `PreparedPackage`,
`Live`, or `Manual`); `Live`, `Manual`, `Windows`, `Linux`, or `SystemFont`);
- `Purpose=Diagnostic` marks output/investigation apparatus that cannot add to - `Purpose=Diagnostic` marks output/investigation apparatus that cannot add to
the contract-test pass count; and the contract-test pass count; and
- `Status=KnownFailure` keeps a named executable oracle visible without making - `Status=KnownFailure` keeps a named executable oracle visible without making
@ -127,7 +126,7 @@ identifiable in the lane report.
| T-004 warning mismatches | resolved in R2 | Clean rebuild is zero-warning with repository-wide warnings-as-errors. | | T-004 warning mismatches | resolved in R2 | Clean rebuild is zero-warning with repository-wide warnings-as-errors. |
| T-005 unreachable panel stack | requires production reachability proof | Do not delete 52 meaningful tests until the dead presentation surface and any supported plugin compatibility promise are verified together. | | T-005 unreachable panel stack | requires production reachability proof | Do not delete 52 meaningful tests until the dead presentation surface and any supported plugin compatibility promise are verified together. |
| T-006 misleading installed-DAT reason | resolved in batch B | Shared opt-in is now `ACDREAM_RUN_INSTALLED_DAT_TESTS=1` (legacy switch retained), the reason names the lane, and all nine owners carry `Lane=InstalledDat`. | | T-006 misleading installed-DAT reason | resolved in batch B | Shared opt-in is now `ACDREAM_RUN_INSTALLED_DAT_TESTS=1` (legacy switch retained), the reason names the lane, and all nine owners carry `Lane=InstalledDat`. |
| T-007 271 silent passing gates | lane classification complete in batch D; body cleanup active | Of 282 current candidates, 280 are true prerequisite gates and now have an explicit lane. The two unlaned methods are reviewed false positives that assert the current Windows/Linux branch before returning. Empty-return removal remains, lane by lane. | | T-007 271 silent passing gates | resolved in batch G | All 280 directly found gates plus three later-reconciled sites now fail explicitly when their selected lane lacks its prerequisite. The only three syntax candidates left are reviewed cross-platform branch false positives. |
| T-008 incapable-of-failing diagnostics | batch A plus diagnostic lane work | Delete the literal wiring smoke test; repair the GPU contract tautology; later re-home output-only apparatus. | | T-008 incapable-of-failing diagnostics | batch A plus diagnostic lane work | Delete the literal wiring smoke test; repair the GPU contract tautology; later re-home output-only apparatus. |
| T-009 wall-clock double-click tests | resolved in batch E | Four sleeps were replaced by a deterministic test clock behind an internal factory overload. The production factory still reads `Environment.TickCount64` exactly as before. | | T-009 wall-clock double-click tests | resolved in batch E | Four sleeps were replaced by a deterministic test clock behind an internal factory overload. The production factory still reads `Environment.TickCount64` exactly as before. |
| T-010 two useless cases | high-confidence cleanup batch A | Delete `SmokeTest.TestProject_IsWired` and `ChaseCameraTests.ImplementsICamera`; compilation already proves both claims. | | T-010 two useless cases | high-confidence cleanup batch A | Delete `SmokeTest.TestProject_IsWired` and `ChaseCameraTests.ImplementsICamera`; compilation already proves both claims. |
@ -370,3 +369,57 @@ warnings/errors, the refreshed inventory reports two explicit known-failure
methods and 15 remaining direct `Thread.Sleep` methods, and the no-retry methods and 15 remaining direct `Thread.Sleep` methods, and the no-retry
hermetic gate passed 14,391/14,391 with zero skips or failures. The one-pass hermetic gate passed 14,391/14,391 with zero skips or failures. The one-pass
reduction is exactly #321 leaving the release lane. reduction is exactly #321 leaving the release lane.
## Batch G honest prerequisite lanes
Batch G removes every true silent prerequisite pass found by the direct and
same-file-helper inventory. Across 101 test files, 283 lane-owned `return;`
sites now report a prerequisite failure when that lane was explicitly
selected: 261 installed-DAT, ten Linux, seven Windows, three Live, and two
prepared-package methods. Seventeen platform guards throw
`PlatformNotSupportedException`; the remaining gates use lane-specific
assertion failures. Production behavior and every contract assertion after the
guard are unchanged.
The eleven conditional `SkipException.ForSkip` sites now use explicit
prerequisite failures as well. Their asset, package, or font reason is retained,
but a selected lane can no longer look green by dynamically skipping the
contract. The refreshed syntax inventory finds zero true silent-prerequisite
candidates. Its three remaining candidates are the reviewed Windows/Linux
branch returns recorded in Batch E.
The focused installed-DAT run also exposed a taxonomy error rather than a
product failure: 19 interactive layout methods need a retail DAT directory but
are operator-driven probes, not automated DAT contracts. They now live under
`Lane=Manual`, divided into `ManualTask=LiveMountProbe` (13) and
`ManualTask=PowerbarProbe` (6). The comprehensive existing generator is
separately named `ManualTask=FixtureGeneration`, so selecting a probe cannot
rewrite committed fixtures. Current attributed-method lane ownership is:
| Lane | Methods |
|---|---:|
| `InstalledDat` | 317 |
| `PreparedPackage` | 2 |
| `Live` | 3 |
| `Manual` | 20 |
| `Windows` | 7 |
| `Linux` | 10 |
| `SystemFont` | 2 |
Focused verification before the complete gate:
- Release build of all 44 maintained projects: 0 warnings, 0 errors;
- installed-DAT contracts: 311/311 passed (App 150, Bake 3, Content 28,
Core 130);
- prepared-package contracts: 2/2 passed against the validated local package;
- Windows contracts: 7/7 passed; system-font contracts: 2/2 passed;
- manual live-mount probes: 13/13 passed; manual powerbar probes: 6/6 passed;
- a Linux contract selected on Windows failed with the explicit wrong-host
reason; and
- a Live contract selected without opt-in failed with the explicit
`ACDREAM_LIVE=1`/reachable-server prerequisite reason.
The fixture-generation task was intentionally not executed: its documented
purpose is to rewrite fixture files, while this R3 batch is review/test-only.
The no-retry complete hermetic Release gate passed 14,391/14,391 with zero
skips or failures across all 12 test assemblies.

View file

@ -135,7 +135,7 @@ public sealed class AppCredentialResolverTests
public void LinuxRejectsGroupOrOtherCredentialPermissions() public void LinuxRejectsGroupOrOtherCredentialPermissions()
{ {
if (!OperatingSystem.IsLinux()) if (!OperatingSystem.IsLinux())
return; throw new PlatformNotSupportedException("Lane=Linux requires a native Linux host.");
string path = Path.Combine( string path = Path.Combine(
Path.GetTempPath(), Path.GetTempPath(),

View file

@ -49,7 +49,7 @@ public sealed class ChargenPreviewControllerTests
public void Rebuild_SameSelectionTwice_IsANoOpSecondTime() public void Rebuild_SameSelectionTwice_IsANoOpSecondTime()
{ {
if (!TryOpen(out DatCollection? dats, out DatCollectionAdapter? adapter)) if (!TryOpen(out DatCollection? dats, out DatCollectionAdapter? adapter))
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using (dats) using (dats)
using (adapter) using (adapter)
{ {
@ -72,7 +72,7 @@ public sealed class ChargenPreviewControllerTests
public void Rebuild_HeritageChange_ResetsCameraToTheNewHeritagesDefaultEye() public void Rebuild_HeritageChange_ResetsCameraToTheNewHeritagesDefaultEye()
{ {
if (!TryOpen(out DatCollection? dats, out DatCollectionAdapter? adapter)) if (!TryOpen(out DatCollection? dats, out DatCollectionAdapter? adapter))
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using (dats) using (dats)
using (adapter) using (adapter)
{ {
@ -119,7 +119,7 @@ public sealed class ChargenPreviewControllerTests
public void Rebuild_AppearanceOnlyChange_LeavesTheCameraUntouched() public void Rebuild_AppearanceOnlyChange_LeavesTheCameraUntouched()
{ {
if (!TryOpen(out DatCollection? dats, out DatCollectionAdapter? adapter)) if (!TryOpen(out DatCollection? dats, out DatCollectionAdapter? adapter))
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using (dats) using (dats)
using (adapter) using (adapter)
{ {
@ -147,7 +147,7 @@ public sealed class ChargenPreviewControllerTests
public void Rebuild_PreservesZoomState_AcrossAnAppearanceOnlyChange() public void Rebuild_PreservesZoomState_AcrossAnAppearanceOnlyChange()
{ {
if (!TryOpen(out DatCollection? dats, out DatCollectionAdapter? adapter)) if (!TryOpen(out DatCollection? dats, out DatCollectionAdapter? adapter))
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using (dats) using (dats)
using (adapter) using (adapter)
{ {
@ -178,7 +178,7 @@ public sealed class ChargenPreviewControllerTests
public void Rebuild_ThenRender_SeedsTheEntityHeadingToTheRetailDefault180Degrees() public void Rebuild_ThenRender_SeedsTheEntityHeadingToTheRetailDefault180Degrees()
{ {
if (!TryOpen(out DatCollection? dats, out DatCollectionAdapter? adapter)) if (!TryOpen(out DatCollection? dats, out DatCollectionAdapter? adapter))
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using (dats) using (dats)
using (adapter) using (adapter)
{ {
@ -215,7 +215,7 @@ public sealed class ChargenPreviewControllerTests
public void Rebuild_HeritageWithEnvironmentSetupId_SetsANonNullBackdrop() public void Rebuild_HeritageWithEnvironmentSetupId_SetsANonNullBackdrop()
{ {
if (!TryOpen(out DatCollection? dats, out DatCollectionAdapter? adapter)) if (!TryOpen(out DatCollection? dats, out DatCollectionAdapter? adapter))
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using (dats) using (dats)
using (adapter) using (adapter)
{ {
@ -250,7 +250,7 @@ public sealed class ChargenPreviewControllerTests
public void Rebuild_HeritageWithNoEnvironmentSetupId_LeavesTheBackdropAbsent() public void Rebuild_HeritageWithNoEnvironmentSetupId_LeavesTheBackdropAbsent()
{ {
if (!TryOpen(out DatCollection? dats, out DatCollectionAdapter? adapter)) if (!TryOpen(out DatCollection? dats, out DatCollectionAdapter? adapter))
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using (dats) using (dats)
using (adapter) using (adapter)
{ {
@ -292,7 +292,7 @@ public sealed class ChargenPreviewControllerTests
public void Rebuild_HeritageChange_SwapsTheBackdropEntity() public void Rebuild_HeritageChange_SwapsTheBackdropEntity()
{ {
if (!TryOpen(out DatCollection? dats, out DatCollectionAdapter? adapter)) if (!TryOpen(out DatCollection? dats, out DatCollectionAdapter? adapter))
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using (dats) using (dats)
using (adapter) using (adapter)
{ {
@ -345,7 +345,7 @@ public sealed class ChargenPreviewControllerTests
public void Rebuild_AppearanceOnlyChange_DoesNotRebuildTheBackdrop() public void Rebuild_AppearanceOnlyChange_DoesNotRebuildTheBackdrop()
{ {
if (!TryOpen(out DatCollection? dats, out DatCollectionAdapter? adapter)) if (!TryOpen(out DatCollection? dats, out DatCollectionAdapter? adapter))
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using (dats) using (dats)
using (adapter) using (adapter)
{ {
@ -371,7 +371,7 @@ public sealed class ChargenPreviewControllerTests
public void Render_WhilePageInvisible_SkipsRenderAndTexturePublication() public void Render_WhilePageInvisible_SkipsRenderAndTexturePublication()
{ {
if (!TryOpen(out DatCollection? dats, out DatCollectionAdapter? adapter)) if (!TryOpen(out DatCollection? dats, out DatCollectionAdapter? adapter))
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using (dats) using (dats)
using (adapter) using (adapter)
{ {

View file

@ -30,7 +30,7 @@ public sealed class ChargenPreviewEntityBuilderTests
public void TryBuild_AluvianMaleDefaultSelection_ProducesANonEmptyStaticPoseEntity() public void TryBuild_AluvianMaleDefaultSelection_ProducesANonEmptyStaticPoseEntity()
{ {
string? datDir = CornerFloodReplayTests.ResolveDatDir(); string? datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
using var adapter = new DatCollectionAdapter(dats); using var adapter = new DatCollectionAdapter(dats);
@ -88,7 +88,7 @@ public sealed class ChargenPreviewEntityBuilderTests
ChargenPreviewEntityBuilder.SummaryPreviewBackdropRenderId); ChargenPreviewEntityBuilder.SummaryPreviewBackdropRenderId);
string? datDir = CornerFloodReplayTests.ResolveDatDir(); string? datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
using var adapter = new DatCollectionAdapter(dats); using var adapter = new DatCollectionAdapter(dats);
@ -122,7 +122,7 @@ public sealed class ChargenPreviewEntityBuilderTests
public void TryBuild_UnknownSetupId_ReturnsNull() public void TryBuild_UnknownSetupId_ReturnsNull()
{ {
string? datDir = CornerFloodReplayTests.ResolveDatDir(); string? datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
using var adapter = new DatCollectionAdapter(dats); using var adapter = new DatCollectionAdapter(dats);
@ -146,7 +146,7 @@ public sealed class ChargenPreviewEntityBuilderTests
public void TryBuild_OlthoiHeritage_ResolvesADifferentRestPoseDidThanStandardHeritages() public void TryBuild_OlthoiHeritage_ResolvesADifferentRestPoseDidThanStandardHeritages()
{ {
string? datDir = CornerFloodReplayTests.ResolveDatDir(); string? datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
using var adapter = new DatCollectionAdapter(dats); using var adapter = new DatCollectionAdapter(dats);
@ -187,7 +187,7 @@ public sealed class ChargenPreviewEntityBuilderTests
public void TryBuildAnimated_AluvianMaleDefaultSelection_ResolvesARealIdleCycle() public void TryBuildAnimated_AluvianMaleDefaultSelection_ResolvesARealIdleCycle()
{ {
string? datDir = CornerFloodReplayTests.ResolveDatDir(); string? datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
using var adapter = new DatCollectionAdapter(dats); using var adapter = new DatCollectionAdapter(dats);
@ -233,7 +233,7 @@ public sealed class ChargenPreviewEntityBuilderTests
public void TryBuildAnimated_UnknownSetupId_ReturnsNull() public void TryBuildAnimated_UnknownSetupId_ReturnsNull()
{ {
string? datDir = CornerFloodReplayTests.ResolveDatDir(); string? datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
using var adapter = new DatCollectionAdapter(dats); using var adapter = new DatCollectionAdapter(dats);
@ -275,7 +275,7 @@ public sealed class ChargenPreviewEntityBuilderTests
public void OlthoiFamily_SharedIdleRestEnumKey_ResolvesToARealInstalledDid(uint sharedEnumKey) public void OlthoiFamily_SharedIdleRestEnumKey_ResolvesToARealInstalledDid(uint sharedEnumKey)
{ {
string? datDir = CornerFloodReplayTests.ResolveDatDir(); string? datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
using var adapter = new DatCollectionAdapter(dats); using var adapter = new DatCollectionAdapter(dats);
@ -298,7 +298,7 @@ public sealed class ChargenPreviewEntityBuilderTests
public void TryBuildAnimated_OlthoiHeritage_ResolvesARealIdleAnimationToo() public void TryBuildAnimated_OlthoiHeritage_ResolvesARealIdleAnimationToo()
{ {
string? datDir = CornerFloodReplayTests.ResolveDatDir(); string? datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
using var adapter = new DatCollectionAdapter(dats); using var adapter = new DatCollectionAdapter(dats);
@ -338,7 +338,7 @@ public sealed class ChargenPreviewEntityBuilderTests
public void TryBuildBackdrop_AluvianHeritage_ResolvesANonEmptyMesh() public void TryBuildBackdrop_AluvianHeritage_ResolvesANonEmptyMesh()
{ {
string? datDir = CornerFloodReplayTests.ResolveDatDir(); string? datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
using var adapter = new DatCollectionAdapter(dats); using var adapter = new DatCollectionAdapter(dats);
@ -377,7 +377,7 @@ public sealed class ChargenPreviewEntityBuilderTests
public void TryBuildBackdrop_ExplicitRenderId_StampsThatIdOnTheEntity() public void TryBuildBackdrop_ExplicitRenderId_StampsThatIdOnTheEntity()
{ {
string? datDir = CornerFloodReplayTests.ResolveDatDir(); string? datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
using var adapter = new DatCollectionAdapter(dats); using var adapter = new DatCollectionAdapter(dats);
@ -406,7 +406,7 @@ public sealed class ChargenPreviewEntityBuilderTests
public void TryBuildBackdrop_UnsetEnvironmentSetupId_ReturnsNull() public void TryBuildBackdrop_UnsetEnvironmentSetupId_ReturnsNull()
{ {
string? datDir = CornerFloodReplayTests.ResolveDatDir(); string? datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
using var adapter = new DatCollectionAdapter(dats); using var adapter = new DatCollectionAdapter(dats);
@ -420,7 +420,7 @@ public sealed class ChargenPreviewEntityBuilderTests
public void TryBuildBackdrop_UnknownSetupId_ReturnsNull() public void TryBuildBackdrop_UnknownSetupId_ReturnsNull()
{ {
string? datDir = CornerFloodReplayTests.ResolveDatDir(); string? datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
using var adapter = new DatCollectionAdapter(dats); using var adapter = new DatCollectionAdapter(dats);
@ -441,7 +441,7 @@ public sealed class ChargenPreviewEntityBuilderTests
public void TryBuildBackdrop_AllThirteenHeritages_ResolveOrAreReportedByName() public void TryBuildBackdrop_AllThirteenHeritages_ResolveOrAreReportedByName()
{ {
string? datDir = CornerFloodReplayTests.ResolveDatDir(); string? datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
using var adapter = new DatCollectionAdapter(dats); using var adapter = new DatCollectionAdapter(dats);

View file

@ -202,7 +202,7 @@ public class CornerFloodReplayTests
public void Diagnostic_TraceGoodVsGlitchStep() public void Diagnostic_TraceGoodVsGlitchStep()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = LoadBuilding(dats); var cells = LoadBuilding(dats);
@ -271,7 +271,7 @@ public class CornerFloodReplayTests
public void CornerSweep_FloodIsCompleteAndMonotone() public void CornerSweep_FloodIsCompleteAndMonotone()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = LoadBuilding(dats); var cells = LoadBuilding(dats);
@ -369,7 +369,7 @@ public class CornerFloodReplayTests
public void PortalPlaneCrossings_InPlacePropagationConverges() public void PortalPlaneCrossings_InPlacePropagationConverges()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = LoadBuilding(dats); var cells = LoadBuilding(dats);
@ -440,7 +440,7 @@ public class CornerFloodReplayTests
public void InCellDirectionSweep_InPlacePropagationConverges() public void InCellDirectionSweep_InPlacePropagationConverges()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = LoadBuilding(dats); var cells = LoadBuilding(dats);
@ -503,7 +503,7 @@ public class CornerFloodReplayTests
public void Diagnostic_Hop2Microscope() public void Diagnostic_Hop2Microscope()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = LoadBuilding(dats); var cells = LoadBuilding(dats);
@ -634,7 +634,7 @@ public class CornerFloodReplayTests
public void Diagnostic_CornerPress_FloodAcrossDoorwayPlane() public void Diagnostic_CornerPress_FloodAcrossDoorwayPlane()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = LoadBuilding(dats); var cells = LoadBuilding(dats);

View file

@ -123,7 +123,7 @@ public sealed class FramePacingControllerTests
public void Windows_high_resolution_timer_arms_and_disposes_its_handle() public void Windows_high_resolution_timer_arms_and_disposes_its_handle()
{ {
if (!OperatingSystem.IsWindowsVersionAtLeast(10, 0, 17134)) if (!OperatingSystem.IsWindowsVersionAtLeast(10, 0, 17134))
return; throw new PlatformNotSupportedException("Lane=Windows requires a Windows host.");
using var timer = WindowsHighResolutionFramePacingWaiter.Create(); using var timer = WindowsHighResolutionFramePacingWaiter.Create();
timer.Wait(1, System.Diagnostics.Stopwatch.Frequency); timer.Wait(1, System.Diagnostics.Stopwatch.Frequency);

View file

@ -372,7 +372,7 @@ public class HouseExitWalkReplayTests
public void ExitWalk_PlayerStaysConeVisible_EveryStep() public void ExitWalk_PlayerStaysConeVisible_EveryStep()
{ {
var steps = RunExitWalk(); var steps = RunExitWalk();
if (steps is null) return; if (steps is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
var failures = steps.FindAll(s => !s.ConeVisible); var failures = steps.FindAll(s => !s.ConeVisible);
if (failures.Count > 0) if (failures.Count > 0)
@ -394,7 +394,7 @@ public class HouseExitWalkReplayTests
public void ExitWalk_PlayerSurvivesSealDepth_WhenConeVisible() public void ExitWalk_PlayerSurvivesSealDepth_WhenConeVisible()
{ {
var steps = RunExitWalk(); var steps = RunExitWalk();
if (steps is null) return; if (steps is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
var applicable = steps.FindAll(s => s.DepthCheckApplies); var applicable = steps.FindAll(s => s.DepthCheckApplies);
_out.WriteLine($"depth check applies on {applicable.Count}/{steps.Count} steps"); _out.WriteLine($"depth check applies on {applicable.Count}/{steps.Count} steps");
@ -420,7 +420,7 @@ public class HouseExitWalkReplayTests
public void ExitWalk_StraddlingPlayerDrawsInOutsideStage() public void ExitWalk_StraddlingPlayerDrawsInOutsideStage()
{ {
var steps = RunExitWalk(); var steps = RunExitWalk();
if (steps is null) return; if (steps is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
var straddling = steps.FindAll(s => var straddling = steps.FindAll(s =>
s.RootCellId != 0u && MathF.Abs(s.CenterS) < PlayerSphereRadius); s.RootCellId != 0u && MathF.Abs(s.CenterS) < PlayerSphereRadius);
@ -440,7 +440,7 @@ public class HouseExitWalkReplayTests
public void Diagnostic_ExitWalk_PerStepTable() public void Diagnostic_ExitWalk_PerStepTable()
{ {
var steps = RunExitWalk(); var steps = RunExitWalk();
if (steps is null) return; if (steps is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
DumpSteps(steps); DumpSteps(steps);
// transition summary // transition summary
int firstOutPlayer = steps.FindIndex(s => s.CenterS > 0f); int firstOutPlayer = steps.FindIndex(s => s.CenterS > 0f);
@ -460,7 +460,7 @@ public class HouseExitWalkReplayTests
public void Diagnostic_StaleRootWindow_EyeJustOutside() public void Diagnostic_StaleRootWindow_EyeJustOutside()
{ {
var datDir = CornerFloodReplayTests.ResolveDatDir(); var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = CornerFloodReplayTests.LoadBuilding(dats); var cells = CornerFloodReplayTests.LoadBuilding(dats);

View file

@ -40,7 +40,7 @@ public class Issue113DrawingBspFilterTests
public void MeetingHall_OrphanStairPolys_AreExcludedFromDrawSet() public void MeetingHall_OrphanStairPolys_AreExcludedFromDrawSet()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var hall = dats.Get<DatReaderWriter.DBObjs.GfxObj>(0x010014C3u)!; var hall = dats.Get<DatReaderWriter.DBObjs.GfxObj>(0x010014C3u)!;
@ -60,7 +60,7 @@ public class Issue113DrawingBspFilterTests
public void HillCottage_OrphanPolys_AreExcludedFromDrawSet() public void HillCottage_OrphanPolys_AreExcludedFromDrawSet()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cottage = dats.Get<DatReaderWriter.DBObjs.GfxObj>(0x01000827u)!; var cottage = dats.Get<DatReaderWriter.DBObjs.GfxObj>(0x01000827u)!;

View file

@ -181,7 +181,7 @@ public class Issue113MeetingHallFloodTests
public void WestApproach_HallCellSlices_HaveUsableClip() public void WestApproach_HallCellSlices_HaveUsableClip()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = LoadHall(dats); var cells = LoadHall(dats);

View file

@ -79,7 +79,7 @@ public class Issue120ReciprocalPingPongTests
public void CapturedPingPongSites_Converge(uint landblock, uint lowA, uint lowB, float ex, float ey, float ez) public void CapturedPingPongSites_Converge(uint landblock, uint lowA, uint lowB, float ex, float ey, float ez)
{ {
var datDir = CornerFloodReplayTests.ResolveDatDir(); var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = LoadAllInteriorCells(dats, landblock); var cells = LoadAllInteriorCells(dats, landblock);
@ -136,7 +136,7 @@ public class Issue120ReciprocalPingPongTests
{ {
_ = ex; _ = ey; _ = ez; // geometric variant derives its own eyes _ = ex; _ = ey; _ = ez; // geometric variant derives its own eyes
var datDir = CornerFloodReplayTests.ResolveDatDir(); var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = LoadAllInteriorCells(dats, landblock); var cells = LoadAllInteriorCells(dats, landblock);

View file

@ -89,7 +89,7 @@ public class Issue124LookInSeedRegionTests
public void SeedRegion_ContainingAperture_Floods_DisjointRegion_DoesNot() public void SeedRegion_ContainingAperture_Floods_DisjointRegion_DoesNot()
{ {
var datDir = CornerFloodReplayTests.ResolveDatDir(); var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var (cells, exitCell, exitIdx, centroid, outward) = LoadFixture(dats); var (cells, exitCell, exitIdx, centroid, outward) = LoadFixture(dats);
LoadedCell? Lookup(uint id) => cells.TryGetValue(id, out var c) ? c : null; LoadedCell? Lookup(uint id) => cells.TryGetValue(id, out var c) ? c : null;
@ -138,7 +138,7 @@ public class Issue124LookInSeedRegionTests
// interior-root gather pass ALL nearby buildings including the // interior-root gather pass ALL nearby buildings including the
// viewer's own without special-casing. // viewer's own without special-casing.
var datDir = CornerFloodReplayTests.ResolveDatDir(); var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var (cells, exitCell, _, centroid, outward) = LoadFixture(dats); var (cells, exitCell, _, centroid, outward) = LoadFixture(dats);
LoadedCell? Lookup(uint id) => cells.TryGetValue(id, out var c) ? c : null; LoadedCell? Lookup(uint id) => cells.TryGetValue(id, out var c) ? c : null;

View file

@ -60,7 +60,7 @@ public class Issue130DoorwayStripTests
public void Diagnostic_ExitDoorTopEdge_GateVsAperture() public void Diagnostic_ExitDoorTopEdge_GateVsAperture()
{ {
var datDir = CornerFloodReplayTests.ResolveDatDir(); var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = CornerFloodReplayTests.LoadBuilding(dats); var cells = CornerFloodReplayTests.LoadBuilding(dats);
@ -213,7 +213,7 @@ public class Issue130DoorwayStripTests
public void UnliftedGate_LeavesTheStripAtTheDrawnTopEdge() public void UnliftedGate_LeavesTheStripAtTheDrawnTopEdge()
{ {
var datDir = CornerFloodReplayTests.ResolveDatDir(); var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = CornerFloodReplayTests.LoadBuilding(dats); var cells = CornerFloodReplayTests.LoadBuilding(dats);

View file

@ -30,7 +30,7 @@ public class Issue131SetupProbeTests
public void Diagnostic_LookInFlood_AdmitsHallPorchFromCottage() public void Diagnostic_LookInFlood_AdmitsHallPorchFromCottage()
{ {
var datDir = CornerFloodReplayTests.ResolveDatDir(); var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, 0xA9B40000u); var cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, 0xA9B40000u);
@ -68,7 +68,7 @@ public class Issue131SetupProbeTests
public void Diagnostic_DumpOutstageCandidateSetups() public void Diagnostic_DumpOutstageCandidateSetups()
{ {
var datDir = CornerFloodReplayTests.ResolveDatDir(); var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
uint[] candidates = uint[] candidates =

View file

@ -68,7 +68,7 @@ public class Issue176177FacilityHubFloodReplayTests
public void ScenarioA_StairApproach_AdmissionsFromCorridor() public void ScenarioA_StairApproach_AdmissionsFromCorridor()
{ {
var datDir = CornerFloodReplayTests.ResolveDatDir(); var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; } if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub); var cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub);
Assert.True(cells.ContainsKey(FacilityHub | 0x0178u), "0x0178 not loaded"); Assert.True(cells.ContainsKey(FacilityHub | 0x0178u), "0x0178 not loaded");
@ -103,7 +103,7 @@ public class Issue176177FacilityHubFloodReplayTests
public void Diagnostic_ScenarioB_StairDescent_RampCellRetention() public void Diagnostic_ScenarioB_StairDescent_RampCellRetention()
{ {
var datDir = CornerFloodReplayTests.ResolveDatDir(); var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; } if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub); var cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub);
@ -146,7 +146,7 @@ public class Issue176177FacilityHubFloodReplayTests
public void Diagnostic_ScenarioC_CorridorSeamGazeSweep_Bistability() public void Diagnostic_ScenarioC_CorridorSeamGazeSweep_Bistability()
{ {
var datDir = CornerFloodReplayTests.ResolveDatDir(); var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; } if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub); var cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub);
@ -222,7 +222,7 @@ public class Issue176177FacilityHubFloodReplayTests
uint rootLow, uint forwardLow, float planeX, float eyeZ) uint rootLow, uint forwardLow, float planeX, float eyeZ)
{ {
var datDir = CornerFloodReplayTests.ResolveDatDir(); var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; } if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub); var cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub);
@ -247,7 +247,7 @@ public class Issue176177FacilityHubFloodReplayTests
public void Diagnostic_ScenarioD_CorridorWalk_PerStepChurn() public void Diagnostic_ScenarioD_CorridorWalk_PerStepChurn()
{ {
var datDir = CornerFloodReplayTests.ResolveDatDir(); var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; } if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub); var cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub);

View file

@ -110,7 +110,7 @@ public class Issue177StairDescentCameraFloodTests
public void Diagnostic_StairCellComposition_ShellVsStatics() public void Diagnostic_StairCellComposition_ShellVsStatics()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; } if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
foreach (uint low in new uint[] { 0x01C8, 0x01C4, 0x01C9, 0x0210, 0x020E, 0x01C1, 0x01C0 }) foreach (uint low in new uint[] { 0x01C8, 0x01C4, 0x01C9, 0x0210, 0x020E, 0x01C1, 0x01C0 })
@ -172,7 +172,7 @@ public class Issue177StairDescentCameraFloodTests
public void Diagnostic_RealStaircase_FineYawZoomSweep_FindKnifeEdge() public void Diagnostic_RealStaircase_FineYawZoomSweep_FindKnifeEdge()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; } if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var renderCells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub); var renderCells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub);
var engine = BuildHubEngine(dats); var engine = BuildHubEngine(dats);
@ -235,7 +235,7 @@ public class Issue177StairDescentCameraFloodTests
public void Diagnostic_FloodDepthFrom015E_VsRetail26() public void Diagnostic_FloodDepthFrom015E_VsRetail26()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; } if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var renderCells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub); var renderCells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub);
var engine = BuildHubEngine(dats); var engine = BuildHubEngine(dats);
@ -296,7 +296,7 @@ public class Issue177StairDescentCameraFloodTests
public void EdgeOnCeilingPortal_DropsUpperCell_OffPlaneReadmits() public void EdgeOnCeilingPortal_DropsUpperCell_OffPlaneReadmits()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; } if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub); var cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub);
Func<uint, LoadedCell?> lookup = id => cells.TryGetValue(id, out var c) ? c : null; Func<uint, LoadedCell?> lookup = id => cells.TryGetValue(id, out var c) ? c : null;
@ -357,7 +357,7 @@ public class Issue177StairDescentCameraFloodTests
public void Diagnostic_StaircaseSweep_EyeClearanceFromCeilingPortal() public void Diagnostic_StaircaseSweep_EyeClearanceFromCeilingPortal()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; } if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var renderCells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub); var renderCells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub);
var engine = BuildHubEngine(dats); var engine = BuildHubEngine(dats);
@ -404,7 +404,7 @@ public class Issue177StairDescentCameraFloodTests
public void Diagnostic_ParkedYawZoomSweep_StairAdmission(float px, uint pcell, string label) public void Diagnostic_ParkedYawZoomSweep_StairAdmission(float px, uint pcell, string label)
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; } if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var renderCells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub); var renderCells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub);
var engine = BuildHubEngine(dats); var engine = BuildHubEngine(dats);
@ -461,7 +461,7 @@ public class Issue177StairDescentCameraFloodTests
public void Diagnostic_Descent_RealCameraSweep_StairCellRetention() public void Diagnostic_Descent_RealCameraSweep_StairCellRetention()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; } if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var renderCells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub); var renderCells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub);

View file

@ -61,7 +61,7 @@ public class Issue181VisFlapReplayTests
public void Diagnostic_FlappingCellViewRegion_SliverOrLarge() public void Diagnostic_FlappingCellViewRegion_SliverOrLarge()
{ {
var datDir = CornerFloodReplayTests.ResolveDatDir(); var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; } if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub); var cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub);
uint flapper = FacilityHub | 0x0181u; uint flapper = FacilityHub | 0x0181u;
@ -120,7 +120,7 @@ public class Issue181VisFlapReplayTests
public void Diagnostic_SubMillimeterEyePerturbation_MustNotChangeAdmission() public void Diagnostic_SubMillimeterEyePerturbation_MustNotChangeAdmission()
{ {
var datDir = CornerFloodReplayTests.ResolveDatDir(); var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; } if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub); var cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub);
Assert.True(cells.ContainsKey(LiveRoot), "live root 0x0142 not loaded"); Assert.True(cells.ContainsKey(LiveRoot), "live root 0x0142 not loaded");

View file

@ -82,7 +82,7 @@ public class Issue181WallPressEquilibriumTests
public void Diagnostic_WallPressedCamera_EyeWanderAndViewerCellStability() public void Diagnostic_WallPressedCamera_EyeWanderAndViewerCellStability()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var (engine, _) = BuildCorridorEngine(dats); var (engine, _) = BuildCorridorEngine(dats);

View file

@ -52,7 +52,7 @@ public class Issue95DungeonFloodDiagnosticTests
_out.WriteLine("SKIP: dat dir did not resolve (ACDREAM_DAT_DIR unset and " _out.WriteLine("SKIP: dat dir did not resolve (ACDREAM_DAT_DIR unset and "
+ "%USERPROFILE%\\Documents\\Asheron's Call absent). No numbers measured."); + "%USERPROFILE%\\Documents\\Asheron's Call absent). No numbers measured.");
// Diagnostic test: do not hard-fail when dats are absent (matches sibling harnesses). // Diagnostic test: do not hard-fail when dats are absent (matches sibling harnesses).
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
_out.WriteLine($"dat dir resolved: {datDir}"); _out.WriteLine($"dat dir resolved: {datDir}");

View file

@ -52,7 +52,7 @@ public sealed class LinuxMonotonicFramePacingWaiterTests
public void LinuxWaitBlocksUntilRequestedMonotonicDeadline() public void LinuxWaitBlocksUntilRequestedMonotonicDeadline()
{ {
if (!OperatingSystem.IsLinux()) if (!OperatingSystem.IsLinux())
return; throw new PlatformNotSupportedException("Lane=Linux requires a native Linux host.");
LinuxMonotonicFramePacingWaiter waiter = LinuxMonotonicFramePacingWaiter waiter =
LinuxMonotonicFramePacingWaiter.Create(); LinuxMonotonicFramePacingWaiter.Create();
@ -75,7 +75,7 @@ public sealed class LinuxMonotonicFramePacingWaiterTests
public void LinuxWaiterRejectsUseAfterDisposal() public void LinuxWaiterRejectsUseAfterDisposal()
{ {
if (!OperatingSystem.IsLinux()) if (!OperatingSystem.IsLinux())
return; throw new PlatformNotSupportedException("Lane=Linux requires a native Linux host.");
LinuxMonotonicFramePacingWaiter waiter = LinuxMonotonicFramePacingWaiter waiter =
LinuxMonotonicFramePacingWaiter.Create(); LinuxMonotonicFramePacingWaiter.Create();

View file

@ -7,7 +7,6 @@ using DatReaderWriter;
using DatReaderWriter.DBObjs; using DatReaderWriter.DBObjs;
using DatReaderWriter.Enums; using DatReaderWriter.Enums;
using DatReaderWriter.Options; using DatReaderWriter.Options;
using Xunit.Sdk;
namespace AcDream.App.Tests.Rendering; namespace AcDream.App.Tests.Rendering;
@ -57,8 +56,8 @@ public sealed class PortalTunnelAssetTests
{ {
string? datDir = ResolveDatDir(); string? datDir = ResolveDatDir();
if (datDir is null) if (datDir is null)
throw SkipException.ForSkip( throw new InvalidOperationException(
"Installed client_portal.dat is required for the portal-space asset gate."); "Lane=InstalledDat requires client_portal.dat for the portal-space asset gate; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
uint setupDid = RetailDataIdResolver.Resolve( uint setupDid = RetailDataIdResolver.Resolve(

View file

@ -8,7 +8,6 @@ using DatReaderWriter.DBObjs;
using DatReaderWriter.Enums; using DatReaderWriter.Enums;
using DatReaderWriter.Options; using DatReaderWriter.Options;
using DatReaderWriter.Types; using DatReaderWriter.Types;
using Xunit.Sdk;
namespace AcDream.App.Tests.Rendering; namespace AcDream.App.Tests.Rendering;
@ -211,8 +210,8 @@ public sealed class RetailParticleGeometryClassifierTests
{ {
string? datDir = ResolveDatDir(); string? datDir = ResolveDatDir();
if (datDir is null) if (datDir is null)
throw SkipException.ForSkip( throw new InvalidOperationException(
"Installed client_portal.dat is required for the Armor Self asset-chain gate."); "Lane=InstalledDat requires client_portal.dat for the Armor Self asset-chain gate; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var tableResolver = new PhysicsScriptTableResolver( var tableResolver = new PhysicsScriptTableResolver(
@ -270,7 +269,8 @@ public sealed class RetailParticleGeometryClassifierTests
{ {
string? datDir = ResolveDatDir(); string? datDir = ResolveDatDir();
if (datDir is null) if (datDir is null)
throw SkipException.ForSkip("Installed client_portal.dat is required."); throw new InvalidOperationException(
"Lane=InstalledDat requires client_portal.dat; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var resolver = new PhysicsScriptTableResolver(id => dats.Get<PhysicsScriptTable>(id)); var resolver = new PhysicsScriptTableResolver(id => dats.Get<PhysicsScriptTable>(id));
@ -285,7 +285,8 @@ public sealed class RetailParticleGeometryClassifierTests
{ {
string? datDir = ResolveDatDir(); string? datDir = ResolveDatDir();
if (datDir is null) if (datDir is null)
throw SkipException.ForSkip("Installed client_portal.dat is required."); throw new InvalidOperationException(
"Lane=InstalledDat requires client_portal.dat; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var emitters = new EmitterDescRegistry(dats); var emitters = new EmitterDescRegistry(dats);

View file

@ -8,7 +8,6 @@ using AcDream.Core.Selection;
using DatReaderWriter; using DatReaderWriter;
using DatReaderWriter.DBObjs; using DatReaderWriter.DBObjs;
using DatReaderWriter.Options; using DatReaderWriter.Options;
using Xunit.Sdk;
using SysEnv = System.Environment; using SysEnv = System.Environment;
namespace AcDream.App.Tests.Rendering; namespace AcDream.App.Tests.Rendering;
@ -116,6 +115,7 @@ public sealed class RetailSelectionAssetTests
if (File.Exists(Path.Combine(conventional, "client_portal.dat"))) if (File.Exists(Path.Combine(conventional, "client_portal.dat")))
return conventional; return conventional;
throw SkipException.ForSkip("Installed client_portal.dat is required."); throw new InvalidOperationException(
"Lane=InstalledDat requires client_portal.dat; see docs/release-gate.md.");
} }
} }

View file

@ -8,7 +8,6 @@ using AcDream.Core.World;
using DatReaderWriter; using DatReaderWriter;
using DatReaderWriter.DBObjs; using DatReaderWriter.DBObjs;
using DatReaderWriter.Types; using DatReaderWriter.Types;
using Xunit.Sdk;
namespace AcDream.App.Tests.Streaming; namespace AcDream.App.Tests.Streaming;
@ -348,7 +347,8 @@ public sealed class LandblockBuildFactoryTests
{ {
string? datDirectory = ResolveDatDirectory(); string? datDirectory = ResolveDatDirectory();
if (datDirectory is null) if (datDirectory is null)
throw SkipException.ForSkip("Installed retail DATs are required."); throw new InvalidOperationException(
"Lane=PreparedPackage requires installed retail DATs; see docs/release-gate.md.");
using var dat = new BoundedTestDatCollection(datDirectory); using var dat = new BoundedTestDatCollection(datDirectory);
var bounded = (IDatReaderWriter)dat; var bounded = (IDatReaderWriter)dat;
@ -358,7 +358,8 @@ public sealed class LandblockBuildFactoryTests
Assert.True(heights.Length >= 256); Assert.True(heights.Length >= 256);
string? pakPath = ResolvePreparedPackagePath(datDirectory); string? pakPath = ResolvePreparedPackagePath(datDirectory);
if (pakPath is null) if (pakPath is null)
throw SkipException.ForSkip("Installed acdream.pak is required."); throw new InvalidOperationException(
"Lane=PreparedPackage requires a validated acdream.pak; see docs/release-gate.md.");
using var prepared = new PakPreparedAssetSource(pakPath, bounded); using var prepared = new PakPreparedAssetSource(pakPath, bounded);
var factory = new LandblockBuildFactory( var factory = new LandblockBuildFactory(
bounded, bounded,

View file

@ -80,7 +80,7 @@ public class IconComposerTests
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) if (datDir is null)
return; // dats absent (CI) — skip cleanly Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); // dats absent (CI) — skip cleanly
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
// TextureCache is not needed for the resolve path; pass a null-safe stub // TextureCache is not needed for the resolve path; pass a null-safe stub
@ -108,7 +108,7 @@ public class IconComposerTests
public void ResolveEffectDid_goldenValues_matchDat() public void ResolveEffectDid_goldenValues_matchDat()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) return; // dats absent (CI) — skip cleanly if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); // dats absent (CI) — skip cleanly
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var composer = new IconComposer(dats, null!); var composer = new IconComposer(dats, null!);
@ -134,7 +134,7 @@ public class IconComposerTests
public void TryGetEffectTile_noEffectBlack_magicalTextured() public void TryGetEffectTile_noEffectBlack_magicalTextured()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) return; // dats absent (CI) — skip cleanly if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); // dats absent (CI) — skip cleanly
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var composer = new IconComposer(dats, null!); var composer = new IconComposer(dats, null!);

View file

@ -28,7 +28,7 @@ public sealed class CharacterLayoutImportProbe
public void Selected_attribute_shows_raise_buttons_on_visible_footer_state() public void Selected_attribute_shows_raise_buttons_on_visible_footer_state()
{ {
var datDir = DatDir(); var datDir = DatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var layout = LayoutImporter.Import(dats, CharacterLayout, _ => (1u, 30, 26), null); var layout = LayoutImporter.Import(dats, CharacterLayout, _ => (1u, 30, 26), null);
@ -59,7 +59,7 @@ public sealed class CharacterLayoutImportProbe
public void Close_button_resolves_and_invokes_controller_close_callback() public void Close_button_resolves_and_invokes_controller_close_callback()
{ {
var datDir = DatDir(); var datDir = DatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var layout = LayoutImporter.Import(dats, CharacterLayout, _ => (1u, 30, 26), null); var layout = LayoutImporter.Import(dats, CharacterLayout, _ => (1u, 30, 26), null);
@ -81,7 +81,7 @@ public sealed class CharacterLayoutImportProbe
public void Footer_title_exposes_retail_append_text_palette() public void Footer_title_exposes_retail_append_text_palette()
{ {
string? datDir = DatDir(); string? datDir = DatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
ImportedLayout? layout = LayoutImporter.Import( ImportedLayout? layout = LayoutImporter.Import(

View file

@ -54,14 +54,15 @@ namespace AcDream.App.Tests.UI.Layout;
/// see its own class doc) are unaffected. /// see its own class doc) are unaffected.
/// </para> /// </para>
/// </summary> /// </summary>
[Trait("Lane", "InstalledDat")] [Trait("Lane", "Manual")]
[Trait("ManualTask", "LiveMountProbe")]
public sealed class ChatIndicatorButtonLiveMountProbeTests public sealed class ChatIndicatorButtonLiveMountProbeTests
{ {
[Fact] [Fact]
public void IndicatorButtons_ResolveNormalStateAtRest_ThroughTheLiveImportPath() public void IndicatorButtons_ResolveNormalStateAtRest_ThroughTheLiveImportPath()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1")
return; Assert.Fail("Lane=Manual live-mount probe requires ACDREAM_PROBE_LIVE_MOUNT=1.");
var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine( ?? Path.Combine(

View file

@ -1,7 +1,6 @@
using AcDream.App.UI.Layout; using AcDream.App.UI.Layout;
using DatReaderWriter; using DatReaderWriter;
using DatReaderWriter.Options; using DatReaderWriter.Options;
using Xunit.Sdk;
using SysEnv = System.Environment; using SysEnv = System.Environment;
namespace AcDream.App.Tests.UI.Layout; namespace AcDream.App.Tests.UI.Layout;
@ -53,6 +52,7 @@ public sealed class ChatOptionsDatDefaultsTests
if (File.Exists(Path.Combine(conventional, "client_portal.dat"))) if (File.Exists(Path.Combine(conventional, "client_portal.dat")))
return conventional; return conventional;
throw SkipException.ForSkip("Installed client_portal.dat is required."); throw new InvalidOperationException(
"Lane=InstalledDat requires client_portal.dat; see docs/release-gate.md.");
} }
} }

View file

@ -15,14 +15,15 @@ namespace AcDream.App.Tests.UI.Layout;
/// and 0x10000263 (swear-allegiance button). Env-gated like the other probes. /// and 0x10000263 (swear-allegiance button). Env-gated like the other probes.
/// </summary> /// </summary>
[Trait("Purpose", "Diagnostic")] [Trait("Purpose", "Diagnostic")]
[Trait("Lane", "InstalledDat")] [Trait("Lane", "Manual")]
[Trait("ManualTask", "LiveMountProbe")]
public sealed class FaPanelSlotProbeTests public sealed class FaPanelSlotProbeTests
{ {
[Fact] [Fact]
public void ProbePanelSlotTable() public void ProbePanelSlotTable()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1")
return; Assert.Fail("Lane=Manual live-mount probe requires ACDREAM_PROBE_LIVE_MOUNT=1.");
var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine( ?? Path.Combine(

View file

@ -41,7 +41,7 @@ public class InventoryFrameImportProbe
public void Paperdoll_equip_slots_resolve_to_item_lists() public void Paperdoll_equip_slots_resolve_to_item_lists()
{ {
var datDir = DatDir(); var datDir = DatDir();
if (datDir is null) return; // CI: no live dat — skip if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); // CI: no live dat — skip
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var layout = LayoutImporter.Import(dats, Frame, _ => (0u, 0, 0), null); var layout = LayoutImporter.Import(dats, Frame, _ => (0u, 0, 0), null);
@ -61,7 +61,7 @@ public class InventoryFrameImportProbe
public void Mounted_panels_sit_in_front_of_the_backdrop() public void Mounted_panels_sit_in_front_of_the_backdrop()
{ {
var datDir = DatDir(); var datDir = DatDir();
if (datDir is null) return; // CI: no live dat — skip (this is a smoke test) if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); // CI: no live dat — skip (this is a smoke test)
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var layout = LayoutImporter.Import(dats, Frame, _ => (0u, 0, 0), null); var layout = LayoutImporter.Import(dats, Frame, _ => (0u, 0, 0), null);
@ -93,7 +93,7 @@ public class InventoryFrameImportProbe
public void Close_button_resolves_and_invokes_controller_close_callback() public void Close_button_resolves_and_invokes_controller_close_callback()
{ {
var datDir = DatDir(); var datDir = DatDir();
if (datDir is null) return; // CI: no live dat - skip if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); // CI: no live dat - skip
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var layout = LayoutImporter.Import(dats, Frame, _ => (0u, 0, 0), null); var layout = LayoutImporter.Import(dats, Frame, _ => (0u, 0, 0), null);

View file

@ -754,7 +754,7 @@ public sealed class ItemAppraisalTextFormatterTests
{ {
string? datDirectory = ResolveDatDirectory(); string? datDirectory = ResolveDatDirectory();
if (datDirectory is null) if (datDirectory is null)
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = using var dats =
new AcDream.App.Tests.BoundedTestDatCollection(datDirectory); new AcDream.App.Tests.BoundedTestDatCollection(datDirectory);

View file

@ -39,7 +39,7 @@ public class ItemListCellTemplateTests
public void Inventory_lists_resolve_a_real_nongeneric_empty_sprite() public void Inventory_lists_resolve_a_real_nongeneric_empty_sprite()
{ {
var datDir = DatDir(); var datDir = DatDir();
if (datDir is null) return; // CI: no live dat — skip (smoke test) if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); // CI: no live dat — skip (smoke test)
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -62,7 +62,7 @@ public class ItemListCellTemplateTests
public void Inventory_lists_resolve_the_pinned_retail_sprites() public void Inventory_lists_resolve_the_pinned_retail_sprites()
{ {
var datDir = DatDir(); var datDir = DatDir();
if (datDir is null) return; // CI: no live dat — skip if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); // CI: no live dat — skip
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
// Pinned from the live dat + the 2026-06-22 visual gate. Contents = the 32x32 prototype's // Pinned from the live dat + the 2026-06-22 visual gate. Contents = the 32x32 prototype's
@ -78,7 +78,7 @@ public class ItemListCellTemplateTests
public void Spell_favorite_list_resolves_its_cross_layout_pinned_empty_sprite() public void Spell_favorite_list_resolves_its_cross_layout_pinned_empty_sprite()
{ {
var datDir = DatDir(); var datDir = DatDir();
if (datDir is null) return; // CI: no live dat — skip if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); // CI: no live dat — skip
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
ElementInfo infos = Assert.IsType<ElementInfo>( ElementInfo infos = Assert.IsType<ElementInfo>(
@ -98,7 +98,7 @@ public class ItemListCellTemplateTests
public void Shared_UIItem_resolves_all_ten_cooldown_overlays() public void Shared_UIItem_resolves_all_ten_cooldown_overlays()
{ {
var datDir = DatDir(); var datDir = DatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
ItemCooldownAssets? assets = ItemCooldownAssets.TryLoad(dats); ItemCooldownAssets? assets = ItemCooldownAssets.TryLoad(dats);

View file

@ -16,14 +16,15 @@ namespace AcDream.App.Tests.UI.Layout;
/// rect + caption evidence for each observation. Env-gated like the other /// rect + caption evidence for each observation. Env-gated like the other
/// live probes so CI/dat-less runs skip it. /// live probes so CI/dat-less runs skip it.
/// </summary> /// </summary>
[Trait("Lane", "InstalledDat")] [Trait("Lane", "Manual")]
[Trait("ManualTask", "LiveMountProbe")]
public sealed class KeyboardConfigLiveMountProbeTests public sealed class KeyboardConfigLiveMountProbeTests
{ {
[Fact] [Fact]
public void ProbeKeyboardLiveMount() public void ProbeKeyboardLiveMount()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1")
return; Assert.Fail("Lane=Manual live-mount probe requires ACDREAM_PROBE_LIVE_MOUNT=1.");
var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine( ?? Path.Combine(
@ -159,7 +160,7 @@ public sealed class KeyboardConfigLiveMountProbeTests
public void ProbeKeyboardFontsAndKeyNameStrings() public void ProbeKeyboardFontsAndKeyNameStrings()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1")
return; Assert.Fail("Lane=Manual live-mount probe requires ACDREAM_PROBE_LIVE_MOUNT=1.");
var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine( ?? Path.Combine(

View file

@ -26,7 +26,8 @@ namespace AcDream.App.Tests.UI.Layout;
/// </para> /// </para>
/// </summary> /// </summary>
[Trait("Purpose", "Diagnostic")] [Trait("Purpose", "Diagnostic")]
[Trait("Lane", "InstalledDat")] [Trait("Lane", "Manual")]
[Trait("ManualTask", "LiveMountProbe")]
public sealed class MapHousePanelSlotProbeTests public sealed class MapHousePanelSlotProbeTests
{ {
private const uint HostLayoutId = 0x2100006Eu; private const uint HostLayoutId = 0x2100006Eu;
@ -48,7 +49,7 @@ public sealed class MapHousePanelSlotProbeTests
public void ProbeMapHousePanelSlot() public void ProbeMapHousePanelSlot()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1")
return; Assert.Fail("Lane=Manual live-mount probe requires ACDREAM_PROBE_LIVE_MOUNT=1.");
var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine( ?? Path.Combine(

View file

@ -16,7 +16,8 @@ namespace AcDream.App.Tests.UI.Layout;
/// page controller actually resolves. Env-gated like the fixture /// page controller actually resolves. Env-gated like the fixture
/// generator so CI/dat-less runs skip it. /// generator so CI/dat-less runs skip it.
/// </summary> /// </summary>
[Trait("Lane", "InstalledDat")] [Trait("Lane", "Manual")]
[Trait("ManualTask", "LiveMountProbe")]
public sealed class OptionsPanelLiveMountProbeTests public sealed class OptionsPanelLiveMountProbeTests
{ {
[Fact] [Fact]
@ -24,7 +25,7 @@ public sealed class OptionsPanelLiveMountProbeTests
public void ProbeLiveMountShapes() public void ProbeLiveMountShapes()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1")
return; Assert.Fail("Lane=Manual live-mount probe requires ACDREAM_PROBE_LIVE_MOUNT=1.");
var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine( ?? Path.Combine(
@ -99,7 +100,7 @@ public sealed class OptionsPanelLiveMountProbeTests
public void ProbeConfigMenuChrome() public void ProbeConfigMenuChrome()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1")
return; Assert.Fail("Lane=Manual live-mount probe requires ACDREAM_PROBE_LIVE_MOUNT=1.");
var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine( ?? Path.Combine(
@ -176,7 +177,7 @@ public sealed class OptionsPanelLiveMountProbeTests
public void ProbeConfigMenuPopupChrome() public void ProbeConfigMenuPopupChrome()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1")
return; Assert.Fail("Lane=Manual live-mount probe requires ACDREAM_PROBE_LIVE_MOUNT=1.");
var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine( ?? Path.Combine(
@ -320,7 +321,7 @@ public sealed class OptionsPanelLiveMountProbeTests
public void ProbeMenuPopupSizingAndTextStyle() public void ProbeMenuPopupSizingAndTextStyle()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1")
return; Assert.Fail("Lane=Manual live-mount probe requires ACDREAM_PROBE_LIVE_MOUNT=1.");
var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine( ?? Path.Combine(
@ -452,7 +453,7 @@ public sealed class OptionsPanelLiveMountProbeTests
public void ProbeChatOpacityCaptions() public void ProbeChatOpacityCaptions()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1")
return; Assert.Fail("Lane=Manual live-mount probe requires ACDREAM_PROBE_LIVE_MOUNT=1.");
var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine( ?? Path.Combine(
@ -486,7 +487,7 @@ public sealed class OptionsPanelLiveMountProbeTests
public void ProbeFilterLabelHome() public void ProbeFilterLabelHome()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1")
return; Assert.Fail("Lane=Manual live-mount probe requires ACDREAM_PROBE_LIVE_MOUNT=1.");
var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine( ?? Path.Combine(

View file

@ -53,7 +53,7 @@ public sealed class PaperdollClickMapTests
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
"Documents", "Documents",
"Asheron's Call"); "Asheron's Call");
if (!Directory.Exists(datDir)) return; if (!Directory.Exists(datDir)) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
PaperdollClickMap map = Assert.IsType<PaperdollClickMap>(PaperdollClickMap.Load(dats)); PaperdollClickMap map = Assert.IsType<PaperdollClickMap>(PaperdollClickMap.Load(dats));

View file

@ -53,7 +53,7 @@ public class PaperdollSlotBackgroundTests
string datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") string datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
"Documents", "Asheron's Call"); "Documents", "Asheron's Call");
if (!Directory.Exists(datDir)) return; if (!Directory.Exists(datDir)) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
IReadOnlyDictionary<uint, uint> actual = PaperdollSlotBackgrounds.ResolveEmptySprites(dats); IReadOnlyDictionary<uint, uint> actual = PaperdollSlotBackgrounds.ResolveEmptySprites(dats);

View file

@ -15,7 +15,8 @@ namespace AcDream.App.Tests.UI.Layout;
/// INSTALLED DAT, so the "Height"/"Power"/"Accuracy" fix binds exactly what /// INSTALLED DAT, so the "Height"/"Power"/"Accuracy" fix binds exactly what
/// retail authors instead of guessing. /// retail authors instead of guessing.
/// </summary> /// </summary>
[Trait("Lane", "InstalledDat")] [Trait("Lane", "Manual")]
[Trait("ManualTask", "PowerbarProbe")]
public sealed class PowerbarLayoutProbeTests public sealed class PowerbarLayoutProbeTests
{ {
[Fact] [Fact]
@ -23,7 +24,7 @@ public sealed class PowerbarLayoutProbeTests
public void ProbePowerbarAuthoredStrings() public void ProbePowerbarAuthoredStrings()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_POWERBAR") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_POWERBAR") != "1")
return; Assert.Fail("Lane=Manual powerbar probe requires ACDREAM_PROBE_POWERBAR=1.");
var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine( ?? Path.Combine(
@ -44,7 +45,7 @@ public sealed class PowerbarLayoutProbeTests
public void ProbeFriendsRowTemplate() public void ProbeFriendsRowTemplate()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_POWERBAR") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_POWERBAR") != "1")
return; Assert.Fail("Lane=Manual powerbar probe requires ACDREAM_PROBE_POWERBAR=1.");
var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine( ?? Path.Combine(
@ -81,7 +82,7 @@ public sealed class PowerbarLayoutProbeTests
public void ProbeSecureTradeLayout() public void ProbeSecureTradeLayout()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_POWERBAR") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_POWERBAR") != "1")
return; Assert.Fail("Lane=Manual powerbar probe requires ACDREAM_PROBE_POWERBAR=1.");
var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine( ?? Path.Combine(
@ -114,7 +115,7 @@ public sealed class PowerbarLayoutProbeTests
public void ProbeTotalItemsTemplate() public void ProbeTotalItemsTemplate()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_POWERBAR") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_POWERBAR") != "1")
return; Assert.Fail("Lane=Manual powerbar probe requires ACDREAM_PROBE_POWERBAR=1.");
var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine( ?? Path.Combine(
@ -153,7 +154,7 @@ public sealed class PowerbarLayoutProbeTests
public void ProbeUiItemCatalog() public void ProbeUiItemCatalog()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_POWERBAR") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_POWERBAR") != "1")
return; Assert.Fail("Lane=Manual powerbar probe requires ACDREAM_PROBE_POWERBAR=1.");
var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine( ?? Path.Combine(
@ -176,7 +177,7 @@ public sealed class PowerbarLayoutProbeTests
public void ProbeCharacterSelectRowTemplate() public void ProbeCharacterSelectRowTemplate()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_POWERBAR") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_POWERBAR") != "1")
return; Assert.Fail("Lane=Manual powerbar probe requires ACDREAM_PROBE_POWERBAR=1.");
var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine( ?? Path.Combine(

View file

@ -13,6 +13,7 @@ namespace AcDream.App.Tests.UI.Layout;
/// normal test runs deterministic and dat-independent. /// normal test runs deterministic and dat-independent.
/// </summary> /// </summary>
[Trait("Lane", "Manual")] [Trait("Lane", "Manual")]
[Trait("ManualTask", "FixtureGeneration")]
public sealed class RetailLayoutFixtureGenerator public sealed class RetailLayoutFixtureGenerator
{ {
private static readonly (uint Id, string FileName)[] Layouts = private static readonly (uint Id, string FileName)[] Layouts =

View file

@ -18,14 +18,15 @@ namespace AcDream.App.Tests.UI.Layout;
/// its button→page pairing + default entry can be recorded — coordinator /// its button→page pairing + default entry can be recorded — coordinator
/// addendum, docs/research/2026-08-11-fa-panel-structure.md §10. /// addendum, docs/research/2026-08-11-fa-panel-structure.md §10.
/// </summary> /// </summary>
[Trait("Lane", "InstalledDat")] [Trait("Lane", "Manual")]
[Trait("ManualTask", "LiveMountProbe")]
public sealed class SocialPanelLiveMountProbeTests public sealed class SocialPanelLiveMountProbeTests
{ {
[Fact] [Fact]
public void ProbeLiveMountShapes() public void ProbeLiveMountShapes()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1")
return; Assert.Fail("Lane=Manual live-mount probe requires ACDREAM_PROBE_LIVE_MOUNT=1.");
var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine( ?? Path.Combine(
@ -488,7 +489,7 @@ public sealed class SocialPanelLiveMountProbeTests
public void ProbeSocialClickRouting() public void ProbeSocialClickRouting()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIVE_MOUNT") != "1")
return; Assert.Fail("Lane=Manual live-mount probe requires ACDREAM_PROBE_LIVE_MOUNT=1.");
var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") var datDir = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine( ?? Path.Combine(

View file

@ -13,7 +13,7 @@ public sealed class SpellbookRowStyleTests
string datDir = System.Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") string datDir = System.Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.UserProfile), ?? Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.UserProfile),
"Documents", "Asheron's Call"); "Documents", "Asheron's Call");
if (!Directory.Exists(datDir)) return; if (!Directory.Exists(datDir)) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
SpellbookRowStyle style = Assert.IsType<SpellbookRowStyle>( SpellbookRowStyle style = Assert.IsType<SpellbookRowStyle>(
@ -37,7 +37,7 @@ public sealed class SpellbookRowStyleTests
string datDir = System.Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR") string datDir = System.Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.UserProfile), ?? Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.UserProfile),
"Documents", "Asheron's Call"); "Documents", "Asheron's Call");
if (!Directory.Exists(datDir)) return; if (!Directory.Exists(datDir)) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
ElementInfo root = Assert.IsType<ElementInfo>(LayoutImporter.ImportInfos( ElementInfo root = Assert.IsType<ElementInfo>(LayoutImporter.ImportInfos(

View file

@ -29,7 +29,7 @@ public sealed class RetailCursorCatalogTests
{ {
string? datDir = ResolveDatDir(); string? datDir = ResolveDatDir();
if (datDir is null) if (datDir is null)
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
CursorFeedbackKind[] kinds = CursorFeedbackKind[] kinds =
@ -88,7 +88,7 @@ public sealed class RetailCursorCatalogTests
{ {
string? datDir = ResolveDatDir(); string? datDir = ResolveDatDir();
if (datDir is null) if (datDir is null)
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var resolver = new RetailCursorResolver(dats, new object()); var resolver = new RetailCursorResolver(dats, new object());

View file

@ -106,7 +106,7 @@ public sealed class SpewBoxLayoutDumpDiagnostic
if (datDir is null) if (datDir is null)
{ {
_out.WriteLine("SKIP: installed retail DAT directory is unavailable."); _out.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);

View file

@ -40,7 +40,7 @@ public sealed class UiDatFontBorderPixelTests
{ {
string? datDir = ResolveDatDir(); string? datDir = ResolveDatDir();
if (datDir is null) if (datDir is null)
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
Assert.True(dats.TryGet<Font>(fontId, out Font? font), $"Font 0x{fontId:X8} not found"); Assert.True(dats.TryGet<Font>(fontId, out Font? font), $"Font 0x{fontId:X8} not found");
@ -60,7 +60,7 @@ public sealed class UiDatFontBorderPixelTests
// correlation. Sweep the documented populated range (0x40000000-0x40000032). // correlation. Sweep the documented populated range (0x40000000-0x40000032).
string? datDir = ResolveDatDir(); string? datDir = ResolveDatDir();
if (datDir is null) if (datDir is null)
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
int checkedCount = 0; int checkedCount = 0;

View file

@ -5,7 +5,6 @@ using AcDream.App.Rendering.Gpu;
using AcDream.App.Tests.Rendering.Gpu; using AcDream.App.Tests.Rendering.Gpu;
using AcDream.App.UI; using AcDream.App.UI;
using DatReaderWriter.Types; using DatReaderWriter.Types;
using Xunit.Sdk;
namespace AcDream.App.Tests.UI; namespace AcDream.App.Tests.UI;
@ -96,7 +95,8 @@ public sealed class UiRenderContextAlphaTests
{ {
byte[]? ttf = BitmapFont.TryLoadSystemMonospaceFont(); byte[]? ttf = BitmapFont.TryLoadSystemMonospaceFont();
if (ttf is null) if (ttf is null)
throw SkipException.ForSkip("No system TTF font found for BitmapFont construction."); throw new InvalidOperationException(
"Lane=SystemFont requires a host system TTF font; see docs/release-gate.md.");
return new BitmapFont(device, ttf, pixelHeight: 16f); return new BitmapFont(device, ttf, pixelHeight: 16f);
} }

View file

@ -10,7 +10,6 @@ using AcDream.Runtime.Entities;
using DatReaderWriter; using DatReaderWriter;
using DatReaderWriter.DBObjs; using DatReaderWriter.DBObjs;
using DatReaderWriter.Options; using DatReaderWriter.Options;
using Xunit.Sdk;
namespace AcDream.App.Tests.World; namespace AcDream.App.Tests.World;
@ -155,7 +154,8 @@ public sealed class LiveEntityPresentationControllerTests
const uint magicPortal = 0x40000038u; const uint magicPortal = 0x40000038u;
string datDir = @"C:\Turbine\Asheron's Call"; string datDir = @"C:\Turbine\Asheron's Call";
if (!File.Exists(Path.Combine(datDir, "client_portal.dat"))) if (!File.Exists(Path.Combine(datDir, "client_portal.dat")))
throw SkipException.ForSkip("Installed retail DATs are required."); throw new InvalidOperationException(
"Lane=InstalledDat requires installed retail DATs; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
Setup setup = Assert.IsType<Setup>(dats.Get<Setup>(humanSetup)); Setup setup = Assert.IsType<Setup>(dats.Get<Setup>(humanSetup));

View file

@ -12,7 +12,6 @@ using DatReaderWriter;
using DatReaderWriter.DBObjs; using DatReaderWriter.DBObjs;
using DatReaderWriter.Options; using DatReaderWriter.Options;
using DatReaderWriter.Types; using DatReaderWriter.Types;
using Xunit.Sdk;
namespace AcDream.App.Tests.World; namespace AcDream.App.Tests.World;
@ -190,7 +189,8 @@ public sealed class RecallTeleportAnimationTests
{ {
string datDir = @"C:\Turbine\Asheron's Call"; string datDir = @"C:\Turbine\Asheron's Call";
if (!File.Exists(Path.Combine(datDir, "client_portal.dat"))) if (!File.Exists(Path.Combine(datDir, "client_portal.dat")))
throw SkipException.ForSkip("Installed retail DATs are required."); throw new InvalidOperationException(
"Lane=InstalledDat requires installed retail DATs; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
Setup setup = Assert.IsType<Setup>(dats.Get<Setup>(HumanSetup)); Setup setup = Assert.IsType<Setup>(dats.Get<Setup>(HumanSetup));

View file

@ -47,7 +47,7 @@ public sealed class BakeDeterminismTests : IDisposable {
[Fact] [Fact]
public void Bake_SameIdSet_DifferentThreadCounts_ByteIdenticalPaks() { public void Bake_SameIdSet_DifferentThreadCounts_ByteIdenticalPaks() {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) return; // dats absent (CI) — skip, matching suite convention if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); // dats absent (CI) — skip, matching suite convention
// Small mixed fixture: GfxObjs (incl. the #119 tricky ids), Setups // Small mixed fixture: GfxObjs (incl. the #119 tricky ids), Setups
// (door setup carries emitters -> exercises the side-staged preload // (door setup carries emitters -> exercises the side-staged preload
@ -119,7 +119,7 @@ public sealed class BakeDeterminismTests : IDisposable {
[Fact] [Fact]
public void Bake_RealDuplicateCells_ShareOneBlobAcrossLandblocksAndThreads() { public void Bake_RealDuplicateCells_ShareOneBlobAcrossLandblocksAndThreads() {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
// Full-bake discovery fixture: these eight cells span multiple // Full-bake discovery fixture: these eight cells span multiple
// landblocks but have the same complete environment/structure/surface // landblocks but have the same complete environment/structure/surface
@ -201,7 +201,7 @@ public sealed class BakeDeterminismTests : IDisposable {
{ {
string? datDir = ResolveDatDir(); string? datDir = ResolveDatDir();
if (datDir is null) if (datDir is null)
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
string destination = NewTempPakPath(); string destination = NewTempPakPath();
byte[] lastGood = [0x41, 0x43, 0x50, 0x4B, 1, 2, 3, 4]; byte[] lastGood = [0x41, 0x43, 0x50, 0x4B, 1, 2, 3, 4];

View file

@ -33,7 +33,7 @@ public sealed class Ap155StaticSpherePopulationMeasurementTests
if (datDir is null) if (datDir is null)
{ {
Console.WriteLine("SKIP: installed retail DAT directory is unavailable."); Console.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);

View file

@ -66,7 +66,7 @@ public sealed class ChargenAppearanceCatalogColorTests
if (datDir is null) if (datDir is null)
{ {
_out.WriteLine("SKIP: installed retail DAT directory is unavailable."); _out.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -94,7 +94,7 @@ public sealed class ChargenAppearanceCatalogColorTests
if (datDir is null) if (datDir is null)
{ {
_out.WriteLine("SKIP: installed retail DAT directory is unavailable."); _out.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -120,7 +120,7 @@ public sealed class ChargenAppearanceCatalogColorTests
if (datDir is null) if (datDir is null)
{ {
_out.WriteLine("SKIP: installed retail DAT directory is unavailable."); _out.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -149,7 +149,7 @@ public sealed class ChargenAppearanceCatalogColorTests
if (datDir is null) if (datDir is null)
{ {
_out.WriteLine("SKIP: installed retail DAT directory is unavailable."); _out.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -183,7 +183,7 @@ public sealed class ChargenAppearanceCatalogColorTests
if (datDir is null) if (datDir is null)
{ {
_out.WriteLine("SKIP: installed retail DAT directory is unavailable."); _out.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -216,7 +216,7 @@ public sealed class ChargenAppearanceCatalogColorTests
if (datDir is null) if (datDir is null)
{ {
_out.WriteLine("SKIP: installed retail DAT directory is unavailable."); _out.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);

View file

@ -78,7 +78,7 @@ public sealed class ChargenAppearanceCatalogInstalledDatTests
if (datDir is null) if (datDir is null)
{ {
_out.WriteLine("SKIP: installed retail DAT directory is unavailable."); _out.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -177,7 +177,7 @@ public sealed class ChargenAppearanceCatalogInstalledDatTests
if (datDir is null) if (datDir is null)
{ {
_out.WriteLine("SKIP: installed retail DAT directory is unavailable."); _out.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);

View file

@ -33,7 +33,7 @@ public sealed class ChargenTableReaderInstalledDatTests
if (datDir is null) if (datDir is null)
{ {
Console.WriteLine("SKIP: installed retail DAT directory is unavailable."); Console.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -53,7 +53,7 @@ public sealed class ChargenTableReaderInstalledDatTests
if (datDir is null) if (datDir is null)
{ {
Console.WriteLine("SKIP: installed retail DAT directory is unavailable."); Console.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -85,7 +85,7 @@ public sealed class ChargenTableReaderInstalledDatTests
if (datDir is null) if (datDir is null)
{ {
Console.WriteLine("SKIP: installed retail DAT directory is unavailable."); Console.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -125,7 +125,7 @@ public sealed class ChargenTableReaderInstalledDatTests
if (datDir is null) if (datDir is null)
{ {
Console.WriteLine("SKIP: installed retail DAT directory is unavailable."); Console.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -165,7 +165,7 @@ public sealed class ChargenTableReaderInstalledDatTests
if (datDir is null) if (datDir is null)
{ {
Console.WriteLine("SKIP: installed retail DAT directory is unavailable."); Console.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -195,7 +195,7 @@ public sealed class ChargenTableReaderInstalledDatTests
if (datDir is null) if (datDir is null)
{ {
Console.WriteLine("SKIP: installed retail DAT directory is unavailable."); Console.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -238,7 +238,7 @@ public sealed class ChargenTableReaderInstalledDatTests
if (datDir is null) if (datDir is null)
{ {
Console.WriteLine("SKIP: installed retail DAT directory is unavailable."); Console.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -298,7 +298,7 @@ public sealed class ChargenTableReaderInstalledDatTests
if (datDir is null) if (datDir is null)
{ {
Console.WriteLine("SKIP: installed retail DAT directory is unavailable."); Console.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -352,7 +352,7 @@ public sealed class ChargenTableReaderInstalledDatTests
if (datDir is null) if (datDir is null)
{ {
Console.WriteLine("SKIP: installed retail DAT directory is unavailable."); Console.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);

View file

@ -12,11 +12,11 @@ public sealed class InstalledPreparedCollisionCatalogTests
{ {
string? datDir = ResolveDatDir(); string? datDir = ResolveDatDir();
if (datDir is null) if (datDir is null)
return; Assert.Fail("Lane=PreparedPackage requires installed retail DATs and a validated acdream.pak; see docs/release-gate.md.");
string packagePath = Path.Combine(datDir, "acdream.pak"); string packagePath = Path.Combine(datDir, "acdream.pak");
if (!File.Exists(packagePath)) if (!File.Exists(packagePath))
return; Assert.Fail("Lane=PreparedPackage requires installed retail DATs and a validated acdream.pak; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
using var adapter = new DatCollectionAdapter(dats); using var adapter = new DatCollectionAdapter(dats);

View file

@ -61,7 +61,7 @@ public sealed class InstalledSetupBspPrimitiveDispatchTests
{ {
string? datDir = ContentConformanceDats.ResolveDatDir(); string? datDir = ContentConformanceDats.ResolveDatDir();
if (datDir is null) if (datDir is null)
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -240,7 +240,7 @@ public sealed class InstalledSetupBspPrimitiveDispatchTests
{ {
string? datDir = ContentConformanceDats.ResolveDatDir(); string? datDir = ContentConformanceDats.ResolveDatDir();
if (datDir is null) if (datDir is null)
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);

View file

@ -35,7 +35,7 @@ public sealed class InstalledSetupCollisionReachabilityTests
{ {
string? datDir = ContentConformanceDats.ResolveDatDir(); string? datDir = ContentConformanceDats.ResolveDatDir();
if (datDir is null) if (datDir is null)
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);

View file

@ -60,7 +60,7 @@ public sealed class Issue334NeftetFormationCellMembershipTests
{ {
string? datDir = ContentConformanceDats.ResolveDatDir(); string? datDir = ContentConformanceDats.ResolveDatDir();
if (datDir is null) if (datDir is null)
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
Assert.True( Assert.True(

View file

@ -40,7 +40,7 @@ public sealed class PakEquivalenceTests {
[Fact] [Fact]
public void LiveExtraction_MatchesPakRoundTrip_OnFixtureIdSet() { public void LiveExtraction_MatchesPakRoundTrip_OnFixtureIdSet() {
var datDir = ContentConformanceDats.ResolveDatDir(); var datDir = ContentConformanceDats.ResolveDatDir();
if (datDir is null) return; // dats absent (CI) — skip, matching suite convention if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); // dats absent (CI) — skip, matching suite convention
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
// The unified AcDream.Content.DatCollectionAdapter — same class the // The unified AcDream.Content.DatCollectionAdapter — same class the

View file

@ -22,7 +22,7 @@ public sealed class SolidColorTextureCacheTests {
[Fact] [Fact]
public void GetOrCreateSolidColorTexture_SameColor_ReturnsSameSharedArray() { public void GetOrCreateSolidColorTexture_SameColor_ReturnsSameSharedArray() {
var datDir = ContentConformanceDats.ResolveDatDir(); var datDir = ContentConformanceDats.ResolveDatDir();
if (datDir is null) return; // dats absent (CI) — skip, matching suite convention if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); // dats absent (CI) — skip, matching suite convention
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
using var adapter = new DatCollectionAdapter(dats); using var adapter = new DatCollectionAdapter(dats);
@ -46,7 +46,7 @@ public sealed class SolidColorTextureCacheTests {
[Fact] [Fact]
public void GetOrCreateSolidColorTexture_DifferentColors_ReturnDistinctArrays() { public void GetOrCreateSolidColorTexture_DifferentColors_ReturnDistinctArrays() {
var datDir = ContentConformanceDats.ResolveDatDir(); var datDir = ContentConformanceDats.ResolveDatDir();
if (datDir is null) return; // dats absent (CI) — skip, matching suite convention if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); // dats absent (CI) — skip, matching suite convention
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
using var adapter = new DatCollectionAdapter(dats); using var adapter = new DatCollectionAdapter(dats);

View file

@ -78,7 +78,7 @@ public sealed class RetailSpellMetadataProjectorTests
{ {
string? datDir = ResolveDatDir(); string? datDir = ResolveDatDir();
string? csvPath = ResolveRepoFile("docs", "research", "data", "spells.csv"); string? csvPath = ResolveRepoFile("docs", "research", "data", "spells.csv");
if (datDir is null || csvPath is null) return; if (datDir is null || csvPath is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var rawDats = new DatCollection(datDir, DatAccessType.Read); using var rawDats = new DatCollection(datDir, DatAccessType.Read);
using var dats = new DatCollectionAdapter(rawDats); using var dats = new DatCollectionAdapter(rawDats);
@ -107,7 +107,7 @@ public sealed class RetailSpellMetadataProjectorTests
{ {
string? datDir = ResolveDatDir(); string? datDir = ResolveDatDir();
string? csvPath = ResolveRepoFile("docs", "research", "data", "spells.csv"); string? csvPath = ResolveRepoFile("docs", "research", "data", "spells.csv");
if (datDir is null || csvPath is null) return; if (datDir is null || csvPath is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var rawDats = new DatCollection(datDir, DatAccessType.Read); using var rawDats = new DatCollection(datDir, DatAccessType.Read);
using var dats = new DatCollectionAdapter(rawDats); using var dats = new DatCollectionAdapter(rawDats);

View file

@ -437,7 +437,7 @@ public sealed class RetailDatLoaderTests
{ {
string? datDir = ResolveDatDirectory(); string? datDir = ResolveDatDirectory();
if (datDir is null) if (datDir is null)
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
using var boundedDats = new DatCollectionAdapter(dats); using var boundedDats = new DatCollectionAdapter(dats);

View file

@ -36,7 +36,7 @@ public class LiveHandshakeTests
public void Live_LoginRequest_ReceivesConnectRequestFromServer() public void Live_LoginRequest_ReceivesConnectRequestFromServer()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_LIVE") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_LIVE") != "1")
return; // skipped — not a failure Assert.Fail("Lane=Live requires ACDREAM_LIVE=1 and a reachable configured server."); // skipped — not a failure
var host = Environment.GetEnvironmentVariable("ACDREAM_TEST_HOST") ?? "127.0.0.1"; var host = Environment.GetEnvironmentVariable("ACDREAM_TEST_HOST") ?? "127.0.0.1";
var portStr = Environment.GetEnvironmentVariable("ACDREAM_TEST_PORT") ?? "9000"; var portStr = Environment.GetEnvironmentVariable("ACDREAM_TEST_PORT") ?? "9000";
@ -113,7 +113,7 @@ public class LiveHandshakeTests
public void Live_FullThreeWayHandshake_ReachesConnectedState() public void Live_FullThreeWayHandshake_ReachesConnectedState()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_LIVE") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_LIVE") != "1")
return; Assert.Fail("Lane=Live requires ACDREAM_LIVE=1 and a reachable configured server.");
var host = Environment.GetEnvironmentVariable("ACDREAM_TEST_HOST") ?? "127.0.0.1"; var host = Environment.GetEnvironmentVariable("ACDREAM_TEST_HOST") ?? "127.0.0.1";
var portStr = Environment.GetEnvironmentVariable("ACDREAM_TEST_PORT") ?? "9000"; var portStr = Environment.GetEnvironmentVariable("ACDREAM_TEST_PORT") ?? "9000";
@ -263,7 +263,7 @@ public class LiveHandshakeTests
public void Live_CharacterEnterWorld_ReceivesCreateObjectFlood() public void Live_CharacterEnterWorld_ReceivesCreateObjectFlood()
{ {
if (Environment.GetEnvironmentVariable("ACDREAM_LIVE") != "1") if (Environment.GetEnvironmentVariable("ACDREAM_LIVE") != "1")
return; Assert.Fail("Lane=Live requires ACDREAM_LIVE=1 and a reachable configured server.");
var host = Environment.GetEnvironmentVariable("ACDREAM_TEST_HOST") ?? "127.0.0.1"; var host = Environment.GetEnvironmentVariable("ACDREAM_TEST_HOST") ?? "127.0.0.1";
var portStr = Environment.GetEnvironmentVariable("ACDREAM_TEST_PORT") ?? "9000"; var portStr = Environment.GetEnvironmentVariable("ACDREAM_TEST_PORT") ?? "9000";

View file

@ -50,7 +50,7 @@ public sealed class EnvCellSoundEmitterInventoryTests
{ {
string? datDir = ConformanceDats.ResolveDatDir(); string? datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) if (datDir is null)
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(new DatCollectionOptions using var dats = new DatCollection(new DatCollectionOptions
{ {
@ -133,7 +133,7 @@ public sealed class EnvCellSoundEmitterInventoryTests
{ {
string? datDir = ConformanceDats.ResolveDatDir(); string? datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) if (datDir is null)
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(new DatCollectionOptions using var dats = new DatCollection(new DatCollectionOptions
{ {
@ -191,7 +191,7 @@ public sealed class EnvCellSoundEmitterInventoryTests
{ {
string? datDir = ConformanceDats.ResolveDatDir(); string? datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) if (datDir is null)
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(new DatCollectionOptions using var dats = new DatCollection(new DatCollectionOptions
{ {

View file

@ -72,7 +72,7 @@ public sealed class UiSoundTableResolutionTests
{ {
string? datDir = ConformanceDats.ResolveDatDir(); string? datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) if (datDir is null)
return; // dats absent (CI) — nothing to resolve Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); // dats absent (CI) — nothing to resolve
using var dats = new DatCollection(new DatCollectionOptions using var dats = new DatCollection(new DatCollectionOptions
{ {

View file

@ -26,7 +26,7 @@ public class CottageDoorwayCharacterizationTests
public void Characterize_CottageNeighborhood_PrintStructure() public void Characterize_CottageNeighborhood_PrintStructure()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -71,7 +71,7 @@ public class CottageDoorwayCharacterizationTests
public void Characterize_Doorway_FindInteriorPoints() public void Characterize_Doorway_FindInteriorPoints()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
foreach (var id in new[] { Vestibule0170, Room0171 }) foreach (var id in new[] { Vestibule0170, Room0171 })
@ -114,7 +114,7 @@ public class CottageDoorwayCharacterizationTests
public void Doorway_Topology_IsPinned() public void Doorway_Topology_IsPinned()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cache = new PhysicsDataCache(); var cache = new PhysicsDataCache();
@ -140,7 +140,7 @@ public class CottageDoorwayCharacterizationTests
public void Doorway_InteriorPoints_ArePinned() public void Doorway_InteriorPoints_ArePinned()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cache = new PhysicsDataCache(); var cache = new PhysicsDataCache();

View file

@ -55,7 +55,7 @@ public class DatConcurrencyStressTests
public void ConcurrentRawReads_MatchSingleThreadedGolden() public void ConcurrentRawReads_MatchSingleThreadedGolden()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) return; // dats absent (CI) — skip, matching suite convention if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); // dats absent (CI) — skip, matching suite convention
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var refs = BuildIdSet(dats); var refs = BuildIdSet(dats);
@ -83,7 +83,7 @@ public class DatConcurrencyStressTests
public void ConcurrentTypedReads_MatchSingleThreadedGolden() public void ConcurrentTypedReads_MatchSingleThreadedGolden()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) return; // dats absent (CI) — skip if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); // dats absent (CI) — skip
// FileCachingStrategy.Never: every TryGet<T> re-reads + re-unpacks from disk, // FileCachingStrategy.Never: every TryGet<T> re-reads + re-unpacks from disk,
// matching the worst-case production path and keeping the hammer honest // matching the worst-case production path and keeping the hammer honest

View file

@ -27,7 +27,7 @@ public sealed class DungeonLandblockDatProbeTests
public void Probe_Dungeon0125_vs_Holtburg_A9B4() public void Probe_Dungeon0125_vs_Holtburg_A9B4()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
foreach (uint lb in new uint[] { 0x0125u, 0xA9B4u }) foreach (uint lb in new uint[] { 0x0125u, 0xA9B4u })

View file

@ -34,7 +34,7 @@ public class FindCellListConformanceTests
public void FindCellList_DeepInsideRoom0171_Returns0171() public void FindCellList_DeepInsideRoom0171_Returns0171()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cache = LoadThresholdBuilding(dats); var cache = LoadThresholdBuilding(dats);
@ -52,7 +52,7 @@ public class FindCellListConformanceTests
public void FindCellList_DeepInsideVestibule0170_Returns0170() public void FindCellList_DeepInsideVestibule0170_Returns0170()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cache = LoadThresholdBuilding(dats); var cache = LoadThresholdBuilding(dats);
@ -76,7 +76,7 @@ public class FindCellListConformanceTests
public void FindCellList_InVestibule_SeededFromRoom_Returns0170() public void FindCellList_InVestibule_SeededFromRoom_Returns0170()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cache = LoadThresholdBuilding(dats); var cache = LoadThresholdBuilding(dats);

View file

@ -31,7 +31,7 @@ public sealed class HoltburgTorchFalloffProbeTests
public void Dump_Holtburg_StaticLight_Falloffs() public void Dump_Holtburg_StaticLight_Falloffs()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
// The meeting hall sits in the Holtburg town landblocks. Sweep a small // The meeting hall sits in the Holtburg town landblocks. Sweep a small

View file

@ -44,7 +44,7 @@ public sealed class Issue107SpawnDiagnosticTests
public void SpawnPosition_IsInside0171_NotInside0162_PickRecoversFromGoodSeed() public void SpawnPosition_IsInside0171_NotInside0162_PickRecoversFromGoodSeed()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cache = new PhysicsDataCache(); var cache = new PhysicsDataCache();
@ -91,7 +91,7 @@ public sealed class Issue107SpawnDiagnosticTests
public void SeenOutside_IsPopulated_ForGroundFloorInteriors() public void SeenOutside_IsPopulated_ForGroundFloorInteriors()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cache = new PhysicsDataCache(); var cache = new PhysicsDataCache();
@ -123,7 +123,7 @@ public sealed class Issue107SpawnDiagnosticTests
// mid-population "any cell present" disambiguator, since removed) — // mid-population "any cell present" disambiguator, since removed) —
// this test pins the hydrated-path correctness. // this test pins the hydrated-path correctness.
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cache = new PhysicsDataCache(); var cache = new PhysicsDataCache();
for (uint low = 0x0100; low <= 0x01FF; low++) for (uint low = 0x0100; low <= 0x01FF; low++)
@ -145,7 +145,7 @@ public sealed class Issue107SpawnDiagnosticTests
public void PoisonedClaim_IsADifferentBuilding_55mAway() public void PoisonedClaim_IsADifferentBuilding_55mAway()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var claim = dats.Get<DatReaderWriter.DBObjs.EnvCell>(PoisonedClaim); var claim = dats.Get<DatReaderWriter.DBObjs.EnvCell>(PoisonedClaim);

View file

@ -48,7 +48,7 @@ public sealed class Issue112MembershipTests
public void A9B3CottageGap_AtDoorway_StraddlesExitPlane_DemotesRetailFaithfully() public void A9B3CottageGap_AtDoorway_StraddlesExitPlane_DemotesRetailFaithfully()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cache = LoadLandblockInteriors(dats, 0xA9B30000u); var cache = LoadLandblockInteriors(dats, 0xA9B30000u);
@ -76,7 +76,7 @@ public sealed class Issue112MembershipTests
public void A9B3Cottage_GapBeyondStraddleDistance_KeepsCurrCell_RetailGate() public void A9B3Cottage_GapBeyondStraddleDistance_KeepsCurrCell_RetailGate()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cache = LoadLandblockInteriors(dats, 0xA9B30000u); var cache = LoadLandblockInteriors(dats, 0xA9B30000u);
@ -98,7 +98,7 @@ public sealed class Issue112MembershipTests
public void FindTransitCellsSphere_ExitPortalStraddleGate_MatchesRetail() public void FindTransitCellsSphere_ExitPortalStraddleGate_MatchesRetail()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cache = LoadLandblockInteriors(dats, 0xA9B30000u); var cache = LoadLandblockInteriors(dats, 0xA9B30000u);
@ -177,7 +177,7 @@ public sealed class Issue112MembershipTests
// interior (the transparent cottage), promoting only on touching a // interior (the transparent cottage), promoting only on touching a
// portal-adjacent cell's own volume (the captured late 0x102 flip). // portal-adjacent cell's own volume (the captured late 0x102 flip).
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cache = LoadLandblockInteriors(dats, 0xA9B30000u); var cache = LoadLandblockInteriors(dats, 0xA9B30000u);
RegisterBuildings(dats, cache, 0xA9B30000u); RegisterBuildings(dats, cache, 0xA9B30000u);
@ -201,7 +201,7 @@ public sealed class Issue112MembershipTests
// absorbing outdoor-deep-inside state the user sat in (transparent // absorbing outdoor-deep-inside state the user sat in (transparent
// cottage until randomly touching a portal-adjacent room). // cottage until randomly touching a portal-adjacent room).
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cache = LoadLandblockInteriors(dats, 0xA9B30000u); var cache = LoadLandblockInteriors(dats, 0xA9B30000u);
RegisterBuildings(dats, cache, 0xA9B30000u); RegisterBuildings(dats, cache, 0xA9B30000u);
@ -233,7 +233,7 @@ public sealed class Issue112MembershipTests
// evolving pick, and which landcells had buildings. Names the first // evolving pick, and which landcells had buildings. Names the first
// step where retail would promote vs where ours does. // step where retail would promote vs where ours does.
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cache = LoadLandblockInteriors(dats, 0xA9B30000u); var cache = LoadLandblockInteriors(dats, 0xA9B30000u);
RegisterBuildings(dats, cache, 0xA9B30000u); RegisterBuildings(dats, cache, 0xA9B30000u);
@ -278,7 +278,7 @@ public sealed class Issue112MembershipTests
// is the only container). The transparency at THIS exact spot is a // is the only container). The transparency at THIS exact spot is a
// RENDER question (outdoor root at a doorway), not membership. // RENDER question (outdoor root at a doorway), not membership.
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cache = LoadLandblockInteriors(dats, 0xA9B30000u); var cache = LoadLandblockInteriors(dats, 0xA9B30000u);
RegisterBuildings(dats, cache, 0xA9B30000u); RegisterBuildings(dats, cache, 0xA9B30000u);
@ -293,7 +293,7 @@ public sealed class Issue112MembershipTests
public void ThresholdCottage_AdjacentClaim_LaterallyRecovers_ViaStabGraph() public void ThresholdCottage_AdjacentClaim_LaterallyRecovers_ViaStabGraph()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cache = LoadLandblockInteriors(dats, 0xA9B40000u); var cache = LoadLandblockInteriors(dats, 0xA9B40000u);

View file

@ -33,7 +33,7 @@ public sealed class Issue113DoorVanishDiagnosticTests
public void DumpDoorSetup_DrawingBspCoverage() public void DumpDoorSetup_DrawingBspCoverage()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var setup = dats.Get<DatReaderWriter.DBObjs.Setup>(DoorSetupId); var setup = dats.Get<DatReaderWriter.DBObjs.Setup>(DoorSetupId);
@ -75,7 +75,7 @@ public sealed class Issue113DoorVanishDiagnosticTests
public void DumpHoltburgBuildings_OrphanGeometry() public void DumpHoltburgBuildings_OrphanGeometry()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var modelIds = new SortedSet<uint>(); var modelIds = new SortedSet<uint>();
@ -197,7 +197,7 @@ public sealed class Issue113DoorVanishDiagnosticTests
public void Diagnostic_ReplicateProductionEmission_OnPortalFills() public void Diagnostic_ReplicateProductionEmission_OnPortalFills()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
foreach (uint mid in new uint[] { 0x010014C3u, 0x01000827u }) foreach (uint mid in new uint[] { 0x010014C3u, 0x01000827u })
@ -244,7 +244,7 @@ public sealed class Issue113DoorVanishDiagnosticTests
public void DumpPortalFillSurfaceTypes() public void DumpPortalFillSurfaceTypes()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
foreach (uint mid in new uint[] { 0x010014C3u, 0x01000827u, 0x0100082Eu, 0x01000C17u }) foreach (uint mid in new uint[] { 0x010014C3u, 0x01000827u, 0x0100082Eu, 0x01000C17u })
@ -290,7 +290,7 @@ public sealed class Issue113DoorVanishDiagnosticTests
public void DumpControls_HallAndCottage() public void DumpControls_HallAndCottage()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
DumpGfxObjBspCoverage(dats, 0x010014C3u); // meeting hall shell DumpGfxObjBspCoverage(dats, 0x010014C3u); // meeting hall shell

View file

@ -42,7 +42,7 @@ public sealed class Issue113PhantomStairsDumpTests
public void DumpA9B3_Buildings_And_InteriorCells() public void DumpA9B3_Buildings_And_InteriorCells()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var lbi = dats.Get<DatLandBlockInfo>(Landblock | 0xFFFEu); var lbi = dats.Get<DatLandBlockInfo>(Landblock | 0xFFFEu);
@ -199,7 +199,7 @@ public sealed class Issue113PhantomStairsDumpTests
public void DumpA9B3_Statics_OutdoorStabs_And_ShellModel() public void DumpA9B3_Statics_OutdoorStabs_And_ShellModel()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var lbi = dats.Get<DatLandBlockInfo>(Landblock | 0xFFFEu); var lbi = dats.Get<DatLandBlockInfo>(Landblock | 0xFFFEu);
@ -292,7 +292,7 @@ public sealed class Issue113PhantomStairsDumpTests
public void Dump_Cell104_ExteriorPortalPlane_Vs_GapPoint() public void Dump_Cell104_ExteriorPortalPlane_Vs_GapPoint()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
foreach (uint low in new uint[] { 0x0104, 0x0102, 0x0105, 0x0100 }) foreach (uint low in new uint[] { 0x0104, 0x0102, 0x0105, 0x0100 })
@ -345,7 +345,7 @@ public sealed class Issue113PhantomStairsDumpTests
public void DumpAAB3_Buildings_And_StairScan() public void DumpAAB3_Buildings_And_StairScan()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
const uint lb = 0xAAB30000u; const uint lb = 0xAAB30000u;
@ -444,7 +444,7 @@ public sealed class Issue113PhantomStairsDumpTests
public void DumpAAB3_Watchtower_DoorAlignment_And_RampFaces() public void DumpAAB3_Watchtower_DoorAlignment_And_RampFaces()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
const uint lb = 0xAAB30000u; const uint lb = 0xAAB30000u;
@ -565,7 +565,7 @@ public sealed class Issue113PhantomStairsDumpTests
public void DumpAAB3_Watchtower_TopDownMap() public void DumpAAB3_Watchtower_TopDownMap()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
const uint lb = 0xAAB30000u; const uint lb = 0xAAB30000u;
@ -686,7 +686,7 @@ public sealed class Issue113PhantomStairsDumpTests
public void DumpHallModel_PolyFlagHistogram() public void DumpHallModel_PolyFlagHistogram()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
foreach (uint mid in new uint[] { 0x010014C3u, 0x01000827u }) foreach (uint mid in new uint[] { 0x010014C3u, 0x01000827u })

View file

@ -38,7 +38,7 @@ public sealed class Issue119TowerDumpTests
public void DumpTowerCellNeighbourhood() public void DumpTowerCellNeighbourhood()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var lbi = dats.Get<DatLandBlockInfo>(Landblock | 0xFFFEu); var lbi = dats.Get<DatLandBlockInfo>(Landblock | 0xFFFEu);
@ -149,7 +149,7 @@ public sealed class Issue119TowerDumpTests
public void DumpTowerStairSetups(uint setupId) public void DumpTowerStairSetups(uint setupId)
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
Assert.True(dats.Portal.TryGet<DatReaderWriter.DBObjs.Setup>(setupId, out var setup) && setup is not null, Assert.True(dats.Portal.TryGet<DatReaderWriter.DBObjs.Setup>(setupId, out var setup) && setup is not null,

View file

@ -36,7 +36,7 @@ public sealed class Issue119UpNullGfxObjDumpTests
public void DumpUpNullGfxObj(uint id) public void DumpUpNullGfxObj(uint id)
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
Assert.True(dats.Portal.TryGet<GfxObj>(id, out var gfx) && gfx is not null, Assert.True(dats.Portal.TryGet<GfxObj>(id, out var gfx) && gfx is not null,
@ -101,7 +101,7 @@ public sealed class Issue119UpNullGfxObjDumpTests
public void ShellModel_NoTexturedPolyIsDropped(uint id) public void ShellModel_NoTexturedPolyIsDropped(uint id)
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
Assert.True(dats.Portal.TryGet<GfxObj>(id, out var gfx) && gfx is not null, Assert.True(dats.Portal.TryGet<GfxObj>(id, out var gfx) && gfx is not null,

View file

@ -49,7 +49,7 @@ public sealed class StipplingSurfaceEquivalenceTests
public void NoPosStippling_Equals_UntexturedSurface_OnBuildingsAndCells() public void NoPosStippling_Equals_UntexturedSurface_OnBuildingsAndCells()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; } if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
int polysChecked = 0; int polysChecked = 0;

View file

@ -24,9 +24,9 @@ public class ThresholdDivergenceDiagnosticTests
public void Diagnose_ThresholdTransitions() public void Diagnose_ThresholdTransitions()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
var fixturePath = System.IO.Path.Combine(ConformanceDats.FixturesDir, "find-cell-list-threshold.log"); var fixturePath = System.IO.Path.Combine(ConformanceDats.FixturesDir, "find-cell-list-threshold.log");
if (!System.IO.File.Exists(fixturePath)) { _out.WriteLine("SKIP: capture pending"); return; } if (!System.IO.File.Exists(fixturePath)) { _out.WriteLine("SKIP: capture pending"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var cache = new PhysicsDataCache(); var cache = new PhysicsDataCache();

View file

@ -108,9 +108,9 @@ public class ThresholdPortalCrossingReplayTests
public void ProductionPath_IndoorCrossings_MatchRetail() public void ProductionPath_IndoorCrossings_MatchRetail()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
var fixturePath = Path.Combine(ConformanceDats.FixturesDir, "find-cell-list-threshold.log"); var fixturePath = Path.Combine(ConformanceDats.FixturesDir, "find-cell-list-threshold.log");
if (!File.Exists(fixturePath)) { _out.WriteLine("SKIP: capture pending"); return; } if (!File.Exists(fixturePath)) { _out.WriteLine("SKIP: capture pending"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var (engine, _) = BuildBuildingEngine(dats); var (engine, _) = BuildBuildingEngine(dats);

View file

@ -91,7 +91,7 @@ public sealed class RetailActionIdentityRoundTripTests
public void MappedActions_DatUnionDefaultBindings_MatchRetailDefaults() public void MappedActions_DatUnionDefaultBindings_MatchRetailDefaults()
{ {
string? datDir = Conformance.ConformanceDats.ResolveDatDir(); string? datDir = Conformance.ConformanceDats.ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir); using var dats = new DatCollection(datDir);
var source = new DatCollectionAdapter(dats); var source = new DatCollectionAdapter(dats);

View file

@ -211,7 +211,7 @@ public sealed class RetailActionMapReader_LiveDatTests
public void Read_AgainstInstalledDats_MatchesPinnedShape() public void Read_AgainstInstalledDats_MatchesPinnedShape()
{ {
string? datDir = Conformance.ConformanceDats.ResolveDatDir(); string? datDir = Conformance.ConformanceDats.ResolveDatDir();
if (datDir is null) return; // CI / no local install — skip cleanly. if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); // CI / no local install — skip cleanly.
using var dats = new DatCollection(datDir); using var dats = new DatCollection(datDir);
var source = new DatCollectionAdapter(dats); var source = new DatCollectionAdapter(dats);

View file

@ -76,7 +76,7 @@ public sealed class Ap157SortingSphereFloodMeasurementTests
if (datDir is null) if (datDir is null)
{ {
Console.WriteLine("SKIP: installed retail DAT directory is unavailable."); Console.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);

View file

@ -194,7 +194,7 @@ public sealed class BoxIntersectsCellBspDifferentialTests
{ {
string? datDirectory = ConformanceDats.ResolveDatDir(); string? datDirectory = ConformanceDats.ResolveDatDir();
if (datDirectory is null) if (datDirectory is null)
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDirectory, DatAccessType.Read); using var dats = new DatCollection(datDirectory, DatAccessType.Read);
var random = new Random(0x4230_5820); var random = new Random(0x4230_5820);

View file

@ -134,7 +134,7 @@ public class CameraCornerSealReplayTests
public void Diagnostic_DispatchTrace_LeakPath_vs_Controls() public void Diagnostic_DispatchTrace_LeakPath_vs_Controls()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var (engine, cache, envCells) = BuildBuildingEngine(dats); var (engine, cache, envCells) = BuildBuildingEngine(dats);
@ -258,7 +258,7 @@ public class CameraCornerSealReplayTests
public void ViewerSweep_ThroughOpenings_PassesWithoutCollision() public void ViewerSweep_ThroughOpenings_PassesWithoutCollision()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var (engine, _, _) = BuildBuildingEngine(dats); var (engine, _, _) = BuildBuildingEngine(dats);
@ -297,7 +297,7 @@ public class CameraCornerSealReplayTests
public void HoltburgCottageExit_ViewerSweep_AdvancesFromAlcoveToOutdoor() public void HoltburgCottageExit_ViewerSweep_AdvancesFromAlcoveToOutdoor()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var graphCache = new PhysicsDataCache(); var graphCache = new PhysicsDataCache();

View file

@ -268,7 +268,7 @@ public sealed class CellTransitFindTransitCellsBoxTests
{ {
string? datDirectory = ConformanceDats.ResolveDatDir(); string? datDirectory = ConformanceDats.ResolveDatDir();
if (datDirectory is null) if (datDirectory is null)
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDirectory, DatAccessType.Read); using var dats = new DatCollection(datDirectory, DatAccessType.Read);
var cache = new PhysicsDataCache(); var cache = new PhysicsDataCache();

View file

@ -35,7 +35,7 @@ public class CellTransitTests
public void DeepInteriorSphere_NoStraddle_AddsNoOutdoorCells() public void DeepInteriorSphere_NoStraddle_AddsNoOutdoorCells()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
// Hydrate the cells in the portal chain. // Hydrate the cells in the portal chain.
// 0xA9B4013F — deep interior cell (the old over-penetration tick) // 0xA9B4013F — deep interior cell (the old over-penetration tick)
@ -72,7 +72,7 @@ public class CellTransitTests
public void AlcoveSphere_StraddlesExitPortal_ReachesDoorOutdoorCell() public void AlcoveSphere_StraddlesExitPortal_ReachesDoorOutdoorCell()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
// The alcove cell 0xA9B40150 IS the cell with the exit portal, and // The alcove cell 0xA9B40150 IS the cell with the exit portal, and
// at this captured position the foot sphere straddles its plane // at this captured position the foot sphere straddles its plane

View file

@ -86,7 +86,7 @@ public class DoorBugTrajectoryReplayTests
public void LiveCompare_DoorOffCenterWalkthrough_Tick13558() public void LiveCompare_DoorOffCenterWalkthrough_Tick13558()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
// BR-7 / A6.P4 (2026-06-11) — FLIPPED from match-the-capture to // BR-7 / A6.P4 (2026-06-11) — FLIPPED from match-the-capture to
// assert-the-fix. The capture IS the #99 bug (live walked through: // assert-the-fix. The capture IS the #99 bug (live walked through:
@ -122,7 +122,7 @@ public class DoorBugTrajectoryReplayTests
public void LiveCompare_DoorBlocksFromOutside_Tick22760() public void LiveCompare_DoorBlocksFromOutside_Tick22760()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
// BR-7 / A6.P4 (2026-06-11) — narrowed from full-capture match to // BR-7 / A6.P4 (2026-06-11) — narrowed from full-capture match to
// the blocking invariant. The capture (the WORKING outdoor side) // the blocking invariant. The capture (the WORKING outdoor side)
@ -165,7 +165,7 @@ public class DoorBugTrajectoryReplayTests
public void Diagnostic_Tick22760_DumpEngineInternals() public void Diagnostic_Tick22760_DumpEngineInternals()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
PhysicsDiagnostics.ProbeResolveEnabled = true; PhysicsDiagnostics.ProbeResolveEnabled = true;
PhysicsDiagnostics.ProbeBuildingEnabled = true; PhysicsDiagnostics.ProbeBuildingEnabled = true;
@ -218,7 +218,7 @@ public class DoorBugTrajectoryReplayTests
public void Diagnostic_Tick13558_DumpEngineInternals() public void Diagnostic_Tick13558_DumpEngineInternals()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
PhysicsDiagnostics.ProbeResolveEnabled = true; PhysicsDiagnostics.ProbeResolveEnabled = true;
PhysicsDiagnostics.ProbeBuildingEnabled = true; PhysicsDiagnostics.ProbeBuildingEnabled = true;
@ -280,7 +280,7 @@ public class DoorBugTrajectoryReplayTests
public void FindTransitCellsSphere_IndoorExitPortal_AddsOutsideForCapturedSpherePos() public void FindTransitCellsSphere_IndoorExitPortal_AddsOutsideForCapturedSpherePos()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
// ── 1. Hydrate cell 0xA9B40150 from the real dat ──────────── // ── 1. Hydrate cell 0xA9B40150 from the real dat ────────────
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -481,7 +481,7 @@ public class DoorBugTrajectoryReplayTests
public void InsideOut_Tick3254_WithCottageWalls_ShouldBlock() public void InsideOut_Tick3254_WithCottageWalls_ShouldBlock()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
var (engine, cache) = BuildFaithfulDoorEngine(datDir); var (engine, cache) = BuildFaithfulDoorEngine(datDir);
@ -553,7 +553,7 @@ public class DoorBugTrajectoryReplayTests
public void CornerSlide_AlcoveEastToCottageNorth_ShouldBlock() public void CornerSlide_AlcoveEastToCottageNorth_ShouldBlock()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
var (engine, cache) = BuildFaithfulDoorEngine(datDir); var (engine, cache) = BuildFaithfulDoorEngine(datDir);
@ -781,7 +781,7 @@ public class DoorBugTrajectoryReplayTests
public void Geometric_DoorSlabAtSphereHeight_OverlapsInZ() public void Geometric_DoorSlabAtSphereHeight_OverlapsInZ()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
DatReaderWriter.Types.Frame partFrame; DatReaderWriter.Types.Frame partFrame;
float slabLocalZMin = float.MaxValue; float slabLocalZMin = float.MaxValue;
@ -833,7 +833,7 @@ public class DoorBugTrajectoryReplayTests
public void Directional_OutsideIn_SouthApproach_BlocksAtSlabSouthFace() public void Directional_OutsideIn_SouthApproach_BlocksAtSlabSouthFace()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
var (engine, _) = BuildFaithfulDoorEngine(datDir); var (engine, _) = BuildFaithfulDoorEngine(datDir);
@ -861,7 +861,7 @@ public class DoorBugTrajectoryReplayTests
public void Directional_InsideOut_NorthApproach_BlocksAtSlabNorthFace() public void Directional_InsideOut_NorthApproach_BlocksAtSlabNorthFace()
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
var (engine, _) = BuildFaithfulDoorEngine(datDir); var (engine, _) = BuildFaithfulDoorEngine(datDir);

View file

@ -68,7 +68,7 @@ public class DoorCollisionApparatusTests
[Fact] [Fact]
public void Apparatus_DeadCenter_FrontApproach_BlocksOnBSP() public void Apparatus_DeadCenter_FrontApproach_BlocksOnBSP()
{ {
if (!TryBuildScenario(out var ctx)) return; if (!TryBuildScenario(out var ctx)) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
// Door at world (12, 12, 0). The frame's BSP slab extends // Door at world (12, 12, 0). The frame's BSP slab extends
// entity-local Y∈[-0.009, 0.252] (poly Y range plus frame[0] offset). // entity-local Y∈[-0.009, 0.252] (poly Y range plus frame[0] offset).
@ -109,7 +109,7 @@ public class DoorCollisionApparatusTests
[Fact] [Fact]
public void Apparatus_SingleLargeTickJump_DeadCenter_StillBlocksOnBSP() public void Apparatus_SingleLargeTickJump_DeadCenter_StillBlocksOnBSP()
{ {
if (!TryBuildScenario(out var ctx)) return; if (!TryBuildScenario(out var ctx)) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
var start = new Vector3(12f, 11f, 0.5f); var start = new Vector3(12f, 11f, 0.5f);
// The full 20-tick × 0.10 m approach in ONE resolve call. // The full 20-tick × 0.10 m approach in ONE resolve call.
@ -145,7 +145,7 @@ public class DoorCollisionApparatusTests
[Fact] [Fact]
public void Apparatus_50cmOffCenter_FrontApproach_BlocksOnBSP() public void Apparatus_50cmOffCenter_FrontApproach_BlocksOnBSP()
{ {
if (!TryBuildScenario(out var ctx)) return; if (!TryBuildScenario(out var ctx)) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
// Same setup, but start 0.5 m off-center in X. Slab X range // Same setup, but start 0.5 m off-center in X. Slab X range
// is approximately [11.05, 12.97] (frame[0].X offset = -0.006). // is approximately [11.05, 12.97] (frame[0].X offset = -0.006).
@ -175,7 +175,7 @@ public class DoorCollisionApparatusTests
[Fact] [Fact]
public void Apparatus_DeadCenter_BackApproach_BlocksOnBSP() public void Apparatus_DeadCenter_BackApproach_BlocksOnBSP()
{ {
if (!TryBuildScenario(out var ctx)) return; if (!TryBuildScenario(out var ctx)) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
// Start past the door at Y=13, walk back toward -Y. // Start past the door at Y=13, walk back toward -Y.
var start = new Vector3(12f, 13f, 0.5f); var start = new Vector3(12f, 13f, 0.5f);
@ -205,7 +205,7 @@ public class DoorCollisionApparatusTests
[Fact] [Fact]
public void Apparatus_DiagnosticDump_FrontApproach() public void Apparatus_DiagnosticDump_FrontApproach()
{ {
if (!TryBuildScenario(out var ctx)) return; if (!TryBuildScenario(out var ctx)) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
PhysicsDiagnostics.ProbeResolveEnabled = true; PhysicsDiagnostics.ProbeResolveEnabled = true;
PhysicsDiagnostics.ProbeBuildingEnabled = true; PhysicsDiagnostics.ProbeBuildingEnabled = true;
@ -263,7 +263,7 @@ public class DoorCollisionApparatusTests
[Fact] [Fact]
public void Apparatus_Grounded_50cmOffCenter_FrontApproach_Blocks() public void Apparatus_Grounded_50cmOffCenter_FrontApproach_Blocks()
{ {
if (!TryBuildScenario(out var ctx)) return; if (!TryBuildScenario(out var ctx)) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
PhysicsDiagnostics.ProbeResolveEnabled = true; PhysicsDiagnostics.ProbeResolveEnabled = true;
PhysicsDiagnostics.ProbeBuildingEnabled = true; PhysicsDiagnostics.ProbeBuildingEnabled = true;

View file

@ -49,7 +49,7 @@ public class DoorSetupGfxObjInspectionTests
if (!Directory.Exists(datDir)) if (!Directory.Exists(datDir))
{ {
_out.WriteLine($"SKIP: dat directory not found at {datDir}"); _out.WriteLine($"SKIP: dat directory not found at {datDir}");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -247,7 +247,7 @@ public class DoorSetupGfxObjInspectionTests
if (!Directory.Exists(datDir)) if (!Directory.Exists(datDir))
{ {
_out.WriteLine($"SKIP: dat directory not found at {datDir}"); _out.WriteLine($"SKIP: dat directory not found at {datDir}");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -282,7 +282,7 @@ public class DoorSetupGfxObjInspectionTests
if (!Directory.Exists(datDir)) if (!Directory.Exists(datDir))
{ {
_out.WriteLine($"SKIP: dat directory not found at {datDir}"); _out.WriteLine($"SKIP: dat directory not found at {datDir}");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);

View file

@ -417,7 +417,7 @@ public sealed class FlatBspQueryDifferentialTests
{ {
string? datDirectory = ConformanceDats.ResolveDatDir(); string? datDirectory = ConformanceDats.ResolveDatDir();
if (datDirectory is null) if (datDirectory is null)
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDirectory, DatAccessType.Read); using var dats = new DatCollection(datDirectory, DatAccessType.Read);
var random = new Random(0x4934_4253); var random = new Random(0x4934_4253);

View file

@ -24,7 +24,7 @@ public sealed class FlatCollisionInstalledDatTests
if (datDir is null) if (datDir is null)
{ {
_output.WriteLine("SKIP: installed retail DAT directory is unavailable."); _output.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -118,7 +118,7 @@ public sealed class FlatCollisionInstalledDatTests
if (datDir is null) if (datDir is null)
{ {
_output.WriteLine("SKIP: installed retail DAT directory is unavailable."); _output.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);

View file

@ -34,7 +34,7 @@ public sealed class HumanoidMotionTableRootMotionTests
{ {
string? datDir = ConformanceDats.ResolveDatDir(); string? datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) if (datDir is null)
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
MotionTable table = Assert.IsType<MotionTable>(dats.Get<MotionTable>(HumanoidMotionTable)); MotionTable table = Assert.IsType<MotionTable>(dats.Get<MotionTable>(HumanoidMotionTable));
@ -49,7 +49,7 @@ public sealed class HumanoidMotionTableRootMotionTests
{ {
string? datDir = ConformanceDats.ResolveDatDir(); string? datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) if (datDir is null)
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
using var boundedDats = new DatCollectionAdapter(dats); using var boundedDats = new DatCollectionAdapter(dats);
@ -85,7 +85,7 @@ public sealed class HumanoidMotionTableRootMotionTests
{ {
string? datDir = ConformanceDats.ResolveDatDir(); string? datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) if (datDir is null)
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
MotionTable table = Assert.IsType<MotionTable>(dats.Get<MotionTable>(HumanoidMotionTable)); MotionTable table = Assert.IsType<MotionTable>(dats.Get<MotionTable>(HumanoidMotionTable));

View file

@ -284,7 +284,7 @@ public class Issue108CellarAscentViewerReplayTests
public void Diagnostic_CellarAscent_PerStepTable() public void Diagnostic_CellarAscent_PerStepTable()
{ {
var steps = RunAscent(BoomDistance, pathLagMeters: 0f); var steps = RunAscent(BoomDistance, pathLagMeters: 0f);
if (steps is null) return; if (steps is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
uint lastPlayer = 0; uint lastViewer = 0xFFFFFFFFu; var lastBranch = (ViewerBranch)(-1); uint lastPlayer = 0; uint lastViewer = 0xFFFFFFFFu; var lastBranch = (ViewerBranch)(-1);
int suspicious = 0; int suspicious = 0;
@ -309,7 +309,7 @@ public class Issue108CellarAscentViewerReplayTests
foreach (float lag in new[] { 0f, 0.30f }) foreach (float lag in new[] { 0f, 0.30f })
{ {
var steps = RunAscent(dist, lag); var steps = RunAscent(dist, lag);
if (steps is null) return; if (steps is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
int grass = steps.FindAll(s => s.EyeBelowGrade && s.ViewerOutdoorOrNull).Count; int grass = steps.FindAll(s => s.EyeBelowGrade && s.ViewerOutdoorOrNull).Count;
int okFalse = steps.FindAll(s => !s.Viewer.Sweep.Ok).Count; int okFalse = steps.FindAll(s => !s.Viewer.Sweep.Ok).Count;
int fb = steps.FindAll(s => s.Viewer.Branch != ViewerBranch.Sweep).Count; int fb = steps.FindAll(s => s.Viewer.Branch != ViewerBranch.Sweep).Count;
@ -330,7 +330,7 @@ public class Issue108CellarAscentViewerReplayTests
public void CellarAscent_ViewerStaysInterior_WhileEyeBelowGrade() public void CellarAscent_ViewerStaysInterior_WhileEyeBelowGrade()
{ {
var steps = RunAscent(BoomDistance, pathLagMeters: 0f); var steps = RunAscent(BoomDistance, pathLagMeters: 0f);
if (steps is null) return; if (steps is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
var failures = steps.FindAll(s => s.EyeBelowGrade && s.ViewerOutdoorOrNull); var failures = steps.FindAll(s => s.EyeBelowGrade && s.ViewerOutdoorOrNull);
if (failures.Count > 0) if (failures.Count > 0)

View file

@ -40,7 +40,7 @@ public class Issue137CorridorSeamInspectionTests
if (!Directory.Exists(datDir)) if (!Directory.Exists(datDir))
{ {
_out.WriteLine($"SKIP: dat directory not found at {datDir}"); _out.WriteLine($"SKIP: dat directory not found at {datDir}");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -116,7 +116,7 @@ public class Issue137CorridorSeamInspectionTests
if (!Directory.Exists(datDir)) if (!Directory.Exists(datDir))
{ {
_out.WriteLine($"SKIP: dat directory not found at {datDir}"); _out.WriteLine($"SKIP: dat directory not found at {datDir}");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -196,7 +196,7 @@ public class Issue137CorridorSeamInspectionTests
if (!Directory.Exists(datDir)) if (!Directory.Exists(datDir))
{ {
_out.WriteLine($"SKIP: dat directory not found at {datDir}"); _out.WriteLine($"SKIP: dat directory not found at {datDir}");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -228,7 +228,7 @@ public class Issue137CorridorSeamInspectionTests
if (!Directory.Exists(datDir)) if (!Directory.Exists(datDir))
{ {
_out.WriteLine($"SKIP: dat directory not found at {datDir}"); _out.WriteLine($"SKIP: dat directory not found at {datDir}");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -290,7 +290,7 @@ public class Issue137CorridorSeamInspectionTests
if (!Directory.Exists(datDir)) if (!Directory.Exists(datDir))
{ {
_out.WriteLine($"SKIP: dat directory not found at {datDir}"); _out.WriteLine($"SKIP: dat directory not found at {datDir}");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -394,7 +394,7 @@ public class Issue137CorridorSeamInspectionTests
if (!Directory.Exists(datDir)) if (!Directory.Exists(datDir))
{ {
_out.WriteLine($"SKIP: dat directory not found at {datDir}"); _out.WriteLine($"SKIP: dat directory not found at {datDir}");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -475,7 +475,7 @@ public class Issue137CorridorSeamInspectionTests
if (!Directory.Exists(datDir)) if (!Directory.Exists(datDir))
{ {
_out.WriteLine($"SKIP: dat directory not found at {datDir}"); _out.WriteLine($"SKIP: dat directory not found at {datDir}");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);

View file

@ -176,7 +176,7 @@ public class Issue137CorridorSeamReplayTests
if (datDir is null) if (datDir is null)
{ {
_out.WriteLine("SKIP: dat directory not found"); _out.WriteLine("SKIP: dat directory not found");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -265,7 +265,7 @@ public class Issue137CorridorSeamReplayTests
if (datDir is null) if (datDir is null)
{ {
_out.WriteLine("SKIP: dat directory not found"); _out.WriteLine("SKIP: dat directory not found");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -361,7 +361,7 @@ public class Issue137CorridorSeamReplayTests
if (datDir is null) if (datDir is null)
{ {
_out.WriteLine("SKIP: dat directory not found"); _out.WriteLine("SKIP: dat directory not found");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -422,7 +422,7 @@ public class Issue137CorridorSeamReplayTests
if (datDir is null) if (datDir is null)
{ {
_out.WriteLine("SKIP: dat directory not found"); _out.WriteLine("SKIP: dat directory not found");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -452,7 +452,7 @@ public class Issue137CorridorSeamReplayTests
if (datDir is null) if (datDir is null)
{ {
_out.WriteLine("SKIP: dat directory not found"); _out.WriteLine("SKIP: dat directory not found");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);

View file

@ -29,7 +29,7 @@ public sealed class Issue147ArwicBuildingsDumpTests
var datDir = Env.GetEnvironmentVariable("ACDREAM_DAT_DIR") var datDir = Env.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine(Env.GetFolderPath(Env.SpecialFolder.UserProfile), ?? Path.Combine(Env.GetFolderPath(Env.SpecialFolder.UserProfile),
"Documents", "Asheron's Call"); "Documents", "Asheron's Call");
if (!Directory.Exists(datDir)) { _out.WriteLine($"SKIP: no dats at {datDir}"); return; } if (!Directory.Exists(datDir)) { _out.WriteLine($"SKIP: no dats at {datDir}"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var info = dats.Get<LandBlockInfo>(0xC6A9FFFEu); // Arwic landblock info var info = dats.Get<LandBlockInfo>(0xC6A9FFFEu); // Arwic landblock info

View file

@ -48,7 +48,7 @@ public class Issue175HubDoorPoseInspectionTests
if (!Directory.Exists(datDir)) if (!Directory.Exists(datDir))
{ {
_out.WriteLine($"SKIP: dat directory not found at {datDir}"); _out.WriteLine($"SKIP: dat directory not found at {datDir}");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -171,7 +171,7 @@ public class Issue175HubDoorPoseInspectionTests
if (!Directory.Exists(datDir)) if (!Directory.Exists(datDir))
{ {
_out.WriteLine($"SKIP: dat directory not found at {datDir}"); _out.WriteLine($"SKIP: dat directory not found at {datDir}");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);

View file

@ -110,7 +110,7 @@ public class Issue176177SeamTransitLagTests
public void RunAcrossSeam_CellFlipPosition(int direction) public void RunAcrossSeam_CellFlipPosition(int direction)
{ {
var datDir = ResolveDatDir(); var datDir = ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; } if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var engine = BuildEngine(dats); var engine = BuildEngine(dats);
var body = GroundedBody(); var body = GroundedBody();

View file

@ -103,7 +103,7 @@ public class Issue180CorridorSweepHysteresisReplayTests
public void ClippedStop_IsTheContactPoint_NotAStepBoundary() public void ClippedStop_IsTheContactPoint_NotAStepBoundary()
{ {
var datDir = ConformanceDats.ResolveDatDir(); var datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; } if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var (engine, _) = BuildCorridorEngine(dats); var (engine, _) = BuildCorridorEngine(dats);

View file

@ -38,7 +38,7 @@ public class Issue186ConnectorCellGeometryInspectionTests
public void Dump_ConnectorCells_ShellAndCollision() public void Dump_ConnectorCells_ShellAndCollision()
{ {
var datDir = DatDir(); var datDir = DatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; } if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
foreach (uint cellId in new[] { 0xF6820116u, 0xF6820117u, 0xF6820118u }) foreach (uint cellId in new[] { 0xF6820116u, 0xF6820117u, 0xF6820118u })
@ -95,7 +95,7 @@ public class Issue186ConnectorCellGeometryInspectionTests
public void PortalSide_CentroidVsDatBit_AtGreyEye() public void PortalSide_CentroidVsDatBit_AtGreyEye()
{ {
var datDir = DatDir(); var datDir = DatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; } if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
// Live grey-pose eye (fresh HEAD capture + retail cdb trace both ~here). // Live grey-pose eye (fresh HEAD capture + retail cdb trace both ~here).

View file

@ -78,7 +78,7 @@ public class Issue188FadingDoorMotionTableInspectionTests
public void Dump_PedestalWeakSpot_MotionTable_HookContents() public void Dump_PedestalWeakSpot_MotionTable_HookContents()
{ {
var datDir = DatDir(); var datDir = DatDir();
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; } if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
const uint MotionTableId = 0x090000F9u; // live-captured from the Pedestal Weak Spot entity const uint MotionTableId = 0x090000F9u; // live-captured from the Pedestal Weak Spot entity

View file

@ -77,7 +77,7 @@ public sealed class Issue337NeftetRockGeometryInspectionTests
if (datDir is null) if (datDir is null)
{ {
_out.WriteLine("SKIP: installed retail DAT directory is unavailable."); _out.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -402,7 +402,7 @@ public sealed class Issue337NeftetRockGeometryInspectionTests
if (datDir is null) if (datDir is null)
{ {
_out.WriteLine("SKIP: installed retail DAT directory is unavailable."); _out.WriteLine("SKIP: installed retail DAT directory is unavailable.");
return; Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
} }
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
@ -554,7 +554,7 @@ public sealed class Issue337NeftetRockGeometryInspectionTests
public void TheBspQueryReturnsAHitAtThePositionTheClientFellThrough() public void TheBspQueryReturnsAHitAtThePositionTheClientFellThrough()
{ {
string? datDir = ConformanceDats.ResolveDatDir(); string? datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) return; // CI without dats — the sibling dumps skip too. if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); // CI without dats — the sibling dumps skip too.
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var info = dats.Get<LandBlockInfo>((Landblock & 0xFFFF0000u) | 0xFFFEu); var info = dats.Get<LandBlockInfo>((Landblock & 0xFFFF0000u) | 0xFFFEu);
@ -627,7 +627,7 @@ public sealed class Issue337NeftetRockGeometryInspectionTests
public void TheOldBroadphaseMeasuredToTheOriginAndSoRejectedGeometryItStoodOn() public void TheOldBroadphaseMeasuredToTheOriginAndSoRejectedGeometryItStoodOn()
{ {
string? datDir = ConformanceDats.ResolveDatDir(); string? datDir = ConformanceDats.ResolveDatDir();
if (datDir is null) return; if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md.");
using var dats = new DatCollection(datDir, DatAccessType.Read); using var dats = new DatCollection(datDir, DatAccessType.Read);
var info = dats.Get<LandBlockInfo>((Landblock & 0xFFFF0000u) | 0xFFFEu); var info = dats.Get<LandBlockInfo>((Landblock & 0xFFFF0000u) | 0xFFFEu);

Some files were not shown because too many files have changed in this diff Show more