Class SequencePlayerCreatorTests
EditMode tests for SequencePlayerCreator. Every test targets fixture paths under a private
temp folder — the real project's own SequencePlayer assets, if any, are never touched — and every test
passes an explicit DuplicateIdSearchFolder pinned to
Serenity.SequencePlayer.Tests.Editor.Builder.SequencePlayerCreatorTests.TempFolder so every project-wide scan is hermetic by construction. Scene placement
(CreateSequencePlayerWindow.PlaceServiceInOpenScene) is intentionally NOT covered here: it mutates
editor-scene state (creates a GameObject in whatever scene happens to be open), which is exactly the kind
of side effect these hermetic, fixture-scoped tests are built to avoid touching.
Inherited Members
Namespace: Serenity.SequencePlayer.Tests.Editor.Builder
Assembly: Serenity.SequencePlayer.Tests.Editor.dll
Syntax
public class SequencePlayerCreatorTests
Constructors
SequencePlayerCreatorTests()
Declaration
public SequencePlayerCreatorTests()
Methods
Create_ChangedDefinitionIdNotMatchingAnyExistingAssetInFolder_CreatesANewAssetInsteadOfEditing()
Declaration
public void Create_ChangedDefinitionIdNotMatchingAnyExistingAssetInFolder_CreatesANewAssetInsteadOfEditing()
Create_ExistingAssetSeededOnEverySerializedField_RestoresThemAll()
Field-by-field regression guard for the generic capture Create(Input)
now rolls back through (transaction.TrackExistingAsset), replacing the three hand-rolled
*Snapshot classes this migration deleted. Writes a distinct value into EVERY serialized field
of a real UnitySequenceDefinition via reflection — including the nested
UnitySequenceStage list ApplyDefinitionFields only ever rewrites through
UnityEditor.SerializedProperty, never by field name — forces the update run to fail via the same
planted-and-deleted-file technique Create_ExistingDefinitionFileRemovedBeforeSecondRun_RollsBackTheFullFieldSetIncludingStages()
uses, and asserts every field comes back. Proves the capture covers whatever the type declares, not a
hand-maintained field list a future field addition could silently outgrow.
Declaration
public void Create_ExistingAssetSeededOnEverySerializedField_RestoresThemAll()
Create_ExistingDefinitionFileRemovedBeforeSecondRun_RollsBackTheFullFieldSetIncludingStages()
Declaration
public void Create_ExistingDefinitionFileRemovedBeforeSecondRun_RollsBackTheFullFieldSetIncludingStages()
Create_ExistingSettingsLosesADefinition_WarnsUnlinkButLeavesTheFileOnDisk()
Declaration
public void Create_ExistingSettingsLosesADefinition_WarnsUnlinkButLeavesTheFileOnDisk()
Create_ExistingSettingsReorderedAndExtendedFailsAtItsOwnVerify_RestoresOriginalOrderAndRollsBackTheNewDefinition()
CRITICAL coverage for the settings asset's existing-asset restore, previously unreachable from this
suite. The first run creates a two-definition settings asset [seq_a, seq_b]. The second run mutates
the EXISTING settings asset through ApplySettingsFields — reordering to [seq_b, seq_a] AND
adding a brand-new third definition (seq_c) — then the settings asset's own
VerifyAssetWasWrittenToDisk fails (its file was deleted directly off disk).
ApplySettingsFields wrote a live reference to seq_c into the settings asset before the
verify-and-throw step, but transaction.Rollback() replays the settings asset's captured
transaction.TrackExistingAsset restore FIRST, undoing that reference, and only then deletes
the freshly-created seq_c asset. The assertion that seq_c's file is actually gone from disk confirms
the delete still runs on schedule once the restore has cleared the way.
Declaration
public void Create_ExistingSettingsReorderedAndExtendedFailsAtItsOwnVerify_RestoresOriginalOrderAndRollsBackTheNewDefinition()
Create_FreshRunIntoMissingFolder_CreatesTheFolderLazily()
Proves the two top-of-Create ensures that were removed are not load-bearing: with neither
the output folder nor its "Sequences" subfolder existing beforehand, a fresh run still creates
both, lazily, through the by-Id resolves. This is the only one of this pair that can actually fail
if the lazy ensure inside SettingsAssetResolution.ResolveOrCreateByIdInFolder were missing.
Declaration
public void Create_FreshRunIntoMissingFolder_CreatesTheFolderLazily()
Create_OrderIsInputOrderNotAlphabetical()
Declaration
public void Create_OrderIsInputOrderNotAlphabetical()
Create_RegisterAsAddressablesFalse_LeavesAddressablesUntouched()
Declaration
public void Create_RegisterAsAddressablesFalse_LeavesAddressablesUntouched()
Create_RegisterAsAddressablesTrue_TagsBothDefinitionsAndSettingsWithModuleSequencePlayer()
Declaration
public void Create_RegisterAsAddressablesTrue_TagsBothDefinitionsAndSettingsWithModuleSequencePlayer()
Create_ReorderingAnExistingSettings_PersistsTheNewOrder()
Declaration
public void Create_ReorderingAnExistingSettings_PersistsTheNewOrder()
Create_UpdateRunAgainstExistingAssets_CreatesNoNewFolder()
Locks the invariant the deletion relies on: once both folders already exist, an update run against the same Ids creates no new subfolder anywhere under the fixture. This test alone would not have caught a missing lazy ensure (the folders already exist from the first run) — it only guards against a regression that makes the update path write where it should not.
Declaration
public void Create_UpdateRunAgainstExistingAssets_CreatesNoNewFolder()
Create_UpdateRun_WithRowsSeededFromExistingSettings_KeepsEveryDefinition()
Proves the fix for the audit-reported data-loss bug: rows seeded via
FromSettings(UnitySequencePlayerSettings, Action<string>) (the shape CreateSequencePlayerWindow.SeedFromTarget
now uses) must round-trip through a second Create(Input) call intact.
Declaration
public void Create_UpdateRun_WithRowsSeededFromExistingSettings_KeepsEveryDefinition()
Create_UpdatingExistingAssets_PreservesTheOriginalGuids()
Declaration
public void Create_UpdatingExistingAssets_PreservesTheOriginalGuids()
Create_ValidInput_AssignsANonEmptyGuidToEachAsset()
Declaration
public void Create_ValidInput_AssignsANonEmptyGuidToEachAsset()
Create_ValidInput_CreatesDefinitionsAndOrderedSettings()
Declaration
public void Create_ValidInput_CreatesDefinitionsAndOrderedSettings()
Create_ValidInput_SetsNeedsSceneServicePlacementTrue()
Declaration
public void Create_ValidInput_SetsNeedsSceneServicePlacementTrue()
OneTimeTearDown()
The per-test deletion above goes through AssetDatabase.DeleteAsset, which stays consistent without a manual refresh between tests — flushing to disk once after the whole fixture is enough.
Declaration
public void OneTimeTearDown()
Preview_ExistingAssets_ReportsNotNewWithTheirRealPaths()
Declaration
public void Preview_ExistingAssets_ReportsNotNewWithTheirRealPaths()
Preview_NeverMutatesTheProject()
Declaration
public void Preview_NeverMutatesTheProject()
Preview_NullDefinitionEntry_SkipsItInsteadOfThrowing()
Declaration
public void Preview_NullDefinitionEntry_SkipsItInsteadOfThrowing()
Preview_ReportsStageCountPerDefinition()
Declaration
public void Preview_ReportsStageCountPerDefinition()
SetUp()
Declaration
public void SetUp()
TearDown()
Declaration
public void TearDown()
Validate_AnotherDifferentlyIdSettingsAlreadyCarriesTheLabel_WarnsAboutAmbiguity()
Declaration
public void Validate_AnotherDifferentlyIdSettingsAlreadyCarriesTheLabel_WarnsAboutAmbiguity()
Validate_AnotherSettingsExistsButIsNotLabeled_DoesNotWarnAboutAmbiguity()
Declaration
public void Validate_AnotherSettingsExistsButIsNotLabeled_DoesNotWarnAboutAmbiguity()
Validate_CaseVariantDefinitionIdInSameFolder_IsRejectedBecauseAssetFileNamesCollide()
Serenity Ids are case-sensitive, but a definition's Id also becomes its asset FILE NAME
(NamingSanitizer.FileNameSafe), and file names are NOT case-sensitive on Windows/macOS.
So 'seq_orange' and 'Seq_Orange' would collide on disk — one asset silently overwriting the other —
even though they are different, unrelated Ids at runtime. Validate(Input)
must reject this with an error (not merely warn), mirroring PrefetchPolicyCreator's own
case-insensitive uniqueness check, and Create(Input) must refuse to run
at all.
Declaration
public void Validate_CaseVariantDefinitionIdInSameFolder_IsRejectedBecauseAssetFileNamesCollide()
Validate_DuplicateDefinitionIdElsewhere_Blocks()
Declaration
public void Validate_DuplicateDefinitionIdElsewhere_Blocks()
Validate_DuplicateDefinitionIdWithinBatch_ReturnsError()
Declaration
public void Validate_DuplicateDefinitionIdWithinBatch_ReturnsError()
Validate_DuplicateSettingsIdElsewhere_Blocks()
Declaration
public void Validate_DuplicateSettingsIdElsewhere_Blocks()
Validate_DuplicateStageIdWithinDefinition_WarnsWithoutBlocking()
Deliberate deviation from the definition/settings-Id rule: a duplicate stage Id within one definition
never collides two assets (a stage is a plain list entry, not a separately resolved asset), and the
runtime (UnitySequencePlayerService.PlayDefinitionAsync) iterates stages strictly by list
position, never by Id — so this is a warning, not an error, unlike the definition/settings same-batch
Id collision above.
Declaration
public void Validate_DuplicateStageIdWithinDefinition_WarnsWithoutBlocking()
Validate_EmptyDefinitionId_ReturnsError()
Declaration
public void Validate_EmptyDefinitionId_ReturnsError()
Validate_EmptySettingsId_ReturnsError()
Declaration
public void Validate_EmptySettingsId_ReturnsError()
Validate_EmptyStageId_WarnsWithoutBlocking()
Declaration
public void Validate_EmptyStageId_WarnsWithoutBlocking()
Validate_InvalidOutputFolderPath_ReturnsError()
Declaration
public void Validate_InvalidOutputFolderPath_ReturnsError()
Validate_NullDefinitionEntry_ReturnsErrorInsteadOfThrowing()
Declaration
public void Validate_NullDefinitionEntry_ReturnsErrorInsteadOfThrowing()
Validate_NullInput_ReturnsMissingInputError()
Declaration
public void Validate_NullInput_ReturnsMissingInputError()
Validate_RowIdCollidesWithOrphanDefinitionNotReferencedBySettings_WarnsAboutOverwrite()
The other silent-overwrite gap the audit called out: a row's Id matches an on-disk definition (here, an orphan left by an earlier unlink) that is NOT referenced by the resolved settings — a row that could not have come from seeding.
Declaration
public void Validate_RowIdCollidesWithOrphanDefinitionNotReferencedBySettings_WarnsAboutOverwrite()
Validate_SameDefinitionIdInItsOwnFolder_IsExcludedFromTheDuplicateWarning()
Declaration
public void Validate_SameDefinitionIdInItsOwnFolder_IsExcludedFromTheDuplicateWarning()
Validate_SameSettingsIdInItsOwnFolder_IsExcludedFromTheDuplicateWarning()
Declaration
public void Validate_SameSettingsIdInItsOwnFolder_IsExcludedFromTheDuplicateWarning()
Validate_UpdateRun_MissingSeededDefinition_Warns()
Mirrors seeding then deleting a row: the same unlink warning Create_ExistingSettingsLosesADefinition_WarnsUnlinkButLeavesTheFileOnDisk() covers for a hand-built batch must also fire over a seeded-then-edited one.
Declaration
public void Validate_UpdateRun_MissingSeededDefinition_Warns()
Validate_ZeroDefinitions_WarnsWithoutBlocking()
Declaration
public void Validate_ZeroDefinitions_WarnsWithoutBlocking()
Validate_ZeroStagesInDefinition_WarnsWithoutBlocking()
Declaration
public void Validate_ZeroStagesInDefinition_WarnsWithoutBlocking()