logo SERENITY
Game Systems Foundation
Search Results for

    Show / Hide Table of Contents

    Class ServiceExtensionCreatorGenerationTests

    EditMode tests for Create(Input): actual file/asset generation in a temp folder, for the layered aggregate layout ({CodeLayer}/Services, Installation/Installers, Installation/Settings, Tests, root README.md) across the three ServiceExtensionCreator.Style shapes, and the try/catch rollback contract on failure. Every input uses RegisterAsAddressables = false and AppendToPipelineProfile = false so a test run never touches the project's real Addressables settings or initialization pipeline profile (project rule — see CLAUDE.md's Addressables section). Every test targets its own uniquely-named subfolder of Serenity.ServiceExtensionCreator.Tests.Editor.ServiceExtensionCreatorGenerationTests.TempFolder (via Serenity.ServiceExtensionCreator.Tests.Editor.ServiceExtensionCreatorGenerationTests.CreateTargetSubfolder(System.String)) rather than Serenity.ServiceExtensionCreator.Tests.Editor.ServiceExtensionCreatorGenerationTests.TempFolder itself — generating the SAME nested layer folder names ("Application", "Installation", "Tests") directly under a shared parent that gets deleted and recreated between every test risks a stale AssetDatabase meta-file cache from the previous test's teardown colliding with the next test's setup.

    Inheritance
    object
    MetaFileRaceGuardedFixture
    ServiceExtensionCreatorGenerationTests
    Inherited Members
    MetaFileRaceGuardedFixture.SuppressFailingLogMessagesForFixture()
    MetaFileRaceGuardedFixture.RestoreFailingLogMessages()
    MetaFileRaceGuardedFixture.SuppressFailingLogMessagesForTest()
    object.ToString()
    object.Equals(object)
    object.Equals(object, object)
    object.ReferenceEquals(object, object)
    object.GetHashCode()
    object.GetType()
    object.MemberwiseClone()
    Namespace: Serenity.ServiceExtensionCreator.Tests.Editor
    Assembly: Serenity.ServiceExtensionCreator.Tests.Editor.dll
    Syntax
    public class ServiceExtensionCreatorGenerationTests : MetaFileRaceGuardedFixture

    Constructors

    ServiceExtensionCreatorGenerationTests()

    Declaration
    public ServiceExtensionCreatorGenerationTests()

    Methods

    CreateServiceScript_SubclassOfBaseWithProtectedVirtuals_EmitsBothOverrideAccessibilities()

    The Subclass emitter must override protected virtuals alongside public ones, each restating its declared accessibility — a protected virtual base member yields protected override, never public override (which would not compile). Constructed descriptor over a fixture base, calling the public CreateServiceScript(AggregateDescriptor, Style, string, string, string, List<string>, bool) directly — Create() resolves descriptors by catalog name, which a Tests-assembly fixture never has.

    Declaration
    public void CreateServiceScript_SubclassOfBaseWithProtectedVirtuals_EmitsBothOverrideAccessibilities()

    Create_BusinessDecoratorWithPipelineReplace_GeneratesForwardingDecoratorAndReplacementTaskUnderSettings()

    Declaration
    public void Create_BusinessDecoratorWithPipelineReplace_GeneratesForwardingDecoratorAndReplacementTaskUnderSettings()

    Create_BusinessDecorator_ForwardingMembersAreVirtual()

    The Decorator's forwarding members are public virtual too — wrap once, then subclass the decorator and override only the members you care about. The constructor stays non-virtual (constructors cannot be virtual in C#; the emitter must not decorate it).

    Declaration
    public void Create_BusinessDecorator_ForwardingMembersAreVirtual()

    Create_BusinessFresh_EmitsVirtualMembersSoTheGeneratedClassIsItselfASubclassBase()

    Every member a Fresh service emits — the IService foundation triad and each interface-member stub — is public virtual, so the generated class is itself a valid subclass base: generate Fresh once, iterate by subclassing your own generated class afterwards.

    Declaration
    public void Create_BusinessFresh_EmitsVirtualMembersSoTheGeneratedClassIsItselfASubclassBase()

    Create_BusinessFresh_GeneratesInterfaceImplementationUnderApplicationLayerWithNoWiring()

    Declaration
    public void Create_BusinessFresh_GeneratesInterfaceImplementationUnderApplicationLayerWithNoWiring()

    Create_CalledTwiceWithIdenticalInput_ProducesByteIdenticalServiceSource()

    Declaration
    public void Create_CalledTwiceWithIdenticalInput_ProducesByteIdenticalServiceSource()

    Create_GeneratedSourcesUseLayeredNamespacesBuiltFromTheComposedRoot()

    Declaration
    public void Create_GeneratedSourcesUseLayeredNamespacesBuiltFromTheComposedRoot()

    Create_InfrastructureFreshCalledTwiceWithIdenticalInput_ProducesByteIdenticalServiceSource()

    Declaration
    public void Create_InfrastructureFreshCalledTwiceWithIdenticalInput_ProducesByteIdenticalServiceSource()

    Create_InfrastructureFresh_GeneratesInterfaceImplementationUnderInfrastructureLayerWithFoundationTriad()

    InfrastructureFresh is a fresh I{Agg}Service implementation, exactly like BusinessFresh, but placed under the Infrastructure code layer and with no "Unity" prefix (unlike InfrastructureSubclass) — it needs no concrete Unity service to subclass, so it is available for every aggregate, virtualized or not.

    Declaration
    public void Create_InfrastructureFresh_GeneratesInterfaceImplementationUnderInfrastructureLayerWithFoundationTriad()

    Create_InfrastructureSubclassForPlainClassBase_GeneratesForwardingConstructorAndCreateServiceFactory()

    UnityGameCameraService is a plain class whose only public constructor takes three parameters — the InfrastructureSubclass generator must emit a forwarding constructor on the subclass (so it compiles) and a CreateService factory stub on the wiring class (since the generator cannot know the real constructor arguments), per the plain-class construction contract. The factory's return type is the fully-qualified service type (every generated type now carries a real namespace — see Create_GeneratedSourcesUseLayeredNamespacesBuiltFromTheComposedRoot()), so this asserts the qualified form rather than the bare type name.

    Declaration
    public void Create_InfrastructureSubclassForPlainClassBase_GeneratesForwardingConstructorAndCreateServiceFactory()

    Create_InfrastructureSubclassWithAutoRegister_GeneratesOverrideAndInstallerUnderLayeredFolders()

    Declaration
    public void Create_InfrastructureSubclassWithAutoRegister_GeneratesOverrideAndInstallerUnderLayeredFolders()

    Create_InfrastructureSubclass_WithExplicitCanonicalBaseName_ProducesByteIdenticalOutputToDefault()

    The V1 back-compat contract for the base picker: naming the canonical base explicitly (SubclassBaseTypeName = "UnityComboService") must be indistinguishable from leaving it empty — byte-identical generated source and the same asmdef reference set.

    Declaration
    public void Create_InfrastructureSubclass_WithExplicitCanonicalBaseName_ProducesByteIdenticalOutputToDefault()

    Create_PersistenceBusinessDecorator_GeneratesForwardingDecoratorForEveryOperation()

    Persistence has no concrete UnityPersistenceService (see Discover_Persistence_IsCoreInstalledWithNoConcreteUnityService()). A Decorator around IPersistenceService must forward every one of its five async operations to _inner.

    Declaration
    public void Create_PersistenceBusinessDecorator_GeneratesForwardingDecoratorForEveryOperation()

    Create_Readme_IsNamedReadmeAndLivesAtTheTargetFolderRoot()

    Declaration
    public void Create_Readme_IsNamedReadmeAndLivesAtTheTargetFolderRoot()

    Create_ScoreBusinessFreshWithAsmdefs_ReferencesTheInterfaceSignatureAssemblies()

    The Business styles share the latent gap: IScoreService's own members also name ScoreKey/ScoreSnapshot, so a fresh implementation restates them too — the interface-signature scan must cover every style, not just InfrastructureSubclass.

    Declaration
    public void Create_ScoreBusinessFreshWithAsmdefs_ReferencesTheInterfaceSignatureAssemblies()

    Create_ScoreInfrastructureSubclassWithAsmdefs_EveryLayerReferencesTheSignatureAssemblies()

    Regression coverage for a real field-tested compile failure: a generated {X}UnityScoreService overrides members whose signatures name ScoreKey/ScoreValue/ScoreSnapshot from Serenity.Score.Domain — a DIFFERENT assembly than the interface's (Serenity.Score.Application) or the concrete's (Serenity.UnityScore.Infrastructure). The fixed V1 reference set omitted it, so every generated asmdef failed with CS0246/CS0012. All three layer asmdefs must now carry the signature-derived reference: the code layer (declares the overrides), Installation (its wiring names the generated type — refs are not transitive), and Tests (its stub names the generated type too).

    Declaration
    public void Create_ScoreInfrastructureSubclassWithAsmdefs_EveryLayerReferencesTheSignatureAssemblies()

    Create_SkipAsmdefMode_CreatesLayeredFoldersButNoAsmdefFiles()

    Declaration
    public void Create_SkipAsmdefMode_CreatesLayeredFoldersButNoAsmdefFiles()

    Create_WhenTheTargetFolderDisappearsUnderneathIt_FailsCleanlyAndLeavesNoLayerFolders()

    Declaration
    public void Create_WhenTheTargetFolderDisappearsUnderneathIt_FailsCleanlyAndLeavesNoLayerFolders()

    Create_WithAsmdefModeCreateNew_GeneratesLayeredAsmdefsWithExpectedNamesAndReferencesPlusATestsAsmdef()

    Declaration
    public void Create_WithAsmdefModeCreateNew_GeneratesLayeredAsmdefsWithExpectedNamesAndReferencesPlusATestsAsmdef()

    SetUp()

    Declaration
    public void SetUp()

    TearDown()

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