Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/internal/faker-for-core.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { FakerCore } from '../core';
import { Faker } from '../faker';

const fakers = new WeakMap<FakerCore, Faker>();

/**
* Returns a `Faker` instance that uses the given `FakerCore`.
*
* The instance is cached per `FakerCore`, because creating a new `Faker` is expensive
* and all state (locale, randomizer, config) lives in the `FakerCore` anyway.
*
* @internal
*
* @param fakerCore The FakerCore to use.
*
* @example
* getFakerForCore(fakerCore).helpers.fake('{{person.lastName}}');
*/
export function getFakerForCore(fakerCore: FakerCore): Faker {
let faker = fakers.get(fakerCore);
if (faker == null) {
faker = new Faker(fakerCore);
fakers.set(fakerCore, faker);
}

return faker;
}
4 changes: 2 additions & 2 deletions src/modules/commerce/product-description.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FakerCore } from '../../core';
import { Faker } from '../../faker';
import { getFakerForCore } from '../../internal/faker-for-core';

/**
* Returns a product description.
Expand All @@ -14,7 +14,7 @@ import { Faker } from '../../faker';
* @experimental
*/
export function fakeCommerceProductDescription(fakerCore: FakerCore): string {
return new Faker(fakerCore).helpers.fake(
return getFakerForCore(fakerCore).helpers.fake(
fakerCore.locale.commerce.product_description
);
}
4 changes: 2 additions & 2 deletions src/modules/commerce/product-name.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FakerCore } from '../../core';
import { Faker } from '../../faker';
import { getFakerForCore } from '../../internal/faker-for-core';

/**
* Generates a random descriptive product name.
Expand All @@ -14,7 +14,7 @@ import { Faker } from '../../faker';
* @experimental
*/
export function fakeCommerceProductName(fakerCore: FakerCore): string {
return new Faker(fakerCore).helpers.fake(
return getFakerForCore(fakerCore).helpers.fake(
fakerCore.locale.commerce.product_name.pattern
);
}
4 changes: 2 additions & 2 deletions src/modules/company/name.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FakerCore } from '../../core';
import { Faker } from '../../faker';
import { getFakerForCore } from '../../internal/faker-for-core';

/**
* Generates a random company name.
Expand All @@ -14,7 +14,7 @@ import { Faker } from '../../faker';
* @experimental
*/
export function fakeCompanyName(fakerCore: FakerCore): string {
return new Faker(fakerCore).helpers.fake(
return getFakerForCore(fakerCore).helpers.fake(
fakerCore.locale.company.name_pattern
);
}
4 changes: 2 additions & 2 deletions src/modules/finance/transaction-description.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FakerCore } from '../../core';
import { Faker } from '../../faker';
import { getFakerForCore } from '../../internal/faker-for-core';

/**
* Generates a random transaction description.
Expand All @@ -17,7 +17,7 @@ import { Faker } from '../../faker';
export function fakeFinanceTransactionDescription(
fakerCore: FakerCore
): string {
return new Faker(fakerCore).helpers.fake(
return getFakerForCore(fakerCore).helpers.fake(
fakerCore.locale.finance.transaction_description_pattern
);
}
4 changes: 2 additions & 2 deletions src/modules/food/description.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FakerCore } from '../../core';
import { Faker } from '../../faker';
import { getFakerForCore } from '../../internal/faker-for-core';

/**
* Generates a random dish description.
Expand All @@ -14,7 +14,7 @@ import { Faker } from '../../faker';
* @experimental
*/
export function fakeFoodDescription(fakerCore: FakerCore): string {
return new Faker(fakerCore).helpers.fake(
return getFakerForCore(fakerCore).helpers.fake(
fakerCore.locale.food.description_pattern
);
}
6 changes: 4 additions & 2 deletions src/modules/food/dish.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FakerCore } from '../../core';
import { Faker } from '../../faker';
import { getFakerForCore } from '../../internal/faker-for-core';
import { fakeDatatypeBoolean } from '../datatype/boolean';
import { fakeHelpersArrayElement } from '../helpers/array-element';

Expand Down Expand Up @@ -31,7 +31,9 @@ export function fakeFoodDish(fakerCore: FakerCore): string {
// A 50/50 mix of specific dishes and dish_patterns
if (fakeDatatypeBoolean(fakerCore)) {
return toTitleCase(
new Faker(fakerCore).helpers.fake(fakerCore.locale.food.dish_pattern)
getFakerForCore(fakerCore).helpers.fake(
fakerCore.locale.food.dish_pattern
)
);
}

Expand Down
6 changes: 4 additions & 2 deletions src/modules/hacker/phrase.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FakerCore } from '../../core';
import { Faker } from '../../faker';
import { getFakerForCore } from '../../internal/faker-for-core';

/**
* Generates a random hacker/IT phrase.
Expand All @@ -15,5 +15,7 @@ import { Faker } from '../../faker';
* @experimental
*/
export function fakeHackerPhrase(fakerCore: FakerCore): string {
return new Faker(fakerCore).helpers.fake(fakerCore.locale.hacker.phrase);
return getFakerForCore(fakerCore).helpers.fake(
fakerCore.locale.hacker.phrase
);
}
4 changes: 2 additions & 2 deletions src/modules/internet/user-agent.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FakerCore } from '../../core';
import { Faker } from '../../faker';
import { getFakerForCore } from '../../internal/faker-for-core';

/**
* Generates a random user agent string.
Expand All @@ -15,7 +15,7 @@ import { Faker } from '../../faker';
* @experimental
*/
export function fakeInternetUserAgent(fakerCore: FakerCore): string {
return new Faker(fakerCore).helpers.fake(
return getFakerForCore(fakerCore).helpers.fake(
fakerCore.locale.internet.user_agent_pattern
);
}
4 changes: 2 additions & 2 deletions src/modules/location/city.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FakerCore } from '../../core';
import { Faker } from '../../faker';
import { getFakerForCore } from '../../internal/faker-for-core';

/**
* Generates a random localized city name.
Expand All @@ -15,7 +15,7 @@ import { Faker } from '../../faker';
* @experimental
*/
export function fakeLocationCity(fakerCore: FakerCore): string {
return new Faker(fakerCore).helpers.fake(
return getFakerForCore(fakerCore).helpers.fake(
fakerCore.locale.location.city_pattern
);
}
4 changes: 2 additions & 2 deletions src/modules/location/postal-address.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FakerCore } from '../../core';
import { Faker } from '../../faker';
import { getFakerForCore } from '../../internal/faker-for-core';

/**
* Generates a random localized full postal address, which may include a street address, secondary address, city, state, and zip code. To ensure you get locale-specific address formats, use a localized Faker instance.
Expand Down Expand Up @@ -32,7 +32,7 @@ import { Faker } from '../../faker';
* @experimental
*/
export function fakeLocationPostalAddress(fakerCore: FakerCore): string {
return new Faker(fakerCore).helpers.fake(
return getFakerForCore(fakerCore).helpers.fake(
fakerCore.locale.location.postal_address
);
}
6 changes: 3 additions & 3 deletions src/modules/location/secondary-address.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FakerCore } from '../../core';
import { Faker } from '../../faker';
import { getFakerForCore } from '../../internal/faker-for-core';
import { fakeStringNumeric } from '../string/numeric';

/**
Expand All @@ -16,8 +16,8 @@ import { fakeStringNumeric } from '../string/numeric';
* @experimental
*/
export function fakeLocationSecondaryAddress(fakerCore: FakerCore): string {
return new Faker(fakerCore).helpers
.fake(fakerCore.locale.location.secondary_address)
return getFakerForCore(fakerCore)
.helpers.fake(fakerCore.locale.location.secondary_address)
.replaceAll(/#+/g, (m) =>
fakeStringNumeric(fakerCore, {
length: m.length,
Expand Down
4 changes: 2 additions & 2 deletions src/modules/location/street-address.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FakerCore } from '../../core';
import { Faker } from '../../faker';
import { getFakerForCore } from '../../internal/faker-for-core';

/**
* Generates a random localized street address.
Expand Down Expand Up @@ -40,5 +40,5 @@ export function fakeLocationStreetAddress(
const formats = fakerCore.locale.location.street_address;
const format = formats[useFullAddress ? 'full' : 'normal'];

return new Faker(fakerCore).helpers.fake(format);
return getFakerForCore(fakerCore).helpers.fake(format);
}
4 changes: 2 additions & 2 deletions src/modules/location/street.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FakerCore } from '../../core';
import { Faker } from '../../faker';
import { getFakerForCore } from '../../internal/faker-for-core';

/**
* Generates a random localized street name.
Expand All @@ -14,7 +14,7 @@ import { Faker } from '../../faker';
* @experimental
*/
export function fakeLocationStreet(fakerCore: FakerCore): string {
return new Faker(fakerCore).helpers.fake(
return getFakerForCore(fakerCore).helpers.fake(
fakerCore.locale.location.street_pattern
);
}
4 changes: 2 additions & 2 deletions src/modules/location/zip-code.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { FakerCore } from '../../core';
import { FakerError } from '../../errors/faker-error';
import { Faker } from '../../faker';
import { getFakerForCore } from '../../internal/faker-for-core';
import { fakeHelpersArrayElement } from '../helpers/array-element';
import { fakeHelpersReplaceSymbols } from '../helpers/replace-symbols';

Expand Down Expand Up @@ -62,7 +62,7 @@ export function fakeLocationZipCode(
throw new FakerError(`No zip code definition found for state "${state}"`);
}

return new Faker(fakerCore).helpers.fake(zipPattern);
return getFakerForCore(fakerCore).helpers.fake(zipPattern);
}

let { format = fakerCore.locale.location.postcode } = options;
Expand Down
6 changes: 4 additions & 2 deletions src/modules/person/bio.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FakerCore } from '../../core';
import { Faker } from '../../faker';
import { getFakerForCore } from '../../internal/faker-for-core';

/**
* Returns a random short biography
Expand All @@ -14,5 +14,7 @@ import { Faker } from '../../faker';
* @experimental
*/
export function fakePersonBio(fakerCore: FakerCore): string {
return new Faker(fakerCore).helpers.fake(fakerCore.locale.person.bio_pattern);
return getFakerForCore(fakerCore).helpers.fake(
fakerCore.locale.person.bio_pattern
);
}
4 changes: 2 additions & 2 deletions src/modules/person/job-title.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FakerCore } from '../../core';
import { Faker } from '../../faker';
import { getFakerForCore } from '../../internal/faker-for-core';

/**
* Generates a random job title.
Expand All @@ -14,7 +14,7 @@ import { Faker } from '../../faker';
* @experimental
*/
export function fakePersonJobTitle(fakerCore: FakerCore): string {
return new Faker(fakerCore).helpers.fake(
return getFakerForCore(fakerCore).helpers.fake(
fakerCore.locale.person.job_title_pattern
);
}
4 changes: 2 additions & 2 deletions src/modules/person/last-name.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FakerCore } from '../../core';
import { Faker } from '../../faker';
import { getFakerForCore } from '../../internal/faker-for-core';
import { fakeHelpersArrayElement } from '../helpers/array-element';
import { fakeHelpersWeightedArrayElement } from '../helpers/weighted-array-element';
import { selectDefinition } from './_select-definition';
Expand Down Expand Up @@ -31,7 +31,7 @@ export function fakePersonLastName(
fakerCore,
selectDefinition(fakerCore, sex, patterns)
);
return new Faker(fakerCore).helpers.fake(pattern);
return getFakerForCore(fakerCore).helpers.fake(pattern);
}

return fakeHelpersArrayElement(
Expand Down
55 changes: 55 additions & 0 deletions test/internal/faker-for-core.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { describe, expect, it, vi } from 'vitest';
import { Faker, createFakerCore, en } from '../../src';
import { getFakerForCore } from '../../src/internal/faker-for-core';
import { fakePersonLastName } from '../../src/modules/person';

describe('internal', () => {
describe('getFakerForCore', () => {
it('should return the same instance for the same core', () => {
const fakerCore = createFakerCore({ locale: en });

expect(getFakerForCore(fakerCore)).toBe(getFakerForCore(fakerCore));
});

it('should return different instances for different cores', () => {
const fakerCore1 = createFakerCore({ locale: en });
const fakerCore2 = createFakerCore({ locale: en });

expect(getFakerForCore(fakerCore1)).not.toBe(getFakerForCore(fakerCore2));
});

it('should share the randomizer and locale of the core', () => {
const fakerCore = createFakerCore({ locale: en });
const faker = getFakerForCore(fakerCore);

expect(faker.fakerCore.randomizer).toBe(fakerCore.randomizer);
expect(faker.fakerCore.locale).toBe(fakerCore.locale);
expect(faker.fakerCore.config).toBe(fakerCore.config);
});

it('should generate the same values as a fresh Faker', () => {
const pattern = '{{person.lastName}} {{location.city}}';
const fakerCore = createFakerCore({ locale: en, seed: 42 });
const expected = [1, 2, 3].map(() =>
new Faker(fakerCore).helpers.fake(pattern)
);

fakerCore.randomizer.seed(42);
const actual = [1, 2, 3].map(() =>
getFakerForCore(fakerCore).helpers.fake(pattern)
);

expect(actual).toEqual(expected);
});

it('should be used by standalone functions', () => {
const fakerCore = createFakerCore({ locale: en });
const fake = vi.fn<() => string>(() => 'cached');
getFakerForCore(fakerCore).helpers.fake = fake;

expect(fakePersonLastName(fakerCore)).toBe('cached');
expect(fakePersonLastName(fakerCore)).toBe('cached');
expect(fake).toHaveBeenCalledTimes(2);
});
});
});
Loading