You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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]
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):
New file: config/Strategy.kt — Strategy marker interface
New file: core/StrategyProvider.kt — StrategyProvider interface
config/SomeConfig.kt — implement StrategyProvider, remove strategy properties from data class and copy(), add strategy(), rename register() to factory(), update buildResolvers()
config/NullableStrategy.kt — extend Strategy
config/StringStrategy.kt — extend Strategy
config/CollectionStrategy.kt — extend Strategy
core/FixtureContext.kt — replace 3 strategy properties with single strategyProvider
resolver/CustomFactoryResolver.kt — accept StrategyProvider instead of 3 params
resolver/NullableResolver.kt — accept StrategyProvider instead of NullableStrategy
resolver/StringResolver.kt — accept StrategyProvider instead of StringStrategy
resolver/ListResolver.kt, SetResolver.kt, MapResolver.kt, ArrayResolver.kt — accept StrategyProvider instead of CollectionStrategy
Test files for each changed resolver — update constructor calls and FixtureContext usage
Description
Implement the StrategyProvider design from the #16 spike to decouple strategy definitions from
SomeConfigand 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 theStrategymarker interface and callingconfig.strategy(strategy).This removes the maintenance bottleneck detailed in #16 and allows users to register custom strategies without modifying library code.
Scope and constraints
Strategymarker interface andStrategyProviderSomeConfig,FixtureContext,CustomFactoryResolver, and all 6 strategy-consuming resolversSomeConfig.register()tofactory()to differentiate factory registration from strategy registrationnullableStrategy,stringStrategy, orcollectionStrategyfromFixtureContextmust be updated to usestrategyProvider[<Type>::class]References
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
Strategymarker interface exists atdev.appoutlet.some.config.StrategyNullableStrategy,StringStrategy, andCollectionStrategyextendStrategyStrategyProviderinterface exists atdev.appoutlet.some.core.StrategyProviderwithoperator fun <T : Strategy> get(key: KClass<T>): TSomeConfigimplementsStrategyProvidervia an internal map pre-populated with the three default strategies, and exposesfun <T : Strategy> strategy(strategy: T)SomeConfig.register(kClass, factory)renamed toSomeConfig.factory(kClass, factory)to differentiate from strategy registrationSomeConfig.copy()no longer includesnullableStrategy,stringStrategy, orcollectionStrategyas explicit parametersFixtureContextcontains a singlestrategyProvider: StrategyProviderproperty instead of the three named strategy propertiesNullableResolver,StringResolver,ListResolver,SetResolver,MapResolver,ArrayResolver) accepts aStrategyProviderconstructor parameter and retrieves its strategy viastrategyProvider[<StrategyType>::class]CustomFactoryResolveraccepts a singleStrategyProviderinstead of three individual strategy paramsSomeConfig.buildResolvers()passes a singleStrategyProvider(typicallythis) to resolvers instead of individual strategy paramsconfig { strategy(MyCustomStrategy()) }and a custom resolver can retrieve it viasome.resolversorFixtureContext.strategyProviderStrategyProvider, usestrategyProvider[<Type>::class]inFixtureContextassertions, and usefactory()instead ofregister()AGENTS.mdupdated to reflect the new strategy registration and factory registration patternsbuildResolvers()changeSomeConfig,FixtureContext, andCustomFactoryResolverupdated to document the newStrategyProviderusage./gradlew buildpassesAdditional information
Files to change (~14):
config/Strategy.kt—Strategymarker interfacecore/StrategyProvider.kt—StrategyProviderinterfaceconfig/SomeConfig.kt— implementStrategyProvider, remove strategy properties from data class andcopy(), addstrategy(), renameregister()tofactory(), updatebuildResolvers()config/NullableStrategy.kt— extendStrategyconfig/StringStrategy.kt— extendStrategyconfig/CollectionStrategy.kt— extendStrategycore/FixtureContext.kt— replace 3 strategy properties with singlestrategyProviderresolver/CustomFactoryResolver.kt— acceptStrategyProviderinstead of 3 paramsresolver/NullableResolver.kt— acceptStrategyProviderinstead ofNullableStrategyresolver/StringResolver.kt— acceptStrategyProviderinstead ofStringStrategyresolver/ListResolver.kt,SetResolver.kt,MapResolver.kt,ArrayResolver.kt— acceptStrategyProviderinstead ofCollectionStrategyFixtureContextusageSomeConfig.kt,FixtureContext.kt,CustomFactoryResolver.kt— KDoc updatesAGENTS.md— strategy and factory registration pattern docs