logo SERENITY
Game Systems Foundation
Search Results for

    Show / Hide Table of Contents

    Class GameSaveCreatorTests

    EditMode tests for GameSaveCreator. Every test targets a fixture UnityGameSaveSettings asset under a private temp folder via Input.SettingsAssetPath — the real project-wide single settings asset (used by the production wizard) is never touched, so these tests stay hermetic regardless of what the project already has configured. Mirrors Serenity.GameProgress.Tests.Editor.Builder.GameProgressCreatorTests.

    Inheritance
    object
    GameSaveCreatorTests
    Inherited Members
    object.ToString()
    object.Equals(object)
    object.Equals(object, object)
    object.ReferenceEquals(object, object)
    object.GetHashCode()
    object.GetType()
    object.MemberwiseClone()
    Namespace: Serenity.GameSave.Tests.Editor.Builder
    Assembly: Serenity.GameSave.Tests.Editor.dll
    Syntax
    public class GameSaveCreatorTests

    Constructors

    GameSaveCreatorTests()

    Declaration
    public GameSaveCreatorTests()

    Methods

    Create_BackendWithAddressablesRegistration_RegistersTheCreatedAssets()

    Declaration
    public void Create_BackendWithAddressablesRegistration_RegistersTheCreatedAssets()

    Create_ExistingBackend_IsNotReplacedWithoutTheFlag()

    Declaration
    public void Create_ExistingBackend_IsNotReplacedWithoutTheFlag()

    Create_ExistingBackend_IsReplacedWhenFlagIsSet()

    The flag's own on/off contract, at the assigned backend's own name/path — a rename through Replace is a different, blocking case, covered by Validate_ReplaceOnWithAssignedBackendAndAGenuinelyFreePlannedPath_ReportsAnErrorNamingTheAssignedBackend().

    Declaration
    public void Create_ExistingBackend_IsReplacedWhenFlagIsSet()

    Create_ExistingSettingsAsset_EditsInsteadOfDuplicatingTheAsset()

    Declaration
    public void Create_ExistingSettingsAsset_EditsInsteadOfDuplicatingTheAsset()

    Create_ExistingSettings_DoesNotRewriteTheTableOrCollectionName()

    Declaration
    public void Create_ExistingSettings_DoesNotRewriteTheTableOrCollectionName()

    Create_ExistingSettings_UpdatesSlotCountAndRouteCheckpointsFlag()

    Declaration
    public void Create_ExistingSettings_UpdatesSlotCountAndRouteCheckpointsFlag()

    Create_NoExistingSettingsAsset_CreatesOneAtTheGivenPath()

    Declaration
    public void Create_NoExistingSettingsAsset_CreatesOneAtTheGivenPath()

    Create_RegisterAsAddressablesFalse_LeavesAddressablesUntouched()

    Declaration
    public void Create_RegisterAsAddressablesFalse_LeavesAddressablesUntouched()

    Create_ReplaceExistingBackendAtSameName_Succeeds_ProducesOneCleanAssetWithNewConfig()

    Enables the non-destructive "Replace Existing Backend" flow at the SAME asset name (rename-to-temp): the old backend is relocated, never destroyed, until the whole run succeeds. Also switches backend KIND (Http to Sqlite) to prove the replacement can be a different concrete type at the same path.

    Declaration
    public void Create_ReplaceExistingBackendAtSameName_Succeeds_ProducesOneCleanAssetWithNewConfig()

    Create_ReplaceExistingBackendAtSameName_ThenLaterStepFails_RestoresTheOriginalBackendIntact()

    Hand-builds the exact mid-run state a same-name replace leaves behind — the original backend moved aside to a temp path (rename-to-temp, not destroyed) and a brand-new replacement created at the original path — then invokes the private RollBack directly, mirroring RollBack_RestoresBackendReferenceBeforeDeletingTheReplacementBackend() extended with the parked backend registered on the transaction. GameSaveCreator has no asset-creation step after the backend, so there is no black-box way to force a genuine later-stage failure once the replacement backend has been created.

    Declaration
    public void Create_ReplaceExistingBackendAtSameName_ThenLaterStepFails_RestoresTheOriginalBackendIntact()

    Create_ReplaceOnWithAssignedBackendAndAGenuinelyFreePlannedPath_BlocksAndCreatesNoOrphan()

    Companion to Validate_ReplaceOnWithAssignedBackendAndAGenuinelyFreePlannedPath_ReportsAnErrorNamingTheAssignedBackend(): Create(Input) must refuse the same request end to end, leaving the assigned backend untouched and creating no second, orphaned backend asset at the free path.

    Declaration
    public void Create_ReplaceOnWithAssignedBackendAndAGenuinelyFreePlannedPath_BlocksAndCreatesNoOrphan()

    Create_ReplaceOnWithAssignedBackendElsewhereAndUnrelatedAssetAtPlannedPath_BlocksAndLeavesBothAssetsIntact()

    Companion to Validate_ReplaceOnWithAssignedBackendElsewhereAndUnrelatedAssetAtPlannedPath_StillReportsCollision(): Create(Input) must refuse the same request end to end, leaving the unrelated asset byte-identical and the assigned backend untouched.

    Declaration
    public void Create_ReplaceOnWithAssignedBackendElsewhereAndUnrelatedAssetAtPlannedPath_BlocksAndLeavesBothAssetsIntact()

    Create_SettingsFolderDoesNotExistYet_CreatesTheFolderChainAndTheSettingsAsset()

    Declaration
    public void Create_SettingsFolderDoesNotExistYet_CreatesTheFolderChainAndTheSettingsAsset()

    Create_UntouchedRerunWithBackendAtItsOwnPlannedPath_Succeeds()

    Companion to Validate_UntouchedRerunWithBackendAtItsOwnPlannedPath_ReportsNoCollision(): the untouched rerun must actually succeed end to end, not merely pass validation — and must still apply the two fields the wizard's own tooltip promises are updated on rerun.

    Declaration
    public void Create_UntouchedRerunWithBackendAtItsOwnPlannedPath_Succeeds()

    Create_WithHttpBackend_CreatesAndLinksTheSharedBackendAsset()

    Declaration
    public void Create_WithHttpBackend_CreatesAndLinksTheSharedBackendAsset()

    Create_WithPlayerPrefsBackend_CreatesAndLinksAFieldlessSharedBackendAsset()

    Declaration
    public void Create_WithPlayerPrefsBackend_CreatesAndLinksAFieldlessSharedBackendAsset()

    Create_WithSqliteBackend_SetsTheDatabaseFileNameOnTheBackendAsset()

    Declaration
    public void Create_WithSqliteBackend_SetsTheDatabaseFileNameOnTheBackendAsset()

    OneTimeTearDown()

    Declaration
    public void OneTimeTearDown()

    RollBack_RestoresBackendReferenceBeforeDeletingTheReplacementBackend()

    Regression test for the rollback-ordering bug: RollBack used to delete every created asset BEFORE restoring the settings asset's prior Backend reference. Since AssetDatabase.DeleteAsset silently skips deleting an asset that a dirty in-memory object still references, deleting a newly created replacement backend while the settings asset still pointed at it stranded the backend on disk. GameSaveCreator has no asset-creation step after the backend (unlike LeaderboardCreator's View step), so there is no black-box way to force a failure once the new backend has been created and assigned; this test instead invokes the private RollBack method via reflection to reproduce the exact hazardous state directly.

    Declaration
    public void RollBack_RestoresBackendReferenceBeforeDeletingTheReplacementBackend()

    SetUp()

    Declaration
    public void SetUp()

    TearDown()

    Declaration
    public void TearDown()

    ValidateIdentity_EmptyAssetName_ReturnsError()

    Declaration
    public void ValidateIdentity_EmptyAssetName_ReturnsError()

    ValidateIdentity_SlotCountLessThanOne_ReturnsError()

    Declaration
    public void ValidateIdentity_SlotCountLessThanOne_ReturnsError()

    Validate_BackendFolderEmpty_ReturnsError()

    Declaration
    public void Validate_BackendFolderEmpty_ReturnsError()

    Validate_DatabaseBackendWithoutHostOrConnectionString_ReturnsError()

    Declaration
    public void Validate_DatabaseBackendWithoutHostOrConnectionString_ReturnsError()

    Validate_HttpBackendMissingBaseUrl_ReturnsError()

    Declaration
    public void Validate_HttpBackendMissingBaseUrl_ReturnsError()

    Validate_ReplaceOnWithAssignedBackendAndAGenuinelyFreePlannedPath_ReportsAnErrorNamingTheAssignedBackend()

    The gap a genuine-collision check alone cannot catch: Replace Existing Backend is on, a backend (A) is already assigned, and the Backend Folder / Backend Asset Name fields plan a path where NOTHING exists yet — so ValidateBackendPathCollision(UnityStructuredBackendDefinition, string, SerenityCreationValidationResult) alone sees a free path and would let Replace silently build a second, disconnected backend there, orphaning A (still on disk, never mentioned again). Only comparing the planned path against A's own asset path catches this.

    Declaration
    public void Validate_ReplaceOnWithAssignedBackendAndAGenuinelyFreePlannedPath_ReportsAnErrorNamingTheAssignedBackend()

    Validate_ReplaceOnWithAssignedBackendElsewhereAndUnrelatedAssetAtPlannedPath_StillReportsCollision()

    Reproduces the collision-bypass: a backend (A) is already assigned, Replace Existing Backend is on, and the Backend Folder / Backend Asset Name fields plan a path that belongs to an UNRELATED existing backend (B), not to A. Replace Existing Backend may only ever replace the asset actually assigned to the settings asset, at its own path — it must never let the planned-path fields point Install at a stranger's file. Both a nullness check and an identity-by-reference check would pass here (the existing backend is non-null, replace is on); only comparing the planned path against A's own asset path catches this.

    Declaration
    public void Validate_ReplaceOnWithAssignedBackendElsewhereAndUnrelatedAssetAtPlannedPath_StillReportsCollision()

    Validate_ReplaceOnWithPlannedPathACaseVariantOfTheAssignedBackendsOwnPath_ReportsNoError()

    The identity rule must not be a case-sensitive string compare on a case-insensitive file system: a planned path that differs from the assigned backend's own path only by letter case names the very same file, and must never be reported as a collision.

    Declaration
    public void Validate_ReplaceOnWithPlannedPathACaseVariantOfTheAssignedBackendsOwnPath_ReportsNoError()

    Validate_UnrelatedAssetAtPlannedBackendPathWithNoExistingBackend_StillReportsCollision()

    A genuine collision — an unrelated asset sitting at the planned backend path while the settings asset has no backend assigned yet — must still block, proving the fix narrows the check rather than removing it.

    Declaration
    public void Validate_UnrelatedAssetAtPlannedBackendPathWithNoExistingBackend_StillReportsCollision()

    Validate_UntouchedRerunWithBackendAtItsOwnPlannedPath_ReportsNoCollision()

    The production wizard recomputes BackendFolderPath/BackendAssetName from the same AssetName on every run, so a completely untouched rerun of a settings asset that already carries a backend plans the IDENTICAL backend path the original run wrote to. That path legitimately exists on disk — it is the very backend already correctly assigned — so it must never be reported as a colliding "asset already exists" error, and the Update primary action must stay available without the reader ever touching Replace Existing Backend. Mirrors GameProgressCreatorTests.Validate_UntouchedRerunWithBackendAtItsOwnPlannedPath_ReportsNoCollision.

    Declaration
    public void Validate_UntouchedRerunWithBackendAtItsOwnPlannedPath_ReportsNoCollision()
    In this article
    © 2026 Serenity. All Rights Reserved