Skip to content

Add NullOnCircularReference strategy to NullableStrategy #34

Description

@MessiasLima

Description

When some<T>() encounters a circular reference (e.g., a data class A has a field of type A?), it currently throws SomeCircularReferenceException unconditionally. This makes it impossible to generate instances of recursive data structures without custom factories, even when the circular field is nullable and could gracefully resolve to null.

The change: when a circular reference is detected by ResolverChain, if nullableStrategy is NullOnCircularReference and the type is nullable (isMarkedNullable), return null instead of throwing. Non-nullable circular references should still throw.

NullOnCircularReference becomes the default strategy, replacing Random().

Scope

In scope:

  • Add NullOnCircularReference as a new variant of the NullableStrategy sealed interface
  • Modify ResolverChain.resolve() to check the strategy + nullability before throwing on circular reference
  • Change the default in SomeConfig from Random() to NullOnCircularReference
  • Add unit tests for:
    • Circular nullable field returns null under NullOnCircularReference
    • Circular non-nullable field still throws SomeCircularReferenceException
    • No behavior change for strategies that aren't NullOnCircularReference

Out of scope:

  • Changes to the exception class
  • Any per-field circular reference control

Acceptance criteria

  • GIVEN a data class with a self-referencing nullable field (e.g., data class Node(val next: Node?))
    WHEN some<Node>() is called with the default config
    THEN the nullable field resolves to null and no exception is thrown

  • GIVEN a data class with a self-referencing non-nullable field (e.g., data class Node(val next: Node))
    WHEN some<Node>() is called with any strategy
    THEN SomeCircularReferenceException is thrown

  • GIVEN any existing strategy (AlwaysNull, NeverNull, Random)
    WHEN a circular reference is detected
    THEN the current behavior (throwing SomeCircularReferenceException) is preserved unchanged

Metadata

Metadata

Assignees

No one assigned

    Labels

    julesJules lives

    Projects

    Status
    Done

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions