feat: float strategy#89
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces FloatStrategy and updates FloatResolver to support configurable ranges for generated Float values, complete with documentation and unit tests. The feedback highlights two key improvements: resolving a potential float overflow issue during random generation for very wide ranges by performing intermediate calculations in Double precision, and optimizing FloatStrategy.default to be a stored property rather than a custom getter to prevent unnecessary object allocations.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Summary
Introduces a
FloatStrategyso users can constrain the range of randomly generatedFloatvalues during fixture generation. Until now,FloatResolveralways calledrandom.nextFloat(), producing values in[0.0, 1.0)with no way to widen, shift, or pin the range without writing a custom resolver or factory.This follows the same pattern as
CollectionStrategy: a data class wrapping aClosedFloatingPointRange<Float>with input validation, acompanion object default, and a corresponding resolver update that consumes the active strategy viaStrategyProvider. The default range0.0f..1.0fpreserves the current behavior ofFloatResolverto avoid a breaking change for existing users. A secondary constructorFloatStrategy(fixed: Float)is provided as a convenience for callers who want to pin generation to a single value.Closes #69.
What changed
core/src/main/kotlin/dev/appoutlet/some/config/FloatStrategy.kt— data class with primary constructorFloatStrategy(range: ClosedFloatingPointRange<Float> = 0.0f..1.0f), secondary constructorFloatStrategy(fixed: Float), validation that throwsIllegalArgumentExceptionwhenrange.start > range.endInclusive(zero-width ranges allowed), and acompanion objectexposingFloatStrategy.default.FloatResolverto accept aStrategyProviderand produce values within the configured range. Zero-width ranges return the fixed value directly; non-zero-width ranges usestart + random.nextFloat() * (endInclusive - start)(exclusive end, matchingrandom.nextDouble(from, until)semantics).SomeConfig.buildResolvers()to wireFloatResolver(strategyProvider, random).Strategy.ktandSomeConfigBuilder.ktto listFloatStrategyalongside the other built-in strategies.FloatStrategyTestcovering default range, validation of inverted ranges, zero-width behavior, and secondary constructor equivalence.FloatResolverTestto cover the new constructor signature, default range, custom range, negative range, fixed value, zero-width range, andSomeConfigintegration.docs/configuration/float-strategy.mddocumenting configuration, fixed-value constructor, default, affected types, and validation. Linked from the configuration index defaults table, thesupported-types.mdFloatrow, and added to thezensical.tomlConfiguration nav.Checklist