Class ProjectWiringPlannerTests
EditMode tests for Serenity.CreateGame.Infrastructure.Editor.Wiring.ProjectWiringPlanner against real project state, with the user-content
half of every scan pinned to Serenity.CreateGame.Tests.Editor.ProjectWiringPlannerTests.ScratchFolder (Serenity.Global.Infrastructure.Editor.SerenityUserContentScan.PinForTests(System.String[])):
the project a test runs in may already own boot profiles of its own — every customer project does — so
the "no profile yet" cases establish that premise instead of assuming it. The "one profile" case
creates a disposable scratch profile outside Assets/Serenity (project-owned per
FoundationAssetOwnership.IsProjectOwnedPath) and deletes it in TearDown(), without
Addressables registration.
Inherited Members
Namespace: Serenity.CreateGame.Tests.Editor
Assembly: Serenity.CreateGame.Tests.Editor.dll
Syntax
public class ProjectWiringPlannerTests
Constructors
ProjectWiringPlannerTests()
Declaration
public ProjectWiringPlannerTests()
Methods
OneTimeTearDown()
Declaration
public void OneTimeTearDown()
PlanBootTasks_TwoSelectedSystems_ListsThemInCanonicalOrder()
Selected out of Serenity.CreateGame.Infrastructure.Editor.BootTaskCanonicalOrder order ("InstallLeaderboard" then "InstallScore" — "InstallScore" sits earlier in the canonical sequence) must still come back in canonical order: the plan is what the Summary step renders, and it must match the order Serenity.CreateGame.Infrastructure.Editor.Wiring.ProjectWiringRunner actually wires them in (canonical, not dependency/selection order — see Engram architecture/boot-task-canonical-order-in-plan).
Declaration
public void PlanBootTasks_TwoSelectedSystems_ListsThemInCanonicalOrder()
Plan_AlwaysRunsHealthCheck()
Declaration
public void Plan_AlwaysRunsHealthCheck()
Plan_GameplayModulesAndSystemsSelected_MergesBothInCanonicalOrderAndFlagsTheModules()
The gameplay modules a project ticked are boot tasks like any other: they merge with the selected systems and the whole list follows Serenity.CreateGame.Infrastructure.Editor.BootTaskCanonicalOrder, so Create seeds the profile and Reuse wires it in the order the Summary step shows.
Declaration
public void Plan_GameplayModulesAndSystemsSelected_MergesBothInCanonicalOrderAndFlagsTheModules()
Plan_NoProjectOwnedProfiles_ProfileStateIsCreate()
Declaration
public void Plan_NoProjectOwnedProfiles_ProfileStateIsCreate()
Plan_NoProjectOwnedProfiles_TargetProfilePathIsUnderTheProjectPipelineProfileFolder()
Declaration
public void Plan_NoProjectOwnedProfiles_TargetProfilePathIsUnderTheProjectPipelineProfileFolder()
Plan_NoSelectedSystems_BootTasksIsEmpty()
Declaration
public void Plan_NoSelectedSystems_BootTasksIsEmpty()
Plan_OneProjectOwnedProfile_ProfileStateIsReuseAndTargetsIt()
Declaration
public void Plan_OneProjectOwnedProfile_ProfileStateIsReuseAndTargetsIt()
Plan_PickNamesAShippedProfile_NeverResolvesToItAndStaysAmbiguous()
A SHIPPED profile among the candidates must never be treated as a valid pick — the Boot pipeline row's candidate list (Serenity.Global.Infrastructure.Editor.InitializationPipeline.InstallTaskAuthoring.FindProjectOwnedProfiles) never contains a shipped profile in the first place (its own doc comment: "a package-shipped profile is never a candidate to wire into"), so a pick naming one resolves exactly like a pick naming nothing the project actually owns — it never silently wires into Serenity.CreateGame.Infrastructure.Editor.SerenityBootTaskCatalog.NoCutscenesProfilePath in place. Two project-owned profiles are required so the pick genuinely matters (with only one, Serenity.CreateGame.Infrastructure.Editor.Wiring.ProjectWiringRules.ResolveProfileState(System.Int32,System.Boolean) would ignore the pick outright).
Declaration
public void Plan_PickNamesAShippedProfile_NeverResolvesToItAndStaysAmbiguous()
Plan_ScenesGenerationOff_BothSceneItemsReportSkip()
Declaration
public void Plan_ScenesGenerationOff_BothSceneItemsReportSkip()
Plan_ScenesOff_NeverBlocksOnMissingSceneSettings()
Scene generation turned off has nothing to resolve settings for — the same project state that blocks Plan_ScenesOnAndFoundationSettingsSystemsSelectedWithNoProjectOwnedSettings_HasBlockingErrorNamingThem() must never block a scenes-off run, which only wires the pipeline profile and boot tasks.
Declaration
public void Plan_ScenesOff_NeverBlocksOnMissingSceneSettings()
Plan_ScenesOnAndFoundationSettingsSystemsSelectedWithNoProjectOwnedSettings_HasBlockingErrorNamingThem()
This dev repo — the Serenity package itself — owns no project-owned Ui/GameMode/Menu/Modal settings clone of its own (only the shipped ones ship with the package), so selecting all four already reproduces the fresh-project shape needed here: scene generation promised with nothing of its own to wire it onto must BLOCK, per the cookbook's own contract ("a row still Missing/In Package when Create runs blocks scene generation ... rather than silently creating a second, competing copy") — never plan it and let Create silently drop it while still reporting success. The four must actually be SELECTED for this to hold — see Plan_ScenesOnAndNoneOfTheFourSettingsSystemsSelected_NeverBlocksOnThem() for why an empty selection is a different case entirely.
Declaration
public void Plan_ScenesOnAndFoundationSettingsSystemsSelectedWithNoProjectOwnedSettings_HasBlockingErrorNamingThem()
Plan_ScenesOnAndNoneOfTheFourSettingsSystemsSelected_NeverBlocksOnThem()
Deselecting a settings-carrying system (Ui/GameMode/Menu/Modal) must never block Create over a Settings row that no longer exists — scene generation needs none of their settings when none of them is selected, since SerenityCreateGameSceneGenerator writes an unselected system's installer field explicitly empty rather than reading it.
Declaration
public void Plan_ScenesOnAndNoneOfTheFourSettingsSystemsSelected_NeverBlocksOnThem()
Plan_StageWaveAndCharacterSelected_ListsCharacterWaveStageInThatOrder()
Declaration
public void Plan_StageWaveAndCharacterSelected_ListsCharacterWaveStageInThatOrder()
Plan_SystemWiredIntoAnUnpickedProfile_PlanAndInspectorBothAgreeItIsNotWiredIntoThePick()
Once a profile is resolved (a project's sole one, or — here — the one the reader picked off an otherwise-Ambiguous "Boot pipeline" row), the plan's own "already wired?" answer (AlreadyWired) and the Settings/Summary steps' own "already wired?" answer (Inspect(IReadOnlyList<SerenityInstallableSystem>, IReadOnlyList<string>)) must be computed over the SAME profile set. This fixture proves it: 'InstallLeaderboard' is wired into Serenity.CreateGame.Tests.Editor.ProjectWiringPlannerTests.ScratchProfilePath, but the reader picks Serenity.CreateGame.Tests.Editor.ProjectWiringPlannerTests.SecondScratchProfilePath — a profile that does NOT carry the task. The plan (which only checks the picked profile) must plan an Insert, and Inspect(IReadOnlyList<SerenityInstallableSystem>, IReadOnlyList<string>) asked over that SAME picked profile must agree it is NotWired — never Wired, which would make the Summary step say "will insert" and "already wired but settings not adopted" about the exact same system at once.
Declaration
public void Plan_SystemWiredIntoAnUnpickedProfile_PlanAndInspectorBothAgreeItIsNotWiredIntoThePick()
Plan_TwoProjectOwnedProfilesNoPick_BlockingErrorNamesThePickInTheSettingsStep()
W5B-11: the Settings step already lists every candidate with a Pick button, so the blocking sentence sends the author there instead of asking them to delete profiles until one is left.
Declaration
public void Plan_TwoProjectOwnedProfilesNoPick_BlockingErrorNamesThePickInTheSettingsStep()
Plan_TwoProjectOwnedProfilesNoPick_ProfileStateIsAmbiguousAndBlocks()
Several profiles is a choice, not a dead end: with no pick made yet, the plan still blocks exactly as before — the pick is what unblocks it, not the mere existence of the row's own GUI.
Declaration
public void Plan_TwoProjectOwnedProfilesNoPick_ProfileStateIsAmbiguousAndBlocks()
Plan_TwoProjectOwnedProfilesWithAPickNamingNeither_StaysAmbiguousAndBlocks()
A pick naming neither candidate (stale, or simply mistyped) must never resolve the ambiguity it does not actually answer — the plan still blocks exactly as if nothing were picked.
Declaration
public void Plan_TwoProjectOwnedProfilesWithAPickNamingNeither_StaysAmbiguousAndBlocks()
Plan_TwoProjectOwnedProfilesWithAValidPick_ProfileStateIsReuseTargetingThePick()
Declaration
public void Plan_TwoProjectOwnedProfilesWithAValidPick_ProfileStateIsReuseTargetingThePick()
Plan_WithoutGameplayModules_FlagsNoBootTaskAsAGameplayModule()
Declaration
public void Plan_WithoutGameplayModules_FlagsNoBootTaskAsAGameplayModule()
SetUp()
Declaration
public void SetUp()
TearDown()
Declaration
public void TearDown()