Skip to content

Implement StrategyProvider-based strategy provision for SomeConfig #35

Description

@MessiasLima

Description

Implement the StrategyProvider design from the #16 spike to decouple strategy definitions from SomeConfig and the resolver chain. Today every new strategy must be manually wired into 5 files (SomeConfig.kt, FixtureContext.kt, CustomFactoryResolver.kt, buildResolvers(), and each consuming resolver). After this change, adding a new strategy requires only implementing the Strategy marker interface and calling config.strategy(strategy).

This removes the maintenance bottleneck detailed in #16 and allows users to register custom strategies without modifying library code.

  • Scope and constraints

    • Introduce Strategy marker interface and StrategyProvider
    • Update SomeConfig, FixtureContext, CustomFactoryResolver, and all 6 strategy-consuming resolvers
    • Rename the existing SomeConfig.register() to factory() to differentiate factory registration from strategy registration
    • Update all affected unit tests and documentation (root AGENTS.md, resolver ordering docs, and inline KDoc in public API classes)
    • Migration is considered a breaking change — user factories that access nullableStrategy, stringStrategy, or collectionStrategy from FixtureContext must be updated to use strategyProvider[<Type>::class]
  • References

    • Design spike: Spike: Design a scalable strategy provision mechanism for SomeConfig #16
    • Current files: SomeConfig.kt:39-41 (hardcoded properties), SomeConfig.kt:53-66 (manual copy), SomeConfig.kt:71-103 (manual resolver wiring), FixtureContext.kt:13-19 (explicit strategy properties), CustomFactoryResolver.kt:13-18 (3 strategy params solely to build FixtureContext)

Acceptance criteria

  • A Strategy marker interface exists at dev.appoutlet.some.config.Strategy
  • NullableStrategy, StringStrategy, and CollectionStrategy extend Strategy
  • A StrategyProvider interface exists at dev.appoutlet.some.core.StrategyProvider with operator fun <T : Strategy> get(key: KClass<T>): T
  • SomeConfig implements StrategyProvider via an internal map pre-populated with the three default strategies, and exposes fun <T : Strategy> strategy(strategy: T)
  • SomeConfig.register(kClass, factory) renamed to SomeConfig.factory(kClass, factory) to differentiate from strategy registration
  • SomeConfig.copy() no longer includes nullableStrategy, stringStrategy, or collectionStrategy as explicit parameters
  • FixtureContext contains a single strategyProvider: StrategyProvider property instead of the three named strategy properties
  • Each strategy-consuming resolver (NullableResolver, StringResolver, ListResolver, SetResolver, MapResolver, ArrayResolver) accepts a StrategyProvider constructor parameter and retrieves its strategy via strategyProvider[<StrategyType>::class]
  • CustomFactoryResolver accepts a single StrategyProvider instead of three individual strategy params
  • SomeConfig.buildResolvers() passes a single StrategyProvider (typically this) to resolvers instead of individual strategy params
  • A user can call config { strategy(MyCustomStrategy()) } and a custom resolver can retrieve it via some.resolvers or FixtureContext.strategyProvider
  • All affected unit tests updated to construct resolvers with StrategyProvider, use strategyProvider[<Type>::class] in FixtureContext assertions, and use factory() instead of register()
  • AGENTS.md updated to reflect the new strategy registration and factory registration patterns
  • Resolver ordering documentation updated if the order comments in buildResolvers() change
  • KDoc on SomeConfig, FixtureContext, and CustomFactoryResolver updated to document the new StrategyProvider usage
  • ./gradlew build passes

Additional information

Files to change (~14):

  1. New file: config/Strategy.ktStrategy marker interface
  2. New file: core/StrategyProvider.ktStrategyProvider interface
  3. config/SomeConfig.kt — implement StrategyProvider, remove strategy properties from data class and copy(), add strategy(), rename register() to factory(), update buildResolvers()
  4. config/NullableStrategy.kt — extend Strategy
  5. config/StringStrategy.kt — extend Strategy
  6. config/CollectionStrategy.kt — extend Strategy
  7. core/FixtureContext.kt — replace 3 strategy properties with single strategyProvider
  8. resolver/CustomFactoryResolver.kt — accept StrategyProvider instead of 3 params
  9. resolver/NullableResolver.kt — accept StrategyProvider instead of NullableStrategy
  10. resolver/StringResolver.kt — accept StrategyProvider instead of StringStrategy
  11. resolver/ListResolver.kt, SetResolver.kt, MapResolver.kt, ArrayResolver.kt — accept StrategyProvider instead of CollectionStrategy
  12. Test files for each changed resolver — update constructor calls and FixtureContext usage
  13. SomeConfig.kt, FixtureContext.kt, CustomFactoryResolver.kt — KDoc updates
  14. AGENTS.md — strategy and factory registration pattern docs

Metadata

Metadata

Assignees

No one assigned

    Labels

    julesJules lives

    Projects

    Status
    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions