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.
Inherited Members
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()