logo SERENITY
Game Systems Foundation
Search Results for

    Show / Hide Table of Contents

    Namespace Serenity.ServiceExtensionCreator.Tests.Editor

    Classes

    AggregateCatalogTests

    EditMode tests for Discover(): the reflection-based aggregate discovery that every other Service Extension Creator piece relies on. Asserts against the live project catalog rather than a fake one, since discovery is inherently a scan over loaded assemblies.

    AlreadyVirtualMethodsVirtualizerFixture

    Fixture for the already-subclass-friendly path: every public method is virtual (a patchable property remains, but property-only patches are pointless for eligibility and must not be written).

    AsmdefReferenceWriterTests

    EditMode tests for AsmdefReferenceWriter: assembly-name resolution, required-reference sets per layer, and the brand-new-asmdef writer. Every mutation happens against a temp folder created for the test — a real project asmdef is never edited, since AsmdefReferenceWriter no longer mutates existing asmdefs at all (every generated layer owns its own folder and asmdef).

    ExtensionPointCatalogTests

    EditMode tests for Discover(): the reflection-based discovery of every extension point kind beyond the I{X}Service aggregates AggregateCatalog already covers. Asserts against the live project catalog, since discovery is inherently a scan over loaded assemblies.

    ExtensionPointGenerationTests

    EditMode tests for Create(Input) across the Store/Repository/Gateway/Factory/Installer extension point kinds (Catalog V2). Mirrors ServiceExtensionCreatorGenerationTests' conventions: every input uses RegisterAsAddressables = false so a test run never touches the project's real Addressables settings, and every test targets its own uniquely-named subfolder.

    ExtensionPointValidationTests

    EditMode tests for Validate(Input) across the Store/Repository/Gateway/Factory/Installer extension point kinds (Catalog V2). Mirrors ServiceExtensionCreatorValidationTests' conventions: a single shared temp folder for the whole fixture, since Validate never writes into it — it only accepts or rejects the target folder via SerenityProjectOutputFolderRules.

    MetaFileRaceGuardedFixture

    Base fixture that suppresses Unity's log-as-failure handling for the whole fixture run. Rapid create/delete of a fixture's temp folders across many tests occasionally races an external file watcher (AV/cloud-sync) still holding a just-deleted folder's .meta file, and because AssetDatabase's underlying file I/O is not guaranteed synchronous with the C# call that triggered it, the resulting console error can surface on a later frame than the operation that caused it — suppressing per-test would leave a gap between one test's TearDown and the next test's SetUp where the delayed log lands. Real assertions in derived fixtures run normally; only the log-as-failure path Unity's test runner applies to unexpected console errors is suppressed.

    PackageCacheAssemblyDefinitionScanTests

    EditMode tests for the package-cache source of Serenity.ServiceExtensionCreator.Editor.ProjectAssemblyDefinitionIndex on its own: a package whose define constraints keep it out of compilation never reaches the compilation pipeline, so its assembly name is known only by reading its assembly definition from the package cache. The index is pointed at a scratch package cache under the project's Temp folder — outside Assets, so nothing is imported — holding a package no compiled assembly comes from.

    ProjectAssemblyDefinitionIndexTests

    EditMode tests for Serenity.ServiceExtensionCreator.Editor.ProjectAssemblyDefinitionIndex: Unity rejects a second assembly with a name any compiled assembly already has, wherever its assembly definition lives — so the index must know the assemblies compiled from registry packages, not only the ones under the project's own folders. The package-cache scan that catches a package kept out of compilation is covered on its own by PackageCacheAssemblyDefinitionScanTests.

    PropertiesOnlyVirtualizerFixture

    Fixture for the methods-only eligibility gate: patchable properties, zero methods — can never become subclass-eligible, so TryMakeSubclassFriendly(Type, out string) must refuse.

    ProtectedVirtualOnlyFixture

    Fixture whose ONLY virtual method is protected — proves the eligibility rule counts protected virtuals (see TryMakeSubclassFriendly_ClassWhoseOnlyVirtualMethodIsProtected_ReportsAlreadySubclassFriendly).

    SealedWithOverrideVirtualizerFixture

    Reproduces the reported bug: a sealed class (like BossDefeatedAction) whose only public method is an inherited override. Its override is virtual and not patchable, so the pre-fix code fell through to AggregateCatalog.HasVirtualMembers and wrongly reported "already subclass-friendly" — C# forbids inheriting a sealed class regardless of how many virtual members it exposes.

    ServiceExtensionCreatorCollisionTests

    EditMode tests for the rule that a generated extension never breaks the build of the project it lands in: a second run with the same name refuses instead of writing uniquified copies, a second extension into the same target gets its own folder so no folder ever holds two assembly definitions, an assembly name already declared anywhere in the project is refused, and no generated assembly definition ever pulls in a script the generator did not write.

    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 (tests must not pollute Addressables settings). 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.

    ServiceExtensionCreatorValidationTests

    EditMode tests for Validate(Input) and its pure preview helpers (ComposeServiceTypeName(Input) / ComposeSanitizedExtensionName(Input)). Aliased as Creator because the class name collides with its own namespace segment (Serenity.ServiceExtensionCreator.Editor.ServiceExtensionCreator). Every case that needs a real aggregate uses "Combo" (gameplay, virtualized, no InterfaceAdapters layer) from the live AggregateCatalog. Validate only reads the target folder (via Serenity.Global.Infrastructure.Editor.SerenityProjectOutputFolderRules.IsAcceptableOutputFolder(System.String), which accepts a well-formed folder whether or not it exists yet) and never writes into it, so one folder is created for the whole fixture instead of per-test — nothing here ever mutates it, and a shared folder means no repeated create/delete churn that could race an external file watcher (AV/cloud-sync).

    ServiceExtensionLayoutTests

    EditMode tests for PlanLayout(Input): the name the author typed is kept when the extension-point suffix is off, every name the extension carries derives from one root that is never the type name itself, each extension owns a child folder of the target, and the files a run writes are exactly the files its plan lists.

    ServiceExtensionRunnerEndToEndTests

    The JSON runner driven the way a command-line caller drives it: the extension-point suffix is the author's choice rather than forced, a Service-kind spec that names the wrong target field is told why, and two extensions generated one after the other into the same target folder leave a project whose assembly layout still compiles — proven on the asmdef files themselves (one per folder, unique names, every reference resolvable, no pre-existing script captured), since a headless EditMode run cannot perform the domain reload a real compile needs.

    ServiceExtensionRunnerTests

    EditMode tests for CreateFromJson(string): spec parsing, enum-error aggregation, the JSON report round trip, and the Catalog V2 extensionPointKind/extensionPointName spec fields (including their back-compat coexistence with the legacy aggregate field). ServiceExtensionSpec is internal to the runner's assembly, so specs are written here as plain JSON text — exactly what a CLI caller would produce.

    VirtualBaseForSealedVirtualizerFixture

    Base carrying the one virtual method SealedWithOverrideVirtualizerFixture overrides — a sealed class's own override still reflects as IsVirtual == true, which is exactly what made the pre-fix code mistake it for "already subclass-friendly".

    VirtualizationEngineTests

    EditMode tests for Rewrite(string, IReadOnlyList<MemberPatch>) (pure text, no IO/AssetDatabase) and CollectPatchableMembers(Type) (pure reflection over a fixture type declared below — member enumeration never goes through discovery, so a Tests-assembly fixture is a faithful subject). The engine's contract under test: anchor precisely, skip already-virtual/override/static declarations, and refuse the WHOLE rewrite on any mismatch — never partial output.

    VirtualizerEnumerationFixture

    Reflection subject for CollectPatchableMembers(Type): one member per enumeration rule — plain method, overload pair, already-virtual method, static method, plain property, virtual property, static property, indexer and event. Living in the Tests assembly is fine here: member enumeration is pure reflection and never goes through the (test-assembly-excluding) discovery.

    In this article
    © 2026 Serenity. All Rights Reserved