Skip to content

Allow option for nested values on slice fields #29

@damif94

Description

@damif94

Intro

Hi!
For some time we have been using this library at my company, and the dot notation for nested field setting on subfactories has proven really useful. It make really the declaration of new instances with fixed data really elegant.

Now, I think a similar strategy could be carried over for slice nested fields.
If you like the idea, I could PR it myself.

Example

Context

For example (borrowed from our codebase):

type Player struct {
  ID          string
  FirstName   string
  LastName    string
  ExternalIds []ExternalID
}

type ExternalID struct {
  ID       string
  Provider string
}

our factories look like:

func playerFactoryBuilder(model any) *factory.Factory {
  return factory.NewFactory(
    model,
  ).Attr(
    "ID",
      AlphanumericGenerator(10),
  ).Attr(
    "FirstName", FirstNameGenerator,
  ).Attr(
    "LastName", LastNameGenerator,
  ).SubSliceFactory(
    "ExternalIds",
    externalIDFactory,
    func() int { return 2 },
  )
}

var externalIDFactory = NewFactory(
  models.ExternalID{},
).Attr(
  "Provider",
  ConstantGenerator("somewhat"),
).Attr(
  "ID",
  AlphanumericGenerator(10),
)

Proposal:

My proposal would work like this:

Scenario 1: Dot notation for nested array fields

func main() {
  for i := 0; i < 3; i++ {
    player := PlayerFactory.MustCreateWithOption(map[string]any{"ExternalIds.Provider": "some-provider"}).(*Player)
    for i, _ := range player.externalIds {
      fmt.Println("ID:", player.ExternalIds.[i].ID, " Provider:", player.ExternalIds[i].Provider)
    }
  }
}

would affect all slice generated instances, printing something like

ID: 12ad23d4bn  Provider: some-provider
ID: 32ad23d4bn  Provider: some-provider

Scenario 2: Dot notation for nested array fields on specific index in slice subfactory bounds

func main() {
  for i := 0; i < 3; i++ {
    player := PlayerFactory.MustCreateWithOption(map[string]any{"ExternalIds.1.Provider": "some-provider"}).(*Player)
    for i, _ := range player.externalIds {
      fmt.Println("ID:", player.ExternalIds.[i].ID, " Provider:", player.ExternalIds[i].Provider)
    }
  }
}

would affect only the instance generated at the specified index, printing something like

ID: 12ad23d4bn  Provider: somewhat
ID: 32ad23d4bn  Provider: some-provider

Scenario 3: Dot notation for nested array fields on specific index out of slice subfactory bounds

func main() {
  for i := 0; i < 3; i++ {
    player := PlayerFactory.MustCreateWithOption(map[string]any{"ExternalIds.2.Provider": "some-provider"}).(*Player)
    for i, _ := range player.externalIds {
      fmt.Println("ID:", player.ExternalIds.[i].ID, " Provider:", player.ExternalIds[i].Provider)
    }
  }
}

would panic with an error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions