faker icon indicating copy to clipboard operation
faker copied to clipboard

Proposal: Replace internal fake patterns with a resolver function

Open ST-DDT opened this issue 1 year ago • 1 comments

Continuation of/Requires: #2667, #2838

  • #2667
  • #2838

Partially inspired by: #1832, #2664

  • #1832
  • #2664

Clear and concise description of the problem

Glossary:

  • fake patterns: String patterns used by faker.helpers.fake
  • resolver functions: functions that take fakerCore as an argument and return a value based on a seed

Currently, some faker internal methods use fake patterns to generate some complex values based on certain parameters. However parsing fake patterns is slow and error prone.

Suggested solution

Introduce a new helper method: faker.helpers.resolve(fns: ResolverFunction[])

type ResolverFunction<T> = (core: FakerCore) => T;

function resolve<T>(core: FakerCore, fns: ResolverFunction<T>[]): T{
    const fn = arrayElement(core, fns);
    return fn(core);
}

This could later be extended to support parameters as well.

Fake-Usage (OLD)

export const last_name_pattern = [
	'{{person.last_name}}',
	'{{person.last_name}}-{{person.last_name}}',
];

function lastName(core: FakerCore) {
	return fake(core, core.locale.person.last_name_pattern);
}

Resolve-Usage (NEW)

export const last_name_resolvers = [
	(core) => arrayElement(core, core.locale.person.last_name),
	(core) => arrayElement(core, core.locale.person.last_name) + '-' + arrayElement(core, core.locale.person.last_name),
];

function lastName(core: FakerCore) {
	return resolve(core, core.locale.person.last_name_resolvers);
}

Pros

  • Compile time errors instead of runtime errors
  • Supports auto completion when creating the resolver functions
  • Significantly better performance
  • No issues with json encoded parameters

Cons

  • Breaking change for locale data
  • Methods that use the new resolve patterns are harder to populate using a DB/file/string only store

Affected Methods

  • company.name
  • food.description
  • food.dish
  • location.zipCode
  • location.city
  • location.street
  • location.streetAddress
  • location.secondayAddress
  • person.lastName
  • person.bio
  • person.jobTitle

And potentially:

  • finance.iban
  • ....

Alternatives

Alternatively, we could follow this pattern for each method individually.

export const last_name_resolvers = [
	(core) => arrayElement(core, core.locale.person.last_name),
	(core) => arrayElement(core, core.locale.person.last_name) + '-' + arrayElement(core, core.locale.person.last_name),
];

function lastName(core: FakerCore) {
    const lastNameResolver = arrayElement(core, core.locale.person.last_name_resolvers);
	return lastNameResolver(core);
}

ST-DDT avatar Oct 12 '24 10:10 ST-DDT

Hmm, i'm not really a big fan of this idea. I like the fact that the data sources for most methods are simple arrays. Also, I think looking at how Faker uses fake patterns internally is educational in figuring out how you might use it yourself.

matthewmayer avatar Oct 12 '24 12:10 matthewmayer