Skip to content

Spike: Investigate kotlin-faker integration with annotation-driven customization #33

Description

@MessiasLima

Description

Investigate the feasibility of integrating kotlin-faker into the Some library so that users can annotate data class properties with annotations like @SomeName (or similar) and get realistic fake data (names, addresses, emails, etc.) generated under the hood.

Background

The Some library currently generates random-but-meaningless test data (e.g., random strings, random ints). For realistic test scenarios — such as generating valid-looking user profiles, addresses, or company names — users would benefit from faker-style data generation. Rather than requiring manual custom factories for every field, an annotation-driven approach would let users declaratively map properties to faker generators.

Current Knowledge

  • The library uses a resolver chain pattern where each TypeResolver implements canResolve(type) -> resolve(type, chain). CustomFactoryResolver sits at the top of the chain and is the existing programmatic override mechanism.
  • No annotation processing exists in the codebase. There is no KSP/KAPT plugin configured. The only build plugins are Dokka, Detekt, Kover, and Maven publishing.
  • kotlin-reflect (v2.3.21) is already a runtime dependency, which is sufficient for runtime annotation scanning on constructor parameters.
  • kotlin-faker is a mature JVM library with comprehensive data generators: names, addresses, phone numbers, emails, companies, internet URLs, lorem ipsum, etc. It supports locale configuration (en_US default), seed-based deterministic random, and a DSL-based FakerConfig API.
  • The SomeConfig data class already carries strategy objects (StringStrategy, NullableStrategy, CollectionStrategy) and a seed property, which could be extended to carry faker configuration.
  • A key architectural question: annotations would need to be placed on constructor parameters of data classes, since DataClassResolver resolves by inspecting primaryConstructor.parameters and calling resolve() for each parameter type. With runtime annotations, the resolver could read @Faker("name.fullName") from a parameter and generate a faker value instead of resolving the type normally.

Scope

In scope:

  • Evaluate the runtime annotation scanning approach — can kotlin-reflect read annotations from KParameter instances in DataClassResolver?
  • Determine path expression resolution — is it feasible to translate a string like "name.fullName" into a faker.name.fullName() call via reflection? If not, what alternatives exist?
  • Assess kotlin-faker dependency — library size, API stability, version compatibility with Kotlin 2.x / kotlin-reflect 2.x
  • Compare runtime vs compile-time (KSP) approaches — pros, cons, and complexity trade-offs
  • Propose a resolver placement — where should a potential FakerResolver sit in the chain relative to CustomFactoryResolver, NullableResolver, and DataClassResolver?
  • Propose configuration integration — how to pass locale, seed, and faker instance through SomeConfig
  • Design the annotation API surface — annotation names, parameter conventions, repeatability, supported types

Out of scope:

  • Implementing the integration (code changes to the library)
  • Finalizing annotation names or API contract
  • Adding KSP as a build plugin (unless the investigation determines it's necessary)

Outcomes

  • Evaluate whether kotlin-reflect can reliably read custom annotations from KParameter (constructor parameters) at runtime, and whether this works across inline/value classes and generic types
  • Determine the feasibility of a path-expression-to-faker-call mapping, and decide on reflection-based vs explicit-mapping approach
  • Assess kotlin-faker's dependency footprint (JAR size, transitive dependencies) and binary compatibility with Kotlin 2.x
  • Compare runtime annotation scanning (simpler, no build config) vs KSP compile-time approach (faster, more type-safe) and recommend one
  • Produce a design recommendation in a comment on this issue, covering: proposed annotation API, resolver placement, config integration, and implementation effort estimate (small / medium / large)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    Status
    In progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions