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.

    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.

    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.

    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).

    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