arkadiuszbachorski / fabbrica

TypeScript library to create object factories that do mocking and testing a breeze
3 stars 1 forks source link

Question: How to depend on other property #2

Open loxy opened 21 hours ago

loxy commented 21 hours ago

Hi!

I like you library! But I have one problem: I want to reuse the value from another field of the generated entity, like here:

import { Factory } from 'fabbrica';
import { faker } from '@faker-js/faker';

export class BasicClubFragmentFactory extends Factory<BasicClubFragment> {
  define = {
    clubId: () => faker.string.uuid(), 
    nodeId: /* Needs to reuse the value from clubId */,
    // Other properties...
  };
}

nodeId should depend on clubId (for example making it base64 encoded). Or even easier using the same (random) data.

I tried something like:

define = () => {
    // Generate a shared UUID for nodeId and clubId
    const sharedId = faker.string.uuid();

    return {
      nodeId: sharedId,
      clubId: sharedId,
      // Other properties...
    };
  };

But that cannot work with current implementation.

Any ideas how to mitigate that? Maybe it would be cool if the field creator function would optionally accept the instance itself, like nodeId: (instance: BasicClubFragment) => instance.clubId

Best regards, Kersten

arkadiuszbachorski commented 5 hours ago

Hi @loxy, great to hear it's useful for you!

Unfortunately, there is just one way to achieve that safely - by overriding create method. Unfortunately, create is overloaded, this requires a bit of type gymnastics. Please refer to implementation of Factory#create method to see the type overload.

Using pseudo-code, it would be something like this:

export class BasicClubFragmentFactory extends Factory<BasicClubFragment> {
  define = {
    clubId: () => faker.string.uuid(), 
    nodeId: "",
  };
  create(...args) {
    const result = super().create(...args); // result is either BasicClubFragment or Array<BasicClubFragment>
    // modify result to override `nodeId` with value of `clubId` and return result
  }
}

I definitely recognize it as missing feature of the library. I am happy to provide a fully-fledged support for that without any hacks or overrides in the future. Although, I can't guarantee any time frame when it's available.

Let me know if any questions!