Skip to content

Add FloatStrategy to control generated Float value range #69

Description

@MessiasLima

Description

Introduce a FloatStrategy so that users can constrain the range of randomly generated Float values during fixture generation. Today, FloatResolver (src/main/kotlin/dev/appoutlet/some/resolver/FloatResolver.kt:9) always calls random.nextFloat(), producing values in [0.0, 1.0). There is no way for users to widen or shift that range, or to pin a value, without writing a custom resolver or factory.

This follows the same pattern as CollectionStrategy (src/main/kotlin/dev/appoutlet/some/config/CollectionStrategy.kt:7): a data class wrapping a ClosedFloatingPointRange<Float> with input validation, a companion object default, and a corresponding resolver update that consumes the active strategy via StrategyProvider. The default range is 0.0f..1.0f to preserve the current behavior of FloatResolver and avoid a breaking change for existing users.

A secondary constructor FloatStrategy(fixed: Float) is provided as a convenience for callers who want to pin generation to a single value; it delegates to the primary constructor with range = fixed..fixed.

Scope

  • Add FloatStrategy in dev.appoutlet.some.config (new file, one class per file) with:
    • Primary constructor FloatStrategy(range: ClosedFloatingPointRange<Float> = 0.0f..1.0f).
    • Secondary constructor FloatStrategy(fixed: Float) that calls the primary constructor with range = fixed..fixed.
    • Validation that throws IllegalArgumentException when the range start is greater than the range end (zero-width ranges are allowed).
    • companion object with default: FloatStrategy returning FloatStrategy().
  • Update FloatResolver to accept a StrategyProvider and produce values within the configured range using the same approach as ListResolver (src/main/kotlin/dev/appoutlet/some/resolver/ListResolver.kt:21). For a zero-width range, the resolver returns the fixed value directly.
  • Register FloatStrategy::class to FloatStrategy.default in SomeConfig.defaultStrategies() (src/main/kotlin/dev/appoutlet/some/config/SomeConfig.kt:194).
  • Update FloatResolver wiring in SomeConfig to pass the StrategyProvider to the constructor.
  • Add unit tests for FloatStrategy (default range, validation of inverted ranges, zero-width behavior, secondary constructor equivalence) and updated tests for FloatResolver.
  • Update KDoc on Strategy and SomeConfigBuilder to list FloatStrategy alongside the other built-in strategies.

Out of scope: an equivalent DoubleStrategy (can be a follow-up), changing the default range away from 0.0f..1.0f, and changing behavior of any other primitive resolvers.

Acceptance criteria

  • GIVEN a fresh SomeConfig with no custom FloatStrategy registered
    WHEN some<Float>() is invoked
    THEN every generated value is a Float in the range 0.0f..1.0f (exclusive end), matching the current random.nextFloat() behavior — no compatibility break for existing users.
  • GIVEN a user calls strategy(FloatStrategy(range = 0.0f..10.0f)) in their someSetup { } block
    WHEN some<Float>() is invoked repeatedly
    THEN every generated value lies inside 0.0f..10.0f and the range is honored end-to-end (exclusive end, matching random.nextDouble(from, until) semantics).
  • GIVEN a user calls strategy(FloatStrategy(fixed = 5.0f)) in their someSetup { } block
    WHEN some<Float>() is invoked repeatedly
    THEN every generated value equals 5.0f, and this is equivalent to strategy(FloatStrategy(range = 5.0f..5.0f)).
  • GIVEN a user constructs FloatStrategy(range = 5.0f..5.0f) (zero-width)
    WHEN the strategy is consumed by FloatResolver
    THEN it always returns 5.0f and no exception is thrown.
  • GIVEN a user calls strategy(FloatStrategy(range = 5.0f..2.0f)) (inverted)
    WHEN the strategy is constructed
    THEN it throws an IllegalArgumentException with a descriptive message, matching the validation style of CollectionStrategy (src/main/kotlin/dev/appoutlet/some/config/CollectionStrategy.kt:12).
  • GIVEN the existing FloatResolverTest
    WHEN the new tests are added
    THEN the test class verifies: (a) the resolver accepts Float and rejects Double/Int, (b) generated values respect the active FloatStrategy range, (c) the default range produces values in 0.0f..1.0f, and (d) a fixed strategy always returns the pinned value.
  • GIVEN the documentation in Strategy.kt and SomeConfigBuilder.kt
    WHEN this change is merged
    THEN both files reference FloatStrategy in their "built-in strategies" lists and SomeConfigBuilder exposes a strategy(FloatStrategy(...)) example mirroring the CollectionStrategy(5..10) example.

Metadata

Metadata

Assignees

No one assigned

    Labels

    julesJules lives

    Projects

    Status
    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions