diff --git a/README.md b/README.md index 2b5781742ab..5aea0cea14f 100644 --- a/README.md +++ b/README.md @@ -56,8 +56,11 @@ npm install --save-dev @faker-js/faker ## 🪄 Usage ```ts +// ESM import { faker } from '@faker-js/faker'; -// import { faker } from '@faker-js/faker/locale/de'; + +// CJS +const { faker } = require('@faker-js/faker'); export function createRandomUser(): User { return { @@ -108,7 +111,6 @@ The API covers the following modules: | Music | `faker.music.genre()` | R&B | | Person | `faker.person.firstName()` | Cameron | | Phone | `faker.phone.phoneNumber()` | +1 291-299-0192 | -| Random | `faker.random.locale()` | fr_CA | | Science | `faker.science.unit()` | `{ name: 'meter', symbol: 'm' }` | | System | `faker.system.directoryPath()` | /root | | Vehicle | `faker.vehicle.vehicle()` | Lamborghini Camry | @@ -130,18 +132,30 @@ console.log( Faker has support for multiple locales. -The default language locale is set to English. - -Setting a new locale is simple: +The main `faker` instance uses the English locale. +But you can also import instances using other locales. ```ts -// sets locale to de -faker.locale = 'de'; +// ESM +import { fakerDE as faker } from '@faker-js/faker'; + +// CJS +const { fakerDE: faker } = require('@faker-js/faker'); ``` -See our documentation for a list of [provided languages](https://fakerjs.dev/guide/localization.html#available-locales) +See our documentation for a list of [provided languages](https://fakerjs.dev/guide/localization.html#available-locales). + +Please note: Not every locale provides data for every module. In our pre-made faker instances, +we fall back to English in such a case as this is the most complete and most commonly used language. +If you don't want that or prefer a different fallback, you can also build your own instances. -Please note: not every locale provides data for every module. In our pre-made locales, we fallback to English in such a case as this is the most complete and most commonly used language. +```ts +import { Faker, de, de_CH } from '@faker-js/faker'; + +export const faker = new Faker({ + locale: [de_CH, de], +}); +``` ## ⚙️ Setting a randomness seed diff --git a/docs/guide/localization.md b/docs/guide/localization.md index b0bfbad8000..b3003aad505 100644 --- a/docs/guide/localization.md +++ b/docs/guide/localization.md @@ -3,15 +3,20 @@ ## Switching locales Did you know Faker supports many different locales? -By default, when using `import { faker } from '@faker-js/faker'` actually every available locale that is supported by Faker will be loaded and you can switch the locale at runtime with `faker.setLocale('de')`. +When using our default instance `import { faker } from '@faker-js/faker'` you get English data. +However, we also provide pre-built instances for more than 50 other locales. -::: tip -Alternatively you can also just use `faker.locale = 'de'` instead to switch the locale. +`import { fakerDE as faker } from '@faker-js/faker'` + +See below for a list of available locales. + +:::tip Note +You can also build your own Faker instances, with custom locales/overwrites. ::: ## Individual localized packages -By default, Faker will include **all** locale data. +Currently, the imports from the main package have a [bug](https://github.com/faker-js/faker/issues/1791) and always cause the entire Faker lib to be imported. This might result in loading around 5 MB of data into memory and slow down startup times. _But we got your back!_ @@ -33,72 +38,98 @@ Some locales have limited coverage and rely more heavily on the English locale a However, in most cases, using a specific locale will be beneficial in the long term as specifying a locale reduces the time necessary for startup, which has a compounding effect on testing frameworks that reload the imports every execution. ::: +## Custom locales and fallbacks + +If our built-in faker instances don't satisfy your needs, you can build your own: + +```ts +import type { LocaleDefinition } from '@faker-js/faker'; +import { Faker, de_CH, de, en } from '@faker-js/faker'; + +const customLocale: LocaleDefinition = { + title: 'My custom locale', + internet: { + domainSuffix: ['test'], + }, +}; + +export const customFaker = new Faker({ + locale: [customLocale, de_CH, de, en, global], +}); +``` + ## Available locales -| Locale | Name | -| :---------- | :------------------------ | -| af_ZA | Afrikaans | -| ar | Arabic | -| az | Azerbaijani | -| cz | Czech | -| de | German | -| de_AT | German (Austria) | -| de_CH | German (Switzerland) | -| dv | Dhivehi | -| el | Greek | -| en | English | -| en_AU | English (Australia) | -| en_AU_ocker | English (Australia Ocker) | -| en_BORK | English (Bork) | -| en_CA | English (Canada) | -| en_GB | English (Great Britain) | -| en_GH | English (Ghana) | -| en_IE | English (Ireland) | -| en_IN | English (India) | -| en_NG | Nigeria (English) | -| en_US | English (United States) | -| en_ZA | English (South Africa) | -| es | Spanish | -| es_MX | Spanish (Mexico) | -| fa | Farsi | -| fi | Finnish | -| fr | French | -| fr_BE | Français (Belgique) | -| fr_CA | French (Canada) | -| fr_CH | French (Switzerland) | -| fr_LU | French (Luxembourg) | -| ge | Georgian | -| he | Hebrew | -| hr | Hrvatski | -| hu | Hungarian | -| hy | Armenian | -| id_ID | Indonesian | -| it | Italian | -| ja | Japanese | -| ko | Korean | -| lv | Latvian | -| mk | Macedonian | -| nb_NO | Norwegian | -| ne | Nepalese | -| nl | Dutch | -| nl_BE | Dutch (Belgium) | -| pl | Polish | -| pt_BR | Portuguese (Brazil) | -| pt_PT | Portuguese (Portugal) | -| ro | Romanian | -| ru | Russian | -| sk | Slovakian | -| sv | Swedish | -| tr | Turkish | -| uk | Ukrainian | -| ur | Urdu | -| vi | Vietnamese | -| zh_CN | Chinese | -| zh_TW | Chinese (Taiwan) | -| zu_ZA | Zulu (South Africa) | +| Locale | Name | Faker | +| :------------ | :------------------------ | :----------------- | +| `af_ZA` | Afrikaans | `fakerAF_ZA` | +| `ar` | Arabic | `fakerAR` | +| `az` | Azerbaijani | `fakerAZ` | +| `cz` | Czech | `fakerCZ` | +| `de` | German | `fakerDE` | +| `de_AT` | German (Austria) | `fakerDE_AT` | +| `de_CH` | German (Switzerland) | `fakerDE_CH` | +| `dv` | Dhivehi | `fakerDV` | +| `el` | Greek | `fakerEL` | +| `en` | English | `fakerEN` | +| `en_AU` | English (Australia) | `fakerEN_AU` | +| `en_AU_ocker` | English (Australia Ocker) | `fakerEN_AU_ocker` | +| `en_BORK` | English (Bork) | `fakerEN_BORK` | +| `en_CA` | English (Canada) | `fakerEN_CA` | +| `en_GB` | English (Great Britain) | `fakerEN_GB` | +| `en_GH` | English (Ghana) | `fakerEN_GH` | +| `en_IE` | English (Ireland) | `fakerEN_IE` | +| `en_IN` | English (India) | `fakerEN_IN` | +| `en_NG` | Nigeria (English) | `fakerEN_NG` | +| `en_US` | English (United States) | `fakerEN_US` | +| `en_ZA` | English (South Africa) | `fakerEN_ZA` | +| `es` | Spanish | `fakerES` | +| `es_MX` | Spanish (Mexico) | `fakerES_MX` | +| `fa` | Farsi | `fakerFA` | +| `fi` | Finnish | `fakerFI` | +| `fr` | French | `fakerFR` | +| `fr_BE` | Français (Belgique) | `fakerFR_BE` | +| `fr_CA` | French (Canada) | `fakerFR_CA` | +| `fr_CH` | French (Switzerland) | `fakerFR_CH` | +| `fr_LU` | French (Luxembourg) | `fakerFR_LU` | +| `ge` | Georgian | `fakerGE` | +| `he` | Hebrew | `fakerHE` | +| `hr` | Hrvatski | `fakerHR` | +| `hu` | Hungarian | `fakerHU` | +| `hy` | Armenian | `fakerHY` | +| `id_ID` | Indonesian | `fakerID_ID` | +| `it` | Italian | `fakerIT` | +| `ja` | Japanese | `fakerJA` | +| `ko` | Korean | `fakerKO` | +| `lv` | Latvian | `fakerLV` | +| `mk` | Macedonian | `fakerMK` | +| `nb_NO` | Norwegian | `fakerNB_NO` | +| `ne` | Nepalese | `fakerNE` | +| `nl` | Dutch | `fakerNL` | +| `nl_BE` | Dutch (Belgium) | `fakerNL_BE` | +| `pl` | Polish | `fakerPL` | +| `pt_BR` | Portuguese (Brazil) | `fakerPT_BR` | +| `pt_PT` | Portuguese (Portugal) | `fakerPT_PT` | +| `ro` | Romanian | `fakerRO` | +| `ru` | Russian | `fakerRU` | +| `sk` | Slovakian | `fakerSK` | +| `sv` | Swedish | `fakerSV` | +| `tr` | Turkish | `fakerTR` | +| `uk` | Ukrainian | `fakerUK` | +| `ur` | Urdu | `fakerUR` | +| `vi` | Vietnamese | `fakerVI` | +| `zh_CN` | Chinese | `fakerZH_CN` | +| `zh_TW` | Chinese (Taiwan) | `fakerZH_TW` | +| `zu_ZA` | Zulu (South Africa) | `fakerZU_ZA` | + +The `Locale` (data) and `Faker` columns refer to the respective `import` names: + +```ts +import { de, fakerDE } from '@faker-js/faker'; +``` diff --git a/docs/guide/upgrading.md b/docs/guide/upgrading.md index 709a76d0523..82bfd2ac18b 100644 --- a/docs/guide/upgrading.md +++ b/docs/guide/upgrading.md @@ -14,6 +14,90 @@ Not the version you are looking for? ## Breaking changes +### Removed ability to change the locale on existing `Faker` instances + +:::tip NOTE +If you are using only the default (`en`) locale, then you don't have to change anything. +::: + +In order to facilitate better and easier locale fallback mechanics, we removed the methods to change the locales on existing `Faker` instances. +Now, we expose specific faker instances for each locale that you can use: + +**Old** + +```ts +import { faker } from '@faker-js/faker'; + +faker.setLocale('de_CH'); +// or +faker.locale = 'de_CH'; +faker.fallbackLocale = 'en'; +``` + +**New** + +```ts +import { fakerDE_CH as faker } from '@faker-js/faker'; +``` + +This also fixes issues where more than two locales are required: + +**Old** + +```ts +import { faker } from '@faker-js/faker'; + +const customFaker = new Faker({ + locale: 'de_CH', // the expected locale + fallbackLocale: 'de', // ensure we have a German fallbacks for addresses + locales: { de_CH, de, en }, +}); +const a = customFaker.internet.email(); +customFaker.locale = 'en'; // neither 'de_CH' nor 'de' have emojis +const b = customFaker.internet.emoji(); +``` + +**New** + +```ts +import { Faker, de_CH, de, en, global } from '@faker-js/faker'; + +// same as fakerDE_CH +export const customFaker = new Faker({ + // Now multiple fallbacks are supported + locale: [de_CH, de, en, global], +}); +const a = customFaker.internet.email(); +const b = customFaker.internet.emoji(); +``` + +If you wish to create entries for multiple locales, you can still do so: + +**Old** + +```ts +import { faker } from '@faker-js/faker'; + +for (let user of users) { + const lang = faker.helpers.arrayElement(['de', 'en', 'fr']); + faker.locale = lang; + user.email = faker.internet.email(); +} +``` + +**New** + +```ts +import { faker, fakerDE, fakerEN, fakerFR } from '@faker-js/faker'; + +for (let user of users) { + const currentFaker = faker.helpers.arrayElement([fakerDE, fakerEN, fakerFR]); + user.email = currentFaker.internet.email(); +} +``` + +For more information refer to our [Localization Guide](localization). + ### `faker.mersenne` and `faker.helpers.repeatString` removed `faker.mersenne` and `faker.helpers.repeatString` were only ever intended for internal use, and are no longer available. diff --git a/docs/guide/usage.md b/docs/guide/usage.md index 6d325a0bd9d..7448a699cc8 100644 --- a/docs/guide/usage.md +++ b/docs/guide/usage.md @@ -6,18 +6,12 @@ Using Faker is as easy as importing it from `@faker-js/faker`. ```js import { faker } from '@faker-js/faker'; -// or, if desiring only a specific locale -// import { faker } from '@faker-js/faker/locale/de' +// or, if desiring a different locale +// import { fakerDE as faker } from '@faker-js/faker' const randomName = faker.person.fullName(); // Rowan Nikolaus const randomEmail = faker.internet.email(); // Kassandra.Haley@erich.biz ``` -:::tip Note -Using the first import statement will load every locale into memory. -As such, start-up times and performance may be slow. -Thus, by declaring a locale in the import, one can increase performance and reduce the time on start-up. -::: - Or if you're using CommonJS: ```js @@ -27,6 +21,8 @@ const randomName = faker.person.fullName(); // Rowan Nikolaus const randomEmail = faker.internet.email(); // Kassandra.Haley@erich.biz ``` +For more information about changing and customizing the locales, please refer to our [Localization Guide](localization). + ## Browser ```html diff --git a/scripts/apidoc/typedoc.ts b/scripts/apidoc/typedoc.ts index 43b2ac88c86..b408b7ce0d4 100644 --- a/scripts/apidoc/typedoc.ts +++ b/scripts/apidoc/typedoc.ts @@ -94,7 +94,9 @@ export function selectApiModules( export function selectApiMethods( module: DeclarationReflection ): DeclarationReflection[] { - return module.getChildrenByKind(ReflectionKind.Method); + return module + .getChildrenByKind(ReflectionKind.Method) + .filter((method) => !method.flags.isPrivate); } /** diff --git a/scripts/bundle.ts b/scripts/bundle.ts index e08b7de4378..9f8038cb07b 100644 --- a/scripts/bundle.ts +++ b/scripts/bundle.ts @@ -1,7 +1,7 @@ import { buildSync } from 'esbuild'; import { sync as globSync } from 'glob'; import { existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs'; -import locales from '../src/locales'; +import { allLocales } from '../src'; console.log('Building dist for node (cjs)...'); @@ -14,7 +14,7 @@ if (existsSync(localeDir)) { } mkdirSync(localeDir); -for (const locale of Object.keys(locales)) { +for (const locale of Object.keys(allLocales)) { writeFileSync( `${localeDir}/${locale}.js`, `module.exports = require('../dist/cjs/locale/${locale}');\n`, @@ -43,7 +43,7 @@ console.log('Building dist for node type=module (esm)...'); buildSync({ entryPoints: [ './src/index.ts', - ...Object.keys(locales).map((locale) => `./src/locale/${locale}.ts`), + ...Object.keys(allLocales).map((locale) => `./src/locale/${locale}.ts`), ], outdir: './dist/esm', bundle: true, diff --git a/scripts/generateLocales.ts b/scripts/generateLocales.ts index 571815899c9..d8fa1be13a2 100644 --- a/scripts/generateLocales.ts +++ b/scripts/generateLocales.ts @@ -12,7 +12,13 @@ * * Run this script using `pnpm run generate:locales` */ -import { lstatSync, readdirSync, readFileSync, writeFileSync } from 'node:fs'; +import { + existsSync, + lstatSync, + readdirSync, + readFileSync, + writeFileSync, +} from 'node:fs'; import { resolve } from 'node:path'; import type { Options } from 'prettier'; import { format } from 'prettier'; @@ -24,6 +30,7 @@ import type { Definitions, LocaleDefinition } from '../src/definitions'; const pathRoot = resolve(__dirname, '..'); const pathLocale = resolve(pathRoot, 'src', 'locale'); const pathLocales = resolve(pathRoot, 'src', 'locales'); +const pathLocaleIndex = resolve(pathLocale, 'index.ts'); const pathLocalesIndex = resolve(pathLocales, 'index.ts'); const pathDocsGuideLocalization = resolve( pathRoot, @@ -108,19 +115,31 @@ function escapeField(parent: string, module: string): string { } function generateLocaleFile(locale: string): void { + const parts = locale.split('_'); + const locales = [locale]; + + for (let i = parts.length - 1; i > 0; i--) { + const fallback = parts.slice(0, i).join('_'); + if (existsSync(resolve(pathLocales, fallback))) { + locales.push(fallback); + } + } + + if (locales[locales.length - 1] !== 'en') { + locales.push('en'); + } + let content = ` ${autoGeneratedCommentHeader} import { Faker } from '../faker'; - import ${locale} from '../locales/${locale}'; - ${locale !== 'en' ? "import en from '../locales/en';" : ''} + ${locales + .map((imp) => `import ${imp} from '../locales/${imp}';`) + .join('\n')} export const faker = new Faker({ - locale: '${locale}', - localeFallback: 'en', - locales: { - ${locale}, - ${locale !== 'en' ? 'en,' : ''} + locale: ${ + locales.length === 1 ? locales[0] : `[${locales.join(', ')}]` }, }); `; @@ -275,11 +294,12 @@ function updateLocaleFileHook( const locales = readdirSync(pathLocales); removeIndexTs(locales); -let localeIndexImports = "import type { LocaleDefinition } from '..';\n"; -let localeIndexType = 'export type KnownLocale =\n'; -let localeIndexLocales = 'const locales: KnownLocales = {\n'; +let localeIndexImports = ''; +let localeIndexExportsIndividual = ''; +let localeIndexExportsGrouped = ''; +let localesIndexExports = ''; -let localizationLocales = '| Locale | Name |\n| :--- | :--- |\n'; +let localizationLocales = '| Locale | Name | Faker |\n| :--- | :--- | :--- |\n'; for (const locale of locales) { const pathModules = resolve(pathLocales, locale); @@ -288,10 +308,15 @@ for (const locale of locales) { // We use a fallback here to at least generate a working file. const localeTitle = localeDef?.title ?? `TODO: Insert Title for ${locale}`; - localeIndexImports += `import ${locale} from './${locale}';\n`; - localeIndexType += ` | '${locale}'\n`; - localeIndexLocales += ` ${locale},\n`; - localizationLocales += `| ${locale} | ${localeTitle} |\n`; + const localizedFaker = `faker${locale.replace(/^([a-z]+)/, (part) => + part.toUpperCase() + )}`; + + localeIndexImports += `import { faker as ${localizedFaker} } from './${locale}';\n`; + localeIndexExportsIndividual += ` ${localizedFaker},\n`; + localeIndexExportsGrouped += ` ${locale}: ${localizedFaker},\n`; + localesIndexExports += `export { default as ${locale} } from './${locale}';\n`; + localizationLocales += `| \`${locale}\` | ${localeTitle} | \`${localizedFaker}\` |\n`; // src/locale/.ts generateLocaleFile(locale); @@ -306,24 +331,35 @@ for (const locale of locales) { ); } -// src/locales/index.ts +// src/locale/index.ts -let indexContent = ` +let localeIndexContent = ` ${autoGeneratedCommentHeader} ${localeIndexImports} - ${localeIndexType}; + export { + ${localeIndexExportsIndividual} + }; + + export const allFakers = { + ${localeIndexExportsGrouped} + } as const; + `; + +localeIndexContent = format(localeIndexContent, prettierTsOptions); +writeFileSync(pathLocaleIndex, localeIndexContent); - export type KnownLocales = Record; +// src/locales/index.ts - ${localeIndexLocales}}; +let localesIndexContent = ` + ${autoGeneratedCommentHeader} - export default locales; + ${localesIndexExports} `; -indexContent = format(indexContent, prettierTsOptions); -writeFileSync(pathLocalesIndex, indexContent); +localesIndexContent = format(localesIndexContent, prettierTsOptions); +writeFileSync(pathLocalesIndex, localesIndexContent); // docs/guide/localization.md diff --git a/src/faker.ts b/src/faker.ts index a60728959df..6a23cffd681 100644 --- a/src/faker.ts +++ b/src/faker.ts @@ -3,7 +3,6 @@ import { FakerError } from './errors/faker-error'; import { deprecated } from './internal/deprecated'; import type { Mersenne } from './internal/mersenne/mersenne'; import mersenne from './internal/mersenne/mersenne'; -import type { KnownLocale } from './locales'; import { AirlineModule } from './modules/airline'; import { AnimalModule } from './modules/animal'; import { ColorModule } from './modules/color'; @@ -32,53 +31,12 @@ import { StringModule } from './modules/string'; import { SystemModule } from './modules/system'; import { VehicleModule } from './modules/vehicle'; import { WordModule } from './modules/word'; -import type { LiteralUnion } from './utils/types'; - -export type UsableLocale = LiteralUnion; -export type UsedLocales = Partial>; - -export interface FakerOptions { - locales: UsedLocales; - locale?: UsableLocale; - localeFallback?: UsableLocale; -} - -const metadataKeys: ReadonlyArray = ['title']; +import { mergeLocales } from './utils/merge-locales'; export class Faker { - locales: UsedLocales; - private _locale: UsableLocale; - private _localeFallback: UsableLocale; + readonly definitions: LocaleDefinition; private _defaultRefDate: () => Date = () => new Date(); - get locale(): UsableLocale { - return this._locale; - } - - set locale(locale: UsableLocale) { - if (!this.locales[locale]) { - throw new FakerError( - `Locale ${locale} is not supported. You might want to add the requested locale first to \`faker.locales\`.` - ); - } - - this._locale = locale; - } - - get localeFallback(): UsableLocale { - return this._localeFallback; - } - - set localeFallback(localeFallback: UsableLocale) { - if (!this.locales[localeFallback]) { - throw new FakerError( - `Locale ${localeFallback} is not supported. You might want to add the requested locale first to \`faker.locales\`.` - ); - } - - this._localeFallback = localeFallback; - } - /** * Gets a new reference date used to generate relative dates. */ @@ -103,8 +61,6 @@ export class Faker { } } - readonly definitions: LocaleDefinition = this.initDefinitions(); - /** @internal */ private readonly _mersenne: Mersenne = mersenne(); @@ -161,91 +117,88 @@ export class Faker { return this.person; } - constructor(opts: FakerOptions) { - if (!opts) { - throw new FakerError( - 'Options with at least one entry in locales must be provided' - ); - } - - if (Object.keys(opts.locales ?? {}).length === 0) { - throw new FakerError( - 'At least one entry in locales must be provided in the locales parameter' - ); - } - - this.locales = opts.locales; - this.locale = opts.locale || 'en'; - this.localeFallback = opts.localeFallback || 'en'; - } - /** - * Creates a Proxy based LocaleDefinition that virtually merges the locales. + * Creates a new instance of Faker. + * + * @param options The options to use. + * @param options.locale The locale data to use. */ - private initDefinitions(): LocaleDefinition { - // Returns the first LocaleDefinition[key] in any locale - const resolveBaseData = (key: keyof LocaleDefinition): unknown => - this.locales[this.locale][key] ?? this.locales[this.localeFallback][key]; + constructor(options: { + /** + * The locale data to use for this instance. + * If an array is provided, the first locale that has a definition for a given property will be used. + * + * @see mergeLocales + */ + locale: LocaleDefinition | LocaleDefinition[]; + }); + /** + * Creates a new instance of Faker. + * + * @param options The options to use. + * @param options.locales The locale data to use. + * @param options.locale The locale data to use. + * + * @deprecated Use `new Faker({ locale: [locale, localeFallback] })` instead. + */ + constructor(options: { + locales: Record; + locale?: string; + localeFallback?: string; + }); + // This is somehow required for `ConstructorParameters[0]` to work + constructor( + options: + | { locale: LocaleDefinition | LocaleDefinition[] } + | { + locales: Record; + locale?: string; + localeFallback?: string; + } + ); + constructor( + options: + | { locale: LocaleDefinition | LocaleDefinition[] } + | { + locales: Record; + locale?: string; + localeFallback?: string; + } + ) { + const { locales } = options as { + locales: Record; + }; + if (locales != null) { + deprecated({ + deprecated: + "new Faker({ locales: {a, b}, locale: 'a', localeFallback: 'b' })", + proposed: + 'new Faker({ locale: [a, b, ...] }) or new Faker({ locale: a })', + since: '8.0', + until: '9.0', + }); + const { locale = 'en', localeFallback = 'en' } = options as { + locale: string; + localeFallback: string; + }; + options = { + locale: [locales[locale], locales[localeFallback]], + }; + } - // Returns the first LocaleDefinition[module][entry] in any locale - const resolveModuleData = ( - module: keyof LocaleDefinition, - entry: string - ): unknown => - this.locales[this.locale][module]?.[entry] ?? - this.locales[this.localeFallback][module]?.[entry]; + let { locale } = options; - // Returns a proxy that can return the entries for a module (if it exists) - const moduleLoader = ( - module: keyof LocaleDefinition - ): Record | undefined => { - if (resolveBaseData(module)) { - return new Proxy( - {}, - { - get(target, entry: string): unknown { - return resolveModuleData(module, entry); - }, - } + if (Array.isArray(locale)) { + if (locale.length === 0) { + throw new FakerError( + 'The locale option must contain at least one locale definition.' ); - } else { - return undefined; } - }; - return new Proxy({} as LocaleDefinition, { - get(target: LocaleDefinition, module: string): unknown { - // Support aliases - if (module === 'address') { - module = 'location'; - deprecated({ - deprecated: `faker.helpers.fake('{{address.*}}') or faker.definitions.address`, - proposed: `faker.helpers.fake('{{location.*}}') or faker.definitions.location`, - since: '8.0', - until: '10.0', - }); - } else if (module === 'name') { - module = 'person'; - deprecated({ - deprecated: `faker.helpers.fake('{{name.*}}') or faker.definitions.name`, - proposed: `faker.helpers.fake('{{person.*}}') or faker.definitions.person`, - since: '8.0', - until: '10.0', - }); - } + locale = mergeLocales(locale); + } - let result = target[module]; - if (result) { - return result; - } else if (metadataKeys.includes(module)) { - return resolveBaseData(module); - } else { - result = moduleLoader(module); - target[module] = result; - return result; - } - }, - }); + this.definitions = locale as LocaleDefinition; } /** @@ -320,12 +273,84 @@ export class Faker { return seed; } + // Pure JS backwards compatibility + + /** + * Do NOT use. This property has been removed. + * + * @deprecated Use the constructor instead. + */ + private get locales(): never { + throw new FakerError( + 'The locales property has been removed. Please use the constructor instead.' + ); + } + + /** + * Do NOT use. This property has been removed. + * + * @deprecated Use the constructor instead. + */ + private set locales(value: never) { + throw new FakerError( + 'The locales property has been removed. Please use the constructor instead.' + ); + } + + /** + * Do NOT use. This property has been removed. + * + * @deprecated Use the constructor instead. + */ + private get locale(): never { + throw new FakerError( + 'The locale property has been removed. Please use the constructor instead.' + ); + } + /** - * Set Faker's locale + * Do NOT use. This property has been removed. * - * @param locale The locale to set (e.g. `en` or `en_AU`, `en_AU_ocker`). + * @deprecated Use the constructor instead. */ - setLocale(locale: UsableLocale): void { - this.locale = locale; + private set locale(value: never) { + throw new FakerError( + 'The locale property has been removed. Please use the constructor instead.' + ); + } + + /** + * Do NOT use. This property has been removed. + * + * @deprecated Use the constructor instead. + */ + private get localeFallback(): never { + throw new FakerError( + 'The localeFallback property has been removed. Please use the constructor instead.' + ); + } + + /** + * Do NOT use. This property has been removed. + * + * @deprecated Use the constructor instead. + */ + private set localeFallback(value: never) { + throw new FakerError( + 'The localeFallback property has been removed. Please use the constructor instead.' + ); + } + + /** + * Do NOT use. This property has been removed. + * + * @deprecated Use the constructor instead. + */ + private setLocale(): never { + throw new FakerError( + 'This method has been removed. Please use the constructor instead.' + ); } } + +export type FakerOptions = ConstructorParameters[0]; diff --git a/src/index.ts b/src/index.ts index 2007df1ebaa..27923560bdc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,3 @@ -import { Faker } from './faker'; -import allLocales from './locales'; - export type { AirlineDefinitions, AnimalDefinitions, @@ -34,7 +31,12 @@ export type { WordDefinitions, } from './definitions'; export { FakerError } from './errors/faker-error'; -export type { FakerOptions, UsableLocale, UsedLocales } from './faker'; +export { Faker } from './faker'; +export type { FakerOptions } from './faker'; +export * from './locale'; +export { fakerEN as faker } from './locale'; +export * from './locales'; +export * as allLocales from './locales'; export { Aircraft, AircraftType } from './modules/airline'; export type { AirlineModule } from './modules/airline'; export type { AnimalModule } from './modules/animal'; @@ -81,9 +83,3 @@ export type { SystemModule } from './modules/system'; export type { VehicleModule } from './modules/vehicle'; export type { WordModule } from './modules/word'; export { mergeLocales } from './utils/merge-locales'; -export { Faker }; - -// since we are requiring the top level of faker, load all locales by default -export const faker: Faker = new Faker({ - locales: allLocales, -}); diff --git a/src/locale/af_ZA.ts b/src/locale/af_ZA.ts index 93ac1bcf743..17e0a692a28 100644 --- a/src/locale/af_ZA.ts +++ b/src/locale/af_ZA.ts @@ -8,10 +8,5 @@ import af_ZA from '../locales/af_ZA'; import en from '../locales/en'; export const faker = new Faker({ - locale: 'af_ZA', - localeFallback: 'en', - locales: { - af_ZA, - en, - }, + locale: [af_ZA, en], }); diff --git a/src/locale/ar.ts b/src/locale/ar.ts index 83eb41683df..2874a6fb69d 100644 --- a/src/locale/ar.ts +++ b/src/locale/ar.ts @@ -8,10 +8,5 @@ import ar from '../locales/ar'; import en from '../locales/en'; export const faker = new Faker({ - locale: 'ar', - localeFallback: 'en', - locales: { - ar, - en, - }, + locale: [ar, en], }); diff --git a/src/locale/az.ts b/src/locale/az.ts index b7b1fd6fb57..7b11a6a90e8 100644 --- a/src/locale/az.ts +++ b/src/locale/az.ts @@ -8,10 +8,5 @@ import az from '../locales/az'; import en from '../locales/en'; export const faker = new Faker({ - locale: 'az', - localeFallback: 'en', - locales: { - az, - en, - }, + locale: [az, en], }); diff --git a/src/locale/cz.ts b/src/locale/cz.ts index f6932b0b1dc..c2f85800d7c 100644 --- a/src/locale/cz.ts +++ b/src/locale/cz.ts @@ -8,10 +8,5 @@ import cz from '../locales/cz'; import en from '../locales/en'; export const faker = new Faker({ - locale: 'cz', - localeFallback: 'en', - locales: { - cz, - en, - }, + locale: [cz, en], }); diff --git a/src/locale/de.ts b/src/locale/de.ts index 47bd5794c37..09ff3bfa986 100644 --- a/src/locale/de.ts +++ b/src/locale/de.ts @@ -8,10 +8,5 @@ import de from '../locales/de'; import en from '../locales/en'; export const faker = new Faker({ - locale: 'de', - localeFallback: 'en', - locales: { - de, - en, - }, + locale: [de, en], }); diff --git a/src/locale/de_AT.ts b/src/locale/de_AT.ts index 1060b041048..b02b50cb559 100644 --- a/src/locale/de_AT.ts +++ b/src/locale/de_AT.ts @@ -4,14 +4,10 @@ */ import { Faker } from '../faker'; +import de from '../locales/de'; import de_AT from '../locales/de_AT'; import en from '../locales/en'; export const faker = new Faker({ - locale: 'de_AT', - localeFallback: 'en', - locales: { - de_AT, - en, - }, + locale: [de_AT, de, en], }); diff --git a/src/locale/de_CH.ts b/src/locale/de_CH.ts index 2e6b84805a6..5b866437292 100644 --- a/src/locale/de_CH.ts +++ b/src/locale/de_CH.ts @@ -4,14 +4,10 @@ */ import { Faker } from '../faker'; +import de from '../locales/de'; import de_CH from '../locales/de_CH'; import en from '../locales/en'; export const faker = new Faker({ - locale: 'de_CH', - localeFallback: 'en', - locales: { - de_CH, - en, - }, + locale: [de_CH, de, en], }); diff --git a/src/locale/dv.ts b/src/locale/dv.ts index 620cb2b996e..3d996cc14b6 100644 --- a/src/locale/dv.ts +++ b/src/locale/dv.ts @@ -8,10 +8,5 @@ import dv from '../locales/dv'; import en from '../locales/en'; export const faker = new Faker({ - locale: 'dv', - localeFallback: 'en', - locales: { - dv, - en, - }, + locale: [dv, en], }); diff --git a/src/locale/el.ts b/src/locale/el.ts index 0292c6015ba..119403b622c 100644 --- a/src/locale/el.ts +++ b/src/locale/el.ts @@ -8,10 +8,5 @@ import el from '../locales/el'; import en from '../locales/en'; export const faker = new Faker({ - locale: 'el', - localeFallback: 'en', - locales: { - el, - en, - }, + locale: [el, en], }); diff --git a/src/locale/en.ts b/src/locale/en.ts index b857f0ae12e..1d7db9f5061 100644 --- a/src/locale/en.ts +++ b/src/locale/en.ts @@ -7,9 +7,5 @@ import { Faker } from '../faker'; import en from '../locales/en'; export const faker = new Faker({ - locale: 'en', - localeFallback: 'en', - locales: { - en, - }, + locale: en, }); diff --git a/src/locale/en_AU.ts b/src/locale/en_AU.ts index 33d41c4cdaa..01ad19ad394 100644 --- a/src/locale/en_AU.ts +++ b/src/locale/en_AU.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import en_AU from '../locales/en_AU'; export const faker = new Faker({ - locale: 'en_AU', - localeFallback: 'en', - locales: { - en_AU, - en, - }, + locale: [en_AU, en], }); diff --git a/src/locale/en_AU_ocker.ts b/src/locale/en_AU_ocker.ts index 735c3e2c825..22c9ae3254e 100644 --- a/src/locale/en_AU_ocker.ts +++ b/src/locale/en_AU_ocker.ts @@ -5,13 +5,9 @@ import { Faker } from '../faker'; import en from '../locales/en'; +import en_AU from '../locales/en_AU'; import en_AU_ocker from '../locales/en_AU_ocker'; export const faker = new Faker({ - locale: 'en_AU_ocker', - localeFallback: 'en', - locales: { - en_AU_ocker, - en, - }, + locale: [en_AU_ocker, en_AU, en], }); diff --git a/src/locale/en_BORK.ts b/src/locale/en_BORK.ts index 962f26196e6..d8776851a06 100644 --- a/src/locale/en_BORK.ts +++ b/src/locale/en_BORK.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import en_BORK from '../locales/en_BORK'; export const faker = new Faker({ - locale: 'en_BORK', - localeFallback: 'en', - locales: { - en_BORK, - en, - }, + locale: [en_BORK, en], }); diff --git a/src/locale/en_CA.ts b/src/locale/en_CA.ts index 5b64a4eef2f..a1c2d158443 100644 --- a/src/locale/en_CA.ts +++ b/src/locale/en_CA.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import en_CA from '../locales/en_CA'; export const faker = new Faker({ - locale: 'en_CA', - localeFallback: 'en', - locales: { - en_CA, - en, - }, + locale: [en_CA, en], }); diff --git a/src/locale/en_GB.ts b/src/locale/en_GB.ts index 7cd2caba336..411c08234e2 100644 --- a/src/locale/en_GB.ts +++ b/src/locale/en_GB.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import en_GB from '../locales/en_GB'; export const faker = new Faker({ - locale: 'en_GB', - localeFallback: 'en', - locales: { - en_GB, - en, - }, + locale: [en_GB, en], }); diff --git a/src/locale/en_GH.ts b/src/locale/en_GH.ts index d6effe2a31c..a131a786f03 100644 --- a/src/locale/en_GH.ts +++ b/src/locale/en_GH.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import en_GH from '../locales/en_GH'; export const faker = new Faker({ - locale: 'en_GH', - localeFallback: 'en', - locales: { - en_GH, - en, - }, + locale: [en_GH, en], }); diff --git a/src/locale/en_IE.ts b/src/locale/en_IE.ts index 85afdb64dbe..b66c6a45529 100644 --- a/src/locale/en_IE.ts +++ b/src/locale/en_IE.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import en_IE from '../locales/en_IE'; export const faker = new Faker({ - locale: 'en_IE', - localeFallback: 'en', - locales: { - en_IE, - en, - }, + locale: [en_IE, en], }); diff --git a/src/locale/en_IN.ts b/src/locale/en_IN.ts index bb7c21d7fc6..28eb2333257 100644 --- a/src/locale/en_IN.ts +++ b/src/locale/en_IN.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import en_IN from '../locales/en_IN'; export const faker = new Faker({ - locale: 'en_IN', - localeFallback: 'en', - locales: { - en_IN, - en, - }, + locale: [en_IN, en], }); diff --git a/src/locale/en_NG.ts b/src/locale/en_NG.ts index 32802c49716..a5a9b5b1cf7 100644 --- a/src/locale/en_NG.ts +++ b/src/locale/en_NG.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import en_NG from '../locales/en_NG'; export const faker = new Faker({ - locale: 'en_NG', - localeFallback: 'en', - locales: { - en_NG, - en, - }, + locale: [en_NG, en], }); diff --git a/src/locale/en_US.ts b/src/locale/en_US.ts index 558bf4a3dc2..8077c573a56 100644 --- a/src/locale/en_US.ts +++ b/src/locale/en_US.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import en_US from '../locales/en_US'; export const faker = new Faker({ - locale: 'en_US', - localeFallback: 'en', - locales: { - en_US, - en, - }, + locale: [en_US, en], }); diff --git a/src/locale/en_ZA.ts b/src/locale/en_ZA.ts index 94f6d76e84c..3e5b31634ed 100644 --- a/src/locale/en_ZA.ts +++ b/src/locale/en_ZA.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import en_ZA from '../locales/en_ZA'; export const faker = new Faker({ - locale: 'en_ZA', - localeFallback: 'en', - locales: { - en_ZA, - en, - }, + locale: [en_ZA, en], }); diff --git a/src/locale/es.ts b/src/locale/es.ts index cf4d26c2f66..0f5116f2120 100644 --- a/src/locale/es.ts +++ b/src/locale/es.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import es from '../locales/es'; export const faker = new Faker({ - locale: 'es', - localeFallback: 'en', - locales: { - es, - en, - }, + locale: [es, en], }); diff --git a/src/locale/es_MX.ts b/src/locale/es_MX.ts index 96492e5615b..5a80a0f0028 100644 --- a/src/locale/es_MX.ts +++ b/src/locale/es_MX.ts @@ -5,13 +5,9 @@ import { Faker } from '../faker'; import en from '../locales/en'; +import es from '../locales/es'; import es_MX from '../locales/es_MX'; export const faker = new Faker({ - locale: 'es_MX', - localeFallback: 'en', - locales: { - es_MX, - en, - }, + locale: [es_MX, es, en], }); diff --git a/src/locale/fa.ts b/src/locale/fa.ts index 6d5a0944948..9a8c12de9ad 100644 --- a/src/locale/fa.ts +++ b/src/locale/fa.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import fa from '../locales/fa'; export const faker = new Faker({ - locale: 'fa', - localeFallback: 'en', - locales: { - fa, - en, - }, + locale: [fa, en], }); diff --git a/src/locale/fi.ts b/src/locale/fi.ts index 860ab5adf0f..06844df4eea 100644 --- a/src/locale/fi.ts +++ b/src/locale/fi.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import fi from '../locales/fi'; export const faker = new Faker({ - locale: 'fi', - localeFallback: 'en', - locales: { - fi, - en, - }, + locale: [fi, en], }); diff --git a/src/locale/fr.ts b/src/locale/fr.ts index d33c5d1c0b4..f9360a7e30c 100644 --- a/src/locale/fr.ts +++ b/src/locale/fr.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import fr from '../locales/fr'; export const faker = new Faker({ - locale: 'fr', - localeFallback: 'en', - locales: { - fr, - en, - }, + locale: [fr, en], }); diff --git a/src/locale/fr_BE.ts b/src/locale/fr_BE.ts index c9de78dccf7..41e2554de14 100644 --- a/src/locale/fr_BE.ts +++ b/src/locale/fr_BE.ts @@ -5,13 +5,9 @@ import { Faker } from '../faker'; import en from '../locales/en'; +import fr from '../locales/fr'; import fr_BE from '../locales/fr_BE'; export const faker = new Faker({ - locale: 'fr_BE', - localeFallback: 'en', - locales: { - fr_BE, - en, - }, + locale: [fr_BE, fr, en], }); diff --git a/src/locale/fr_CA.ts b/src/locale/fr_CA.ts index 573181a3366..77e9a22784e 100644 --- a/src/locale/fr_CA.ts +++ b/src/locale/fr_CA.ts @@ -5,13 +5,9 @@ import { Faker } from '../faker'; import en from '../locales/en'; +import fr from '../locales/fr'; import fr_CA from '../locales/fr_CA'; export const faker = new Faker({ - locale: 'fr_CA', - localeFallback: 'en', - locales: { - fr_CA, - en, - }, + locale: [fr_CA, fr, en], }); diff --git a/src/locale/fr_CH.ts b/src/locale/fr_CH.ts index 3a914e43452..fc61a9f512b 100644 --- a/src/locale/fr_CH.ts +++ b/src/locale/fr_CH.ts @@ -5,13 +5,9 @@ import { Faker } from '../faker'; import en from '../locales/en'; +import fr from '../locales/fr'; import fr_CH from '../locales/fr_CH'; export const faker = new Faker({ - locale: 'fr_CH', - localeFallback: 'en', - locales: { - fr_CH, - en, - }, + locale: [fr_CH, fr, en], }); diff --git a/src/locale/fr_LU.ts b/src/locale/fr_LU.ts index 8e63bfdbf4a..c7bee2379c0 100644 --- a/src/locale/fr_LU.ts +++ b/src/locale/fr_LU.ts @@ -5,13 +5,9 @@ import { Faker } from '../faker'; import en from '../locales/en'; +import fr from '../locales/fr'; import fr_LU from '../locales/fr_LU'; export const faker = new Faker({ - locale: 'fr_LU', - localeFallback: 'en', - locales: { - fr_LU, - en, - }, + locale: [fr_LU, fr, en], }); diff --git a/src/locale/ge.ts b/src/locale/ge.ts index e1f05865403..f33a614acf9 100644 --- a/src/locale/ge.ts +++ b/src/locale/ge.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import ge from '../locales/ge'; export const faker = new Faker({ - locale: 'ge', - localeFallback: 'en', - locales: { - ge, - en, - }, + locale: [ge, en], }); diff --git a/src/locale/he.ts b/src/locale/he.ts index b4c1b9c9b1d..a7dca5f966d 100644 --- a/src/locale/he.ts +++ b/src/locale/he.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import he from '../locales/he'; export const faker = new Faker({ - locale: 'he', - localeFallback: 'en', - locales: { - he, - en, - }, + locale: [he, en], }); diff --git a/src/locale/hr.ts b/src/locale/hr.ts index d9aa1348012..a210046c9ed 100644 --- a/src/locale/hr.ts +++ b/src/locale/hr.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import hr from '../locales/hr'; export const faker = new Faker({ - locale: 'hr', - localeFallback: 'en', - locales: { - hr, - en, - }, + locale: [hr, en], }); diff --git a/src/locale/hu.ts b/src/locale/hu.ts index f9d9f55536a..de5613dc295 100644 --- a/src/locale/hu.ts +++ b/src/locale/hu.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import hu from '../locales/hu'; export const faker = new Faker({ - locale: 'hu', - localeFallback: 'en', - locales: { - hu, - en, - }, + locale: [hu, en], }); diff --git a/src/locale/hy.ts b/src/locale/hy.ts index 724c1406f68..d7d72c3b8e5 100644 --- a/src/locale/hy.ts +++ b/src/locale/hy.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import hy from '../locales/hy'; export const faker = new Faker({ - locale: 'hy', - localeFallback: 'en', - locales: { - hy, - en, - }, + locale: [hy, en], }); diff --git a/src/locale/id_ID.ts b/src/locale/id_ID.ts index eafc0c528e4..6f481d831f4 100644 --- a/src/locale/id_ID.ts +++ b/src/locale/id_ID.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import id_ID from '../locales/id_ID'; export const faker = new Faker({ - locale: 'id_ID', - localeFallback: 'en', - locales: { - id_ID, - en, - }, + locale: [id_ID, en], }); diff --git a/src/locale/index.ts b/src/locale/index.ts new file mode 100644 index 00000000000..8131e35546f --- /dev/null +++ b/src/locale/index.ts @@ -0,0 +1,188 @@ +/* + * This file is automatically generated. + * Run 'pnpm run generate:locales' to update. + */ + +import { faker as fakerAF_ZA } from './af_ZA'; +import { faker as fakerAR } from './ar'; +import { faker as fakerAZ } from './az'; +import { faker as fakerCZ } from './cz'; +import { faker as fakerDE } from './de'; +import { faker as fakerDE_AT } from './de_AT'; +import { faker as fakerDE_CH } from './de_CH'; +import { faker as fakerDV } from './dv'; +import { faker as fakerEL } from './el'; +import { faker as fakerEN } from './en'; +import { faker as fakerEN_AU } from './en_AU'; +import { faker as fakerEN_AU_ocker } from './en_AU_ocker'; +import { faker as fakerEN_BORK } from './en_BORK'; +import { faker as fakerEN_CA } from './en_CA'; +import { faker as fakerEN_GB } from './en_GB'; +import { faker as fakerEN_GH } from './en_GH'; +import { faker as fakerEN_IE } from './en_IE'; +import { faker as fakerEN_IN } from './en_IN'; +import { faker as fakerEN_NG } from './en_NG'; +import { faker as fakerEN_US } from './en_US'; +import { faker as fakerEN_ZA } from './en_ZA'; +import { faker as fakerES } from './es'; +import { faker as fakerES_MX } from './es_MX'; +import { faker as fakerFA } from './fa'; +import { faker as fakerFI } from './fi'; +import { faker as fakerFR } from './fr'; +import { faker as fakerFR_BE } from './fr_BE'; +import { faker as fakerFR_CA } from './fr_CA'; +import { faker as fakerFR_CH } from './fr_CH'; +import { faker as fakerFR_LU } from './fr_LU'; +import { faker as fakerGE } from './ge'; +import { faker as fakerHE } from './he'; +import { faker as fakerHR } from './hr'; +import { faker as fakerHU } from './hu'; +import { faker as fakerHY } from './hy'; +import { faker as fakerID_ID } from './id_ID'; +import { faker as fakerIT } from './it'; +import { faker as fakerJA } from './ja'; +import { faker as fakerKO } from './ko'; +import { faker as fakerLV } from './lv'; +import { faker as fakerMK } from './mk'; +import { faker as fakerNB_NO } from './nb_NO'; +import { faker as fakerNE } from './ne'; +import { faker as fakerNL } from './nl'; +import { faker as fakerNL_BE } from './nl_BE'; +import { faker as fakerPL } from './pl'; +import { faker as fakerPT_BR } from './pt_BR'; +import { faker as fakerPT_PT } from './pt_PT'; +import { faker as fakerRO } from './ro'; +import { faker as fakerRU } from './ru'; +import { faker as fakerSK } from './sk'; +import { faker as fakerSV } from './sv'; +import { faker as fakerTR } from './tr'; +import { faker as fakerUK } from './uk'; +import { faker as fakerUR } from './ur'; +import { faker as fakerVI } from './vi'; +import { faker as fakerZH_CN } from './zh_CN'; +import { faker as fakerZH_TW } from './zh_TW'; +import { faker as fakerZU_ZA } from './zu_ZA'; + +export { + fakerAF_ZA, + fakerAR, + fakerAZ, + fakerCZ, + fakerDE, + fakerDE_AT, + fakerDE_CH, + fakerDV, + fakerEL, + fakerEN, + fakerEN_AU, + fakerEN_AU_ocker, + fakerEN_BORK, + fakerEN_CA, + fakerEN_GB, + fakerEN_GH, + fakerEN_IE, + fakerEN_IN, + fakerEN_NG, + fakerEN_US, + fakerEN_ZA, + fakerES, + fakerES_MX, + fakerFA, + fakerFI, + fakerFR, + fakerFR_BE, + fakerFR_CA, + fakerFR_CH, + fakerFR_LU, + fakerGE, + fakerHE, + fakerHR, + fakerHU, + fakerHY, + fakerID_ID, + fakerIT, + fakerJA, + fakerKO, + fakerLV, + fakerMK, + fakerNB_NO, + fakerNE, + fakerNL, + fakerNL_BE, + fakerPL, + fakerPT_BR, + fakerPT_PT, + fakerRO, + fakerRU, + fakerSK, + fakerSV, + fakerTR, + fakerUK, + fakerUR, + fakerVI, + fakerZH_CN, + fakerZH_TW, + fakerZU_ZA, +}; + +export const allFakers = { + af_ZA: fakerAF_ZA, + ar: fakerAR, + az: fakerAZ, + cz: fakerCZ, + de: fakerDE, + de_AT: fakerDE_AT, + de_CH: fakerDE_CH, + dv: fakerDV, + el: fakerEL, + en: fakerEN, + en_AU: fakerEN_AU, + en_AU_ocker: fakerEN_AU_ocker, + en_BORK: fakerEN_BORK, + en_CA: fakerEN_CA, + en_GB: fakerEN_GB, + en_GH: fakerEN_GH, + en_IE: fakerEN_IE, + en_IN: fakerEN_IN, + en_NG: fakerEN_NG, + en_US: fakerEN_US, + en_ZA: fakerEN_ZA, + es: fakerES, + es_MX: fakerES_MX, + fa: fakerFA, + fi: fakerFI, + fr: fakerFR, + fr_BE: fakerFR_BE, + fr_CA: fakerFR_CA, + fr_CH: fakerFR_CH, + fr_LU: fakerFR_LU, + ge: fakerGE, + he: fakerHE, + hr: fakerHR, + hu: fakerHU, + hy: fakerHY, + id_ID: fakerID_ID, + it: fakerIT, + ja: fakerJA, + ko: fakerKO, + lv: fakerLV, + mk: fakerMK, + nb_NO: fakerNB_NO, + ne: fakerNE, + nl: fakerNL, + nl_BE: fakerNL_BE, + pl: fakerPL, + pt_BR: fakerPT_BR, + pt_PT: fakerPT_PT, + ro: fakerRO, + ru: fakerRU, + sk: fakerSK, + sv: fakerSV, + tr: fakerTR, + uk: fakerUK, + ur: fakerUR, + vi: fakerVI, + zh_CN: fakerZH_CN, + zh_TW: fakerZH_TW, + zu_ZA: fakerZU_ZA, +} as const; diff --git a/src/locale/it.ts b/src/locale/it.ts index b6df80e82c0..bff0a521691 100644 --- a/src/locale/it.ts +++ b/src/locale/it.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import it from '../locales/it'; export const faker = new Faker({ - locale: 'it', - localeFallback: 'en', - locales: { - it, - en, - }, + locale: [it, en], }); diff --git a/src/locale/ja.ts b/src/locale/ja.ts index f24109df83f..8a9a866c08c 100644 --- a/src/locale/ja.ts +++ b/src/locale/ja.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import ja from '../locales/ja'; export const faker = new Faker({ - locale: 'ja', - localeFallback: 'en', - locales: { - ja, - en, - }, + locale: [ja, en], }); diff --git a/src/locale/ko.ts b/src/locale/ko.ts index 64b0b3e7834..eaa9e3ff156 100644 --- a/src/locale/ko.ts +++ b/src/locale/ko.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import ko from '../locales/ko'; export const faker = new Faker({ - locale: 'ko', - localeFallback: 'en', - locales: { - ko, - en, - }, + locale: [ko, en], }); diff --git a/src/locale/lv.ts b/src/locale/lv.ts index 80ed9156cfd..dc9f432729c 100644 --- a/src/locale/lv.ts +++ b/src/locale/lv.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import lv from '../locales/lv'; export const faker = new Faker({ - locale: 'lv', - localeFallback: 'en', - locales: { - lv, - en, - }, + locale: [lv, en], }); diff --git a/src/locale/mk.ts b/src/locale/mk.ts index 91199ba497c..18981c46d7c 100644 --- a/src/locale/mk.ts +++ b/src/locale/mk.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import mk from '../locales/mk'; export const faker = new Faker({ - locale: 'mk', - localeFallback: 'en', - locales: { - mk, - en, - }, + locale: [mk, en], }); diff --git a/src/locale/nb_NO.ts b/src/locale/nb_NO.ts index ee4b561ced1..3dcc5a5cc31 100644 --- a/src/locale/nb_NO.ts +++ b/src/locale/nb_NO.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import nb_NO from '../locales/nb_NO'; export const faker = new Faker({ - locale: 'nb_NO', - localeFallback: 'en', - locales: { - nb_NO, - en, - }, + locale: [nb_NO, en], }); diff --git a/src/locale/ne.ts b/src/locale/ne.ts index ebc47246bb0..e75adb0c0a8 100644 --- a/src/locale/ne.ts +++ b/src/locale/ne.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import ne from '../locales/ne'; export const faker = new Faker({ - locale: 'ne', - localeFallback: 'en', - locales: { - ne, - en, - }, + locale: [ne, en], }); diff --git a/src/locale/nl.ts b/src/locale/nl.ts index c8f6a649dbb..3965b754bd8 100644 --- a/src/locale/nl.ts +++ b/src/locale/nl.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import nl from '../locales/nl'; export const faker = new Faker({ - locale: 'nl', - localeFallback: 'en', - locales: { - nl, - en, - }, + locale: [nl, en], }); diff --git a/src/locale/nl_BE.ts b/src/locale/nl_BE.ts index dd227f4e7f6..4b6cb7aac83 100644 --- a/src/locale/nl_BE.ts +++ b/src/locale/nl_BE.ts @@ -5,13 +5,9 @@ import { Faker } from '../faker'; import en from '../locales/en'; +import nl from '../locales/nl'; import nl_BE from '../locales/nl_BE'; export const faker = new Faker({ - locale: 'nl_BE', - localeFallback: 'en', - locales: { - nl_BE, - en, - }, + locale: [nl_BE, nl, en], }); diff --git a/src/locale/pl.ts b/src/locale/pl.ts index 44db8e40ab3..875ac5ec9d9 100644 --- a/src/locale/pl.ts +++ b/src/locale/pl.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import pl from '../locales/pl'; export const faker = new Faker({ - locale: 'pl', - localeFallback: 'en', - locales: { - pl, - en, - }, + locale: [pl, en], }); diff --git a/src/locale/pt_BR.ts b/src/locale/pt_BR.ts index 3711d3f6d7e..5a4725d4881 100644 --- a/src/locale/pt_BR.ts +++ b/src/locale/pt_BR.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import pt_BR from '../locales/pt_BR'; export const faker = new Faker({ - locale: 'pt_BR', - localeFallback: 'en', - locales: { - pt_BR, - en, - }, + locale: [pt_BR, en], }); diff --git a/src/locale/pt_PT.ts b/src/locale/pt_PT.ts index 915092abd3a..675e9adaf29 100644 --- a/src/locale/pt_PT.ts +++ b/src/locale/pt_PT.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import pt_PT from '../locales/pt_PT'; export const faker = new Faker({ - locale: 'pt_PT', - localeFallback: 'en', - locales: { - pt_PT, - en, - }, + locale: [pt_PT, en], }); diff --git a/src/locale/ro.ts b/src/locale/ro.ts index 2903e01dd2f..b9b36836bac 100644 --- a/src/locale/ro.ts +++ b/src/locale/ro.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import ro from '../locales/ro'; export const faker = new Faker({ - locale: 'ro', - localeFallback: 'en', - locales: { - ro, - en, - }, + locale: [ro, en], }); diff --git a/src/locale/ru.ts b/src/locale/ru.ts index 433342216bc..3e3602554de 100644 --- a/src/locale/ru.ts +++ b/src/locale/ru.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import ru from '../locales/ru'; export const faker = new Faker({ - locale: 'ru', - localeFallback: 'en', - locales: { - ru, - en, - }, + locale: [ru, en], }); diff --git a/src/locale/sk.ts b/src/locale/sk.ts index 2816c16e6c9..8f6573a9a6d 100644 --- a/src/locale/sk.ts +++ b/src/locale/sk.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import sk from '../locales/sk'; export const faker = new Faker({ - locale: 'sk', - localeFallback: 'en', - locales: { - sk, - en, - }, + locale: [sk, en], }); diff --git a/src/locale/sv.ts b/src/locale/sv.ts index 41c8f4e3643..b459b35d91b 100644 --- a/src/locale/sv.ts +++ b/src/locale/sv.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import sv from '../locales/sv'; export const faker = new Faker({ - locale: 'sv', - localeFallback: 'en', - locales: { - sv, - en, - }, + locale: [sv, en], }); diff --git a/src/locale/tr.ts b/src/locale/tr.ts index 0aa4a51a561..303089520fe 100644 --- a/src/locale/tr.ts +++ b/src/locale/tr.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import tr from '../locales/tr'; export const faker = new Faker({ - locale: 'tr', - localeFallback: 'en', - locales: { - tr, - en, - }, + locale: [tr, en], }); diff --git a/src/locale/uk.ts b/src/locale/uk.ts index ec40da8f4cc..fe35122d321 100644 --- a/src/locale/uk.ts +++ b/src/locale/uk.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import uk from '../locales/uk'; export const faker = new Faker({ - locale: 'uk', - localeFallback: 'en', - locales: { - uk, - en, - }, + locale: [uk, en], }); diff --git a/src/locale/ur.ts b/src/locale/ur.ts index f08be161b5c..dd853d28afd 100644 --- a/src/locale/ur.ts +++ b/src/locale/ur.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import ur from '../locales/ur'; export const faker = new Faker({ - locale: 'ur', - localeFallback: 'en', - locales: { - ur, - en, - }, + locale: [ur, en], }); diff --git a/src/locale/vi.ts b/src/locale/vi.ts index 96c888afea9..2525260a4df 100644 --- a/src/locale/vi.ts +++ b/src/locale/vi.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import vi from '../locales/vi'; export const faker = new Faker({ - locale: 'vi', - localeFallback: 'en', - locales: { - vi, - en, - }, + locale: [vi, en], }); diff --git a/src/locale/zh_CN.ts b/src/locale/zh_CN.ts index 207ede7716a..11c632652db 100644 --- a/src/locale/zh_CN.ts +++ b/src/locale/zh_CN.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import zh_CN from '../locales/zh_CN'; export const faker = new Faker({ - locale: 'zh_CN', - localeFallback: 'en', - locales: { - zh_CN, - en, - }, + locale: [zh_CN, en], }); diff --git a/src/locale/zh_TW.ts b/src/locale/zh_TW.ts index dd36aa2e3d0..7eefd1b6e83 100644 --- a/src/locale/zh_TW.ts +++ b/src/locale/zh_TW.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import zh_TW from '../locales/zh_TW'; export const faker = new Faker({ - locale: 'zh_TW', - localeFallback: 'en', - locales: { - zh_TW, - en, - }, + locale: [zh_TW, en], }); diff --git a/src/locale/zu_ZA.ts b/src/locale/zu_ZA.ts index df595ff2d86..145ff94a684 100644 --- a/src/locale/zu_ZA.ts +++ b/src/locale/zu_ZA.ts @@ -8,10 +8,5 @@ import en from '../locales/en'; import zu_ZA from '../locales/zu_ZA'; export const faker = new Faker({ - locale: 'zu_ZA', - localeFallback: 'en', - locales: { - zu_ZA, - en, - }, + locale: [zu_ZA, en], }); diff --git a/src/locales/index.ts b/src/locales/index.ts index 213442d34c5..f5f2ca0fb34 100644 --- a/src/locales/index.ts +++ b/src/locales/index.ts @@ -3,190 +3,62 @@ * Run 'pnpm run generate:locales' to update. */ -import type { LocaleDefinition } from '..'; -import af_ZA from './af_ZA'; -import ar from './ar'; -import az from './az'; -import cz from './cz'; -import de from './de'; -import de_AT from './de_AT'; -import de_CH from './de_CH'; -import dv from './dv'; -import el from './el'; -import en from './en'; -import en_AU from './en_AU'; -import en_AU_ocker from './en_AU_ocker'; -import en_BORK from './en_BORK'; -import en_CA from './en_CA'; -import en_GB from './en_GB'; -import en_GH from './en_GH'; -import en_IE from './en_IE'; -import en_IN from './en_IN'; -import en_NG from './en_NG'; -import en_US from './en_US'; -import en_ZA from './en_ZA'; -import es from './es'; -import es_MX from './es_MX'; -import fa from './fa'; -import fi from './fi'; -import fr from './fr'; -import fr_BE from './fr_BE'; -import fr_CA from './fr_CA'; -import fr_CH from './fr_CH'; -import fr_LU from './fr_LU'; -import ge from './ge'; -import he from './he'; -import hr from './hr'; -import hu from './hu'; -import hy from './hy'; -import id_ID from './id_ID'; -import it from './it'; -import ja from './ja'; -import ko from './ko'; -import lv from './lv'; -import mk from './mk'; -import nb_NO from './nb_NO'; -import ne from './ne'; -import nl from './nl'; -import nl_BE from './nl_BE'; -import pl from './pl'; -import pt_BR from './pt_BR'; -import pt_PT from './pt_PT'; -import ro from './ro'; -import ru from './ru'; -import sk from './sk'; -import sv from './sv'; -import tr from './tr'; -import uk from './uk'; -import ur from './ur'; -import vi from './vi'; -import zh_CN from './zh_CN'; -import zh_TW from './zh_TW'; -import zu_ZA from './zu_ZA'; - -export type KnownLocale = - | 'af_ZA' - | 'ar' - | 'az' - | 'cz' - | 'de' - | 'de_AT' - | 'de_CH' - | 'dv' - | 'el' - | 'en' - | 'en_AU' - | 'en_AU_ocker' - | 'en_BORK' - | 'en_CA' - | 'en_GB' - | 'en_GH' - | 'en_IE' - | 'en_IN' - | 'en_NG' - | 'en_US' - | 'en_ZA' - | 'es' - | 'es_MX' - | 'fa' - | 'fi' - | 'fr' - | 'fr_BE' - | 'fr_CA' - | 'fr_CH' - | 'fr_LU' - | 'ge' - | 'he' - | 'hr' - | 'hu' - | 'hy' - | 'id_ID' - | 'it' - | 'ja' - | 'ko' - | 'lv' - | 'mk' - | 'nb_NO' - | 'ne' - | 'nl' - | 'nl_BE' - | 'pl' - | 'pt_BR' - | 'pt_PT' - | 'ro' - | 'ru' - | 'sk' - | 'sv' - | 'tr' - | 'uk' - | 'ur' - | 'vi' - | 'zh_CN' - | 'zh_TW' - | 'zu_ZA'; - -export type KnownLocales = Record; - -const locales: KnownLocales = { - af_ZA, - ar, - az, - cz, - de, - de_AT, - de_CH, - dv, - el, - en, - en_AU, - en_AU_ocker, - en_BORK, - en_CA, - en_GB, - en_GH, - en_IE, - en_IN, - en_NG, - en_US, - en_ZA, - es, - es_MX, - fa, - fi, - fr, - fr_BE, - fr_CA, - fr_CH, - fr_LU, - ge, - he, - hr, - hu, - hy, - id_ID, - it, - ja, - ko, - lv, - mk, - nb_NO, - ne, - nl, - nl_BE, - pl, - pt_BR, - pt_PT, - ro, - ru, - sk, - sv, - tr, - uk, - ur, - vi, - zh_CN, - zh_TW, - zu_ZA, -}; - -export default locales; +export { default as af_ZA } from './af_ZA'; +export { default as ar } from './ar'; +export { default as az } from './az'; +export { default as cz } from './cz'; +export { default as de } from './de'; +export { default as de_AT } from './de_AT'; +export { default as de_CH } from './de_CH'; +export { default as dv } from './dv'; +export { default as el } from './el'; +export { default as en } from './en'; +export { default as en_AU } from './en_AU'; +export { default as en_AU_ocker } from './en_AU_ocker'; +export { default as en_BORK } from './en_BORK'; +export { default as en_CA } from './en_CA'; +export { default as en_GB } from './en_GB'; +export { default as en_GH } from './en_GH'; +export { default as en_IE } from './en_IE'; +export { default as en_IN } from './en_IN'; +export { default as en_NG } from './en_NG'; +export { default as en_US } from './en_US'; +export { default as en_ZA } from './en_ZA'; +export { default as es } from './es'; +export { default as es_MX } from './es_MX'; +export { default as fa } from './fa'; +export { default as fi } from './fi'; +export { default as fr } from './fr'; +export { default as fr_BE } from './fr_BE'; +export { default as fr_CA } from './fr_CA'; +export { default as fr_CH } from './fr_CH'; +export { default as fr_LU } from './fr_LU'; +export { default as ge } from './ge'; +export { default as he } from './he'; +export { default as hr } from './hr'; +export { default as hu } from './hu'; +export { default as hy } from './hy'; +export { default as id_ID } from './id_ID'; +export { default as it } from './it'; +export { default as ja } from './ja'; +export { default as ko } from './ko'; +export { default as lv } from './lv'; +export { default as mk } from './mk'; +export { default as nb_NO } from './nb_NO'; +export { default as ne } from './ne'; +export { default as nl } from './nl'; +export { default as nl_BE } from './nl_BE'; +export { default as pl } from './pl'; +export { default as pt_BR } from './pt_BR'; +export { default as pt_PT } from './pt_PT'; +export { default as ro } from './ro'; +export { default as ru } from './ru'; +export { default as sk } from './sk'; +export { default as sv } from './sv'; +export { default as tr } from './tr'; +export { default as uk } from './uk'; +export { default as ur } from './ur'; +export { default as vi } from './vi'; +export { default as zh_CN } from './zh_CN'; +export { default as zh_TW } from './zh_TW'; +export { default as zu_ZA } from './zu_ZA'; diff --git a/src/modules/location/index.ts b/src/modules/location/index.ts index 2025beaccf5..fb902588eb3 100644 --- a/src/modules/location/index.ts +++ b/src/modules/location/index.ts @@ -72,8 +72,8 @@ export class LocationModule { * If not specified, a random zip code is generated according to the locale's zip format. * * @example - * fakerUS.location.zipCodeByState("AK") // '99595' - * fakerUS.location.zipCodeByState("??") // '47683-9880' + * fakerEN_US.location.zipCodeByState("AK") // '99595' + * fakerEN_US.location.zipCodeByState("??") // '47683-9880' * * @since 8.0.0 */ @@ -107,7 +107,7 @@ export class LocationModule { * * @example * faker.location.city() // 'East Jarretmouth' - * faker.locale = 'de'; faker.location.city() // 'Bad Lilianadorf' + * fakerDE.location.city() // 'Bad Lilianadorf' * * @since 8.0.0 */ @@ -120,7 +120,7 @@ export class LocationModule { * * @example * faker.location.cityName() // 'San Rafael' - * faker.locale = 'de'; faker.location.cityName() // 'Nürnberg' + * fakerDE.location.cityName() // 'Nürnberg' * * @since 8.0.0 */ diff --git a/src/modules/random/index.ts b/src/modules/random/index.ts index bf1c4d22194..a2847bbc3d3 100644 --- a/src/modules/random/index.ts +++ b/src/modules/random/index.ts @@ -1,4 +1,5 @@ import type { Faker } from '../..'; +import { FakerError } from '../../errors/faker-error'; import { deprecated } from '../../internal/deprecated'; import type { LiteralUnion } from '../../utils/types'; import type { @@ -171,16 +172,21 @@ export class RandomModule { } /** - * Returns a random locale, that is available in this faker instance. - * You can use the returned locale with `faker.setLocale(result)`. + * Do NOT use. This property has been removed. * * @example - * faker.random.locale() // 'el' + * faker.helpers.objectKey(allLocales) + * faker.helpers.objectValue(allFakers) * * @since 3.1.0 + * + * @deprecated Use `faker.helpers.objectKey(allLocales/allFakers)` instead. */ - locale(): string { - return this.faker.helpers.arrayElement(Object.keys(this.faker.locales)); + private locale(): never { + // We cannot invoke this ourselves, because this would link to all locale data and increase the bundle size by a lot. + throw new FakerError( + 'This method has been removed. Please use `faker.helpers.objectKey(allLocales/allFakers)` instead.' + ); } /** diff --git a/test/__snapshots__/random.spec.ts.snap b/test/__snapshots__/random.spec.ts.snap index 2285503e372..3e725c204a7 100644 --- a/test/__snapshots__/random.spec.ts.snap +++ b/test/__snapshots__/random.spec.ts.snap @@ -8,8 +8,6 @@ exports[`random > 42 > alphaNumeric > noArgs 1`] = `"n"`; exports[`random > 42 > alphaNumeric > with length 1`] = `"nNWbJ"`; -exports[`random > 42 > locale 1`] = `"es_MX"`; - exports[`random > 42 > numeric > noArgs 1`] = `"3"`; exports[`random > 42 > numeric > with length 1`] = `"37917"`; @@ -30,8 +28,6 @@ exports[`random > 1211 > alphaNumeric > noArgs 1`] = `"V"`; exports[`random > 1211 > alphaNumeric > with length 1`] = `"VsTMd"`; -exports[`random > 1211 > locale 1`] = `"ur"`; - exports[`random > 1211 > numeric > noArgs 1`] = `"9"`; exports[`random > 1211 > numeric > with length 1`] = `"94872"`; @@ -52,8 +48,6 @@ exports[`random > 1337 > alphaNumeric > noArgs 1`] = `"g"`; exports[`random > 1337 > alphaNumeric > with length 1`] = `"gy9dh"`; -exports[`random > 1337 > locale 1`] = `"en_GH"`; - exports[`random > 1337 > numeric > noArgs 1`] = `"2"`; exports[`random > 1337 > numeric > with length 1`] = `"25122"`; diff --git a/test/airline.spec.ts b/test/airline.spec.ts index e8f996e1ded..95e4bef0c61 100644 --- a/test/airline.spec.ts +++ b/test/airline.spec.ts @@ -1,14 +1,10 @@ -import { afterEach, describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { Aircraft, faker } from '../src'; import { seededTests } from './support/seededRuns'; const NON_SEEDED_BASED_RUN = 5; describe('airline', () => { - afterEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'airline', (t) => { t.itEach('airport', 'airline', 'airplane', 'aircraftType'); t.describe('recordLocator', (t) => { diff --git a/test/all_functional.spec.ts b/test/all_functional.spec.ts index ae4ac991213..a938b61c972 100644 --- a/test/all_functional.spec.ts +++ b/test/all_functional.spec.ts @@ -1,14 +1,12 @@ import { describe, expect, it } from 'vitest'; -import { faker } from '../src'; -import type { KnownLocale } from '../src/locales'; +import type { allLocales, Faker, RandomModule } from '../src'; +import { allFakers, fakerEN } from '../src'; const IGNORED_MODULES = [ - 'locales', 'definitions', 'helpers', - '_locale', - '_localeFallback', '_mersenne', + '_defaultRefDate', ]; function isTestableModule(mod: string) { @@ -16,9 +14,13 @@ function isTestableModule(mod: string) { } function isMethodOf(mod: string) { - return (meth: string) => typeof faker[mod][meth] === 'function'; + return (meth: string) => typeof fakerEN[mod][meth] === 'function'; } +type SkipConfig = Partial< + Record> +>; + const BROKEN_LOCALE_METHODS = { // TODO ST-DDT 2022-03-28: these are TODOs (usually broken locale files) company: { @@ -29,6 +31,9 @@ const BROKEN_LOCALE_METHODS = { state: ['az', 'cz', 'nb_NO', 'sk'], stateAbbr: ['cz', 'sk'], }, + random: { + locale: '*', // locale() has been pseudo removed + } as SkipConfig, string: { fromCharacters: '*', }, @@ -36,7 +41,9 @@ const BROKEN_LOCALE_METHODS = { prefix: ['az', 'id_ID', 'ru', 'zh_CN', 'zh_TW'], suffix: ['az', 'it', 'mk', 'pt_PT', 'ru'], }, -} satisfies Record>; +} satisfies { + [module in keyof Faker]?: SkipConfig; +}; function isWorkingLocaleForMethod( mod: string, @@ -50,12 +57,12 @@ function isWorkingLocaleForMethod( // Basic smoke tests to make sure each method is at least implemented and returns a value. function modulesList(): { [module: string]: string[] } { - const modules = Object.keys(faker) + const modules = Object.keys(fakerEN) .sort() .filter(isTestableModule) .reduce((result, mod) => { // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - const methods = Object.keys(faker[mod]).filter(isMethodOf(mod)); + const methods = Object.keys(fakerEN[mod]).filter(isMethodOf(mod)); if (methods.length) { result[mod] = methods; } else { @@ -100,13 +107,12 @@ describe('BROKEN_LOCALE_METHODS test', () => { }); describe('functional tests', () => { - for (const locale in faker.locales) { + for (const [locale, faker] of Object.entries(allFakers)) { describe(locale, () => { Object.keys(modules).forEach((module) => { describe(module, () => { modules[module].forEach((meth) => { const testAssertion = () => { - faker.locale = locale; // TODO ST-DDT 2022-03-28: Use random seed once there are no more failures faker.seed(1); const result = faker[module][meth](); @@ -134,13 +140,12 @@ describe('functional tests', () => { }); describe('faker.helpers.fake functional tests', () => { - for (const locale in faker.locales) { + for (const [locale, faker] of Object.entries(allFakers)) { describe(locale, () => { Object.keys(modules).forEach((module) => { describe(module, () => { modules[module].forEach((meth) => { const testAssertion = () => { - faker.locale = locale; // TODO ST-DDT 2022-03-28: Use random seed once there are no more failures faker.seed(1); const result = faker.helpers.fake(`{{${module}.${meth}}}`); diff --git a/test/animal.spec.ts b/test/animal.spec.ts index 26c01e3132b..11532b89cc8 100644 --- a/test/animal.spec.ts +++ b/test/animal.spec.ts @@ -1,4 +1,4 @@ -import { afterEach, describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { faker } from '../src'; import { seededTests } from './support/seededRuns'; @@ -23,10 +23,6 @@ const functionNames = [ ] as const; describe('animal', () => { - afterEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'animal', (t) => { t.itEach(...functionNames); }); diff --git a/test/color.spec.ts b/test/color.spec.ts index 091d7ff0e37..29ce63ed0c7 100644 --- a/test/color.spec.ts +++ b/test/color.spec.ts @@ -1,4 +1,4 @@ -import { afterEach, describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { faker } from '../src'; import { CSS_FUNCTIONS, CSS_SPACES } from '../src/modules/color'; import { seededTests } from './support/seededRuns'; @@ -6,10 +6,6 @@ import { seededTests } from './support/seededRuns'; const NON_SEEDED_BASED_RUN = 5; describe('color', () => { - afterEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'color', (t) => { t.itEach( 'human', diff --git a/test/commerce.spec.ts b/test/commerce.spec.ts index 30b7dde1e47..7d081e497e0 100644 --- a/test/commerce.spec.ts +++ b/test/commerce.spec.ts @@ -1,14 +1,10 @@ -import { afterEach, describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { faker } from '../src'; import { seededTests } from './support/seededRuns'; const NON_SEEDED_BASED_RUN = 5; describe('commerce', () => { - afterEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'commerce', (t) => { t.itEach( 'department', diff --git a/test/company.spec.ts b/test/company.spec.ts index 211dfe9187c..703eb960171 100644 --- a/test/company.spec.ts +++ b/test/company.spec.ts @@ -1,14 +1,10 @@ -import { afterEach, describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { faker } from '../src'; import { seededTests } from './support/seededRuns'; const NON_SEEDED_BASED_RUN = 5; describe('company', () => { - afterEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'company', (t) => { t.itEach( 'suffixes', diff --git a/test/database.spec.ts b/test/database.spec.ts index 80a1e2f1cc9..dacaa5cfd7e 100644 --- a/test/database.spec.ts +++ b/test/database.spec.ts @@ -1,14 +1,10 @@ -import { afterEach, describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { faker } from '../src'; import { seededTests } from './support/seededRuns'; const NON_SEEDED_BASED_RUN = 5; describe('database', () => { - afterEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'database', (t) => { t.itEach('column', 'type', 'collation', 'engine', 'mongodbObjectId'); }); diff --git a/test/date.spec.ts b/test/date.spec.ts index af55508c8bf..8133bc0ec79 100644 --- a/test/date.spec.ts +++ b/test/date.spec.ts @@ -12,10 +12,6 @@ const NON_SEEDED_BASED_RUN = 5; const refDate = '2021-02-21T17:09:15.711Z'; describe('date', () => { - afterEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'date', (t) => { t.describeEach( 'past', diff --git a/test/faker.spec.ts b/test/faker.spec.ts index 12121b9d073..92fa4b96ff3 100644 --- a/test/faker.spec.ts +++ b/test/faker.spec.ts @@ -1,51 +1,13 @@ import type { SpyInstance } from 'vitest'; -import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { describe, expect, it, vi } from 'vitest'; import { faker, Faker } from '../src'; import { FakerError } from '../src/errors/faker-error'; describe('faker', () => { - beforeEach(() => { - faker.locale = 'en'; - }); - - it('should throw error if no options passed', () => { - expect( - () => - // @ts-expect-error: mission options - new Faker() - ).toThrow( - new FakerError( - 'Options with at least one entry in locales must be provided' - ) - ); - }); - it('should throw error if no locales passed', () => { - expect( - () => - // @ts-expect-error: missing locales - new Faker({}) - ).toThrow( + expect(() => new Faker({ locale: [] })).toThrow( new FakerError( - 'At least one entry in locales must be provided in the locales parameter' - ) - ); - }); - - it('should throw error if locale is not known', () => { - const instance = new Faker({ locales: { en: { title: 'English' } } }); - expect(() => (instance.locale = 'unknown')).toThrow( - new FakerError( - 'Locale unknown is not supported. You might want to add the requested locale first to `faker.locales`.' - ) - ); - }); - - it('should throw error if localeFallback is not known', () => { - const instance = new Faker({ locales: { en: { title: 'English' } } }); - expect(() => (instance.localeFallback = 'unknown')).toThrow( - new FakerError( - 'Locale unknown is not supported. You might want to add the requested locale first to `faker.locales`.' + 'The locale option must contain at least one locale definition.' ) ); }); @@ -60,7 +22,7 @@ describe('faker', () => { // eslint-disable-next-line @typescript-eslint/no-var-requires require('..').faker; - new Faker({ locales: { en: { title: '' } } }); + new Faker({ locale: { title: '' } }); for (const spy of spies) { expect(spy).not.toHaveBeenCalled(); @@ -69,13 +31,6 @@ describe('faker', () => { }); describe('definitions', () => { - describe('title', () => { - it.each(Object.keys(faker.locales))('title (%s)', (locale) => { - faker.locale = locale; - expect(faker.definitions.title).toBe(faker.locales[locale].title); - }); - }); - it('locale definition accessability', () => { // Metadata expect(faker.definitions.title).toBeDefined(); diff --git a/test/finance.spec.ts b/test/finance.spec.ts index a0eebd2381b..41be4a017ff 100644 --- a/test/finance.spec.ts +++ b/test/finance.spec.ts @@ -1,5 +1,5 @@ import isValidBtcAddress from 'validator/lib/isBtcAddress'; -import { afterEach, describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { faker } from '../src'; import { FakerError } from '../src/errors/faker-error'; import ibanLib from '../src/modules/finance/iban'; @@ -9,10 +9,6 @@ import { seededTests } from './support/seededRuns'; const NON_SEEDED_BASED_RUN = 5; describe('finance', () => { - afterEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'finance', (t) => { t.itEach( 'accountName', diff --git a/test/git.spec.ts b/test/git.spec.ts index e7fcc37fb90..805b6bb6a14 100644 --- a/test/git.spec.ts +++ b/test/git.spec.ts @@ -1,5 +1,5 @@ import validator from 'validator'; -import { afterEach, describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { faker } from '../src'; import { seededTests } from './support/seededRuns'; @@ -8,10 +8,6 @@ const NON_SEEDED_BASED_RUN = 5; const refDate = '2020-01-01T00:00:00.000Z'; describe('git', () => { - afterEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'git', (t) => { t.itEach('branch', 'commitMessage'); diff --git a/test/hacker.spec.ts b/test/hacker.spec.ts index 9d40c63cfe6..02316fdf0e0 100644 --- a/test/hacker.spec.ts +++ b/test/hacker.spec.ts @@ -1,14 +1,10 @@ -import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { faker } from '../src'; import { seededTests } from './support/seededRuns'; const NON_SEEDED_BASED_RUN = 5; describe('hacker', () => { - afterEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'hacker', (t) => { t.itEach('abbreviation', 'adjective', 'noun', 'verb', 'ingverb', 'phrase'); }); @@ -16,10 +12,6 @@ describe('hacker', () => { describe(`random seeded tests for seed ${faker.seed()}`, () => { for (let i = 1; i <= NON_SEEDED_BASED_RUN; i++) { describe('abbreviation()', () => { - beforeEach(() => { - faker.locale = 'en'; - }); - it('should return a random abbreviation from array', () => { const abbreviation = faker.hacker.abbreviation(); @@ -30,10 +22,6 @@ describe('hacker', () => { }); describe('adjective', () => { - beforeEach(() => { - faker.locale = 'en'; - }); - it('should return a random adjective from array', () => { const adjective = faker.hacker.adjective(); @@ -44,10 +32,6 @@ describe('hacker', () => { }); describe('noun', () => { - beforeEach(() => { - faker.locale = 'en'; - }); - it('should return a random noun from array', () => { const noun = faker.hacker.noun(); @@ -58,10 +42,6 @@ describe('hacker', () => { }); describe('verb', () => { - beforeEach(() => { - faker.locale = 'en'; - }); - it('should return a random verb from array', () => { const verb = faker.hacker.verb(); @@ -72,10 +52,6 @@ describe('hacker', () => { }); describe('ingverb', () => { - beforeEach(() => { - faker.locale = 'en'; - }); - it('should return a random ingverb from array', () => { const ingverb = faker.hacker.ingverb(); @@ -86,10 +62,6 @@ describe('hacker', () => { }); describe('phrase', () => { - beforeEach(() => { - faker.locale = 'en'; - }); - it('should return a random phrase from array', () => { const phrase = faker.hacker.phrase(); diff --git a/test/helpers.spec.ts b/test/helpers.spec.ts index dcf0e48612f..2334c2a20de 100644 --- a/test/helpers.spec.ts +++ b/test/helpers.spec.ts @@ -1,4 +1,4 @@ -import { afterEach, describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { faker, FakerError } from '../src'; import { luhnCheck } from '../src/modules/helpers/luhn-check'; import { seededTests } from './support/seededRuns'; @@ -14,10 +14,6 @@ function customUniqueMethod(prefix: string = ''): string { } describe('helpers', () => { - afterEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'helpers', (t) => { t.describe('slugify', (t) => { t.it('noArgs').it('some string', 'hello world'); @@ -904,15 +900,25 @@ describe('helpers', () => { delete (faker.string as any).special; }); - it('should support deprecated aliases', () => { - expect(faker.definitions.person.first_name).toContain( - faker.helpers.fake('{{name.first_name}}') + it('should support deprecated module aliases', () => { + expect(faker.definitions.location.city_name).toContain( + faker.helpers.fake('{{address.cityName}}') ); expect(faker.definitions.person.first_name).toContain( faker.helpers.fake('{{name.firstName}}') ); }); + // TODO @ST-DDT 2023-01-17: Restore this test when the definitions proxy is restored: #893 + it.todo('should support deprecated definition aliases', () => { + expect(faker.definitions.location.city_name).toContain( + faker.helpers.fake('{{address.city_name}}') + ); + expect(faker.definitions.person.first_name).toContain( + faker.helpers.fake('{{name.first_name}}') + ); + }); + it('should not trim whitespace', () => { expect(faker.helpers.fake(' --- ')).toBe(' --- '); }); diff --git a/test/internet.spec.ts b/test/internet.spec.ts index 16b6a804196..c2d8fcb22d8 100644 --- a/test/internet.spec.ts +++ b/test/internet.spec.ts @@ -1,16 +1,12 @@ import validator from 'validator'; -import { afterEach, describe, expect, it } from 'vitest'; -import { faker } from '../src'; +import { describe, expect, it } from 'vitest'; +import { allFakers, faker } from '../src'; import { seededTests } from './support/seededRuns'; import { times } from './support/times'; const NON_SEEDED_BASED_RUN = 5; describe('internet', () => { - afterEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'internet', (t) => { t.itEach( 'avatar', @@ -110,19 +106,16 @@ describe('internet', () => { expect(faker.definitions.internet.free_email).toContain(suffix); }); - it('should return a valid email in every locale', () => { - for (const locale of Object.keys(faker.locales)) { - faker.setLocale(locale); - const email = faker.internet.email(); + it.each(Object.entries(allFakers))( + 'should return a valid email in %s', + (_, localeFaker) => { + const email = localeFaker.internet.email(); expect(email).toBeTruthy(); expect(email).toBeTypeOf('string'); - expect(email).toSatisfy( - validator.isEmail, - `locale: ${locale} has invalid email: ${email}` - ); + expect(email).toSatisfy(validator.isEmail); } - }); + ); it('should return an email with given firstName', () => { const email = faker.internet.email('Aiden.Harann55'); diff --git a/test/locale-data.spec.ts b/test/locale-data.spec.ts new file mode 100644 index 00000000000..3b9a2dd3879 --- /dev/null +++ b/test/locale-data.spec.ts @@ -0,0 +1,23 @@ +import { describe, expect, it } from 'vitest'; +import { allLocales } from '../src'; +import './vitest-extensions'; + +function checkLocaleData(data: unknown) { + if (Array.isArray(data)) { + it('should not have duplicate entries', () => { + expect(data).not.toContainDuplicates(); + }); + } else if (typeof data === 'object' && data != null) { + for (const [nestedKey, nestedData] of Object.entries(data)) { + describe(nestedKey, () => { + checkLocaleData(nestedData); + }); + } + } else { + it.skip(`primitives cannot be tested`); + } +} + +describe('locale-data', () => { + checkLocaleData(allLocales); +}); diff --git a/test/locale-imports.spec.ts b/test/locale-imports.spec.ts index 3fdbeed1d75..260bc65a057 100644 --- a/test/locale-imports.spec.ts +++ b/test/locale-imports.spec.ts @@ -1,21 +1,28 @@ import { describe, expect, it } from 'vitest'; -import allLocales from '../src/locales'; +import type { Faker } from '../src'; +import { allLocales } from '../src'; describe('locale imports', () => { for (const locale in allLocales) { it(`should be possible to directly require('@faker-js/faker/locale/${locale}')`, () => { // eslint-disable-next-line @typescript-eslint/no-var-requires - const { faker } = require(`../dist/cjs/locale/${locale}`); + const { faker } = require(`../dist/cjs/locale/${locale}`) as { + faker: Faker; + }; expect(faker).toBeDefined(); - expect(faker.locale).toBe(locale); + expect(faker.string.alpha()).toBeTypeOf('string'); + expect(faker.definitions.title).toBe(allLocales[locale].title); }); it(`should be possible to directly import('@faker-js/faker/locale/${locale}')`, async () => { - const { faker } = await import(`../dist/esm/locale/${locale}`); + const { faker } = (await import(`../dist/esm/locale/${locale}`)) as { + faker: Faker; + }; expect(faker).toBeDefined(); - expect(faker.locale).toBe(locale); + expect(faker.string.alpha()).toBeTypeOf('string'); + expect(faker.definitions.title).toBe(allLocales[locale].title); }); describe('Internal tests to cover `src/locale/*.ts`', () => { @@ -24,7 +31,8 @@ describe('locale imports', () => { const { faker } = require(`../locale/${locale}`); expect(faker).toBeDefined(); - expect(faker.locale).toBe(locale); + expect(faker.string.alpha()).toBeTypeOf('string'); + expect(faker.definitions.title).toBe(allLocales[locale].title); }); it(`should be possible to directly import('../src/locale/${locale}')`, async () => { @@ -32,7 +40,8 @@ describe('locale imports', () => { const { faker } = await import(`../src/locale/${locale}`); expect(faker).toBeDefined(); - expect(faker.locale).toBe(locale); + expect(faker.string.alpha()).toBeTypeOf('string'); + expect(faker.definitions.title).toBe(allLocales[locale].title); }); }); } diff --git a/test/locales.spec.ts b/test/locales.spec.ts deleted file mode 100644 index 4249f94ded1..00000000000 --- a/test/locales.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { describe, expect, it } from 'vitest'; -import { faker } from '../src'; -import allLocales from '../src/locales'; -import './vitest-extensions'; - -// Remark: actual use of locales functionality is currently tested in all.functional.js test - -describe('locale', () => { - describe('setLocale()', () => { - it('setLocale() changes faker.locale', () => { - for (const locale in faker.locales) { - faker.setLocale(locale); - expect(faker.locale).toBe(locale); - } - }); - }); - - function checkLocaleData(data: unknown) { - if (Array.isArray(data)) { - it('should not have duplicate entries', () => { - expect(data).not.toContainDuplicates(); - }); - } else if (typeof data === 'object' && data != null) { - for (const [nestedKey, nestedData] of Object.entries(data)) { - describe(nestedKey, () => { - checkLocaleData(nestedData); - }); - } - } else { - it.skip(`primitives cannot be tested`); - } - } - - checkLocaleData(allLocales); -}); diff --git a/test/location.spec.ts b/test/location.spec.ts index 3328f8d0727..3c41d351278 100644 --- a/test/location.spec.ts +++ b/test/location.spec.ts @@ -1,5 +1,5 @@ -import { afterEach, describe, expect, it } from 'vitest'; -import { faker } from '../src'; +import { describe, expect, it } from 'vitest'; +import { faker, fakerEN_CA, fakerEN_US } from '../src'; import { seededTests } from './support/seededRuns'; import { times } from './support/times'; @@ -38,10 +38,6 @@ function haversine( const NON_SEEDED_BASED_RUN = 5; describe('location', () => { - afterEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'location', (t) => { t.itEach('street', 'streetName'); @@ -156,8 +152,7 @@ describe('location', () => { it('returns zipCode with proper locale format', () => { // we'll use the en_CA locale.. - faker.locale = 'en_CA'; - const zipCode = faker.location.zipCode(); + const zipCode = fakerEN_CA.location.zipCode(); expect(zipCode).toMatch(/^[A-Za-z]\d[A-Za-z]\s?\d[A-Za-z]\d$/); }); @@ -165,18 +160,17 @@ describe('location', () => { describe('zipCodeByState()', () => { it('returns zipCode valid for specified State', () => { - faker.locale = 'en_US'; const states = ['IL', 'GA', 'WA']; - const zipCode1 = +faker.location.zipCodeByState(states[0]); + const zipCode1 = +fakerEN_US.location.zipCodeByState(states[0]); expect(zipCode1).toBeGreaterThanOrEqual(60001); expect(zipCode1).toBeLessThanOrEqual(62999); - const zipCode2 = +faker.location.zipCodeByState(states[1]); + const zipCode2 = +fakerEN_US.location.zipCodeByState(states[1]); expect(zipCode2).toBeGreaterThanOrEqual(30001); expect(zipCode2).toBeLessThanOrEqual(31999); - const zipCode3 = +faker.location.zipCodeByState(states[2]); + const zipCode3 = +fakerEN_US.location.zipCodeByState(states[2]); expect(zipCode3).toBeGreaterThanOrEqual(98001); expect(zipCode3).toBeLessThanOrEqual(99403); }); diff --git a/test/lorem.spec.ts b/test/lorem.spec.ts index e1d74a4013b..f22cf72f40e 100644 --- a/test/lorem.spec.ts +++ b/test/lorem.spec.ts @@ -1,5 +1,5 @@ import validator from 'validator'; -import { afterEach, describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { faker } from '../src'; import { seededTests } from './support/seededRuns'; import { times } from './support/times'; @@ -7,10 +7,6 @@ import { times } from './support/times'; const NON_SEEDED_BASED_RUN = 5; describe('lorem', () => { - afterEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'lorem', (t) => { t.describe('word', (t) => { t.it('noArgs') diff --git a/test/music.spec.ts b/test/music.spec.ts index 01274d682ab..aff8af856fc 100644 --- a/test/music.spec.ts +++ b/test/music.spec.ts @@ -1,14 +1,10 @@ -import { beforeEach, describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { faker } from '../src'; import { seededTests } from './support/seededRuns'; const NON_SEEDED_BASED_RUN = 5; describe('music', () => { - beforeEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'music', (t) => { t.itEach('genre', 'songName'); }); diff --git a/test/number.spec.ts b/test/number.spec.ts index 78a385b9bac..9a722480c41 100644 --- a/test/number.spec.ts +++ b/test/number.spec.ts @@ -1,13 +1,9 @@ import validator from 'validator'; -import { afterEach, describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { faker, FakerError } from '../src'; import { seededTests } from './support/seededRuns'; describe('number', () => { - afterEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'number', (t) => { t.describeEach( 'int', diff --git a/test/person.spec.ts b/test/person.spec.ts index c232977ff0a..beca664386a 100644 --- a/test/person.spec.ts +++ b/test/person.spec.ts @@ -1,15 +1,10 @@ -import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import { faker, Sex } from '../src'; +import { describe, expect, it } from 'vitest'; +import { faker, fakerAZ, fakerMK, fakerUK, Sex } from '../src'; import { seededTests } from './support/seededRuns'; const NON_SEEDED_BASED_RUN = 5; describe('person', () => { - afterEach(() => { - faker.locale = 'en'; - faker.localeFallback = 'en'; - }); - seededTests(faker, 'person', (t) => { t.itEach( 'sexType', @@ -48,11 +43,6 @@ describe('person', () => { describe(`random seeded tests for seed ${faker.seed()}`, () => { for (let i = 1; i <= NON_SEEDED_BASED_RUN; i++) { describe('firstName()', () => { - beforeEach(() => { - faker.locale = 'en'; - faker.localeFallback = 'en'; - }); - it('should return a random first name', () => { const first_name = faker.person.firstName(); @@ -69,23 +59,15 @@ describe('person', () => { }); it('should return a sex-specific first name when no sex-specific first name was defined', () => { - faker.locale = 'az'; - faker.localeFallback = 'az'; - - const name = faker.person.firstName(); + const name = fakerAZ.person.firstName(); expect([ - ...faker.definitions.person.female_first_name, - ...faker.definitions.person.male_first_name, + ...fakerAZ.definitions.person.female_first_name, + ...fakerAZ.definitions.person.male_first_name, ]).toContain(name); }); }); describe('lastName()', () => { - beforeEach(() => { - faker.locale = 'en'; - faker.localeFallback = 'en'; - }); - it('should return a random last name', () => { const last_name = faker.person.lastName(); @@ -94,22 +76,15 @@ describe('person', () => { }); it('should return a sex-specific last name', () => { - faker.locale = 'az'; - - let name = faker.person.lastName('female'); - expect(faker.definitions.person.female_last_name).toContain(name); + let name = fakerAZ.person.lastName('female'); + expect(fakerAZ.definitions.person.female_last_name).toContain(name); - name = faker.person.lastName('male'); - expect(faker.definitions.person.male_last_name).toContain(name); + name = fakerAZ.person.lastName('male'); + expect(fakerAZ.definitions.person.male_last_name).toContain(name); }); }); describe('middleName()', () => { - beforeEach(() => { - faker.locale = 'en'; - faker.localeFallback = 'en'; - }); - it('should return a random middle name', () => { const middle_name = faker.person.middleName(); @@ -118,8 +93,6 @@ describe('person', () => { }); it('should return a middle name when passed en locale', () => { - faker.locale = 'en'; - let name = faker.person.middleName(); expect(faker.definitions.person.middle_name).toContain(name); @@ -131,22 +104,15 @@ describe('person', () => { }); it('should return a sex-specific middle name', () => { - faker.locale = 'uk'; - - let name = faker.person.middleName('female'); - expect(faker.definitions.person.female_middle_name).toContain(name); + let name = fakerUK.person.middleName('female'); + expect(fakerUK.definitions.person.female_middle_name).toContain(name); - name = faker.person.middleName('male'); - expect(faker.definitions.person.male_middle_name).toContain(name); + name = fakerUK.person.middleName('male'); + expect(fakerUK.definitions.person.male_middle_name).toContain(name); }); }); describe('fullName()', () => { - beforeEach(() => { - faker.locale = 'en'; - faker.localeFallback = 'en'; - }); - it('should return a name with firstName and lastName', () => { const fullName = faker.person.fullName(); @@ -155,16 +121,14 @@ describe('person', () => { }); it('should return a female sex-specific name without firstName and lastName', () => { - faker.locale = 'mk'; - const female_specific = [ - ...faker.definitions.person.female_prefix, - ...faker.definitions.person.female_first_name, - ...faker.definitions.person.female_last_name, - ...faker.definitions.person.suffix, + ...fakerMK.definitions.person.female_prefix, + ...fakerMK.definitions.person.female_first_name, + ...fakerMK.definitions.person.female_last_name, + ...fakerMK.definitions.person.suffix, ]; - const fullName = faker.person.fullName({ sex: 'female' }); + const fullName = fakerMK.person.fullName({ sex: 'female' }); const parts = fullName.split(' '); for (const part of parts) { @@ -173,16 +137,14 @@ describe('person', () => { }); it('should return a male sex-specific name without firstName and lastName', () => { - faker.locale = 'mk'; - const male_specific = [ - ...faker.definitions.person.male_prefix, - ...faker.definitions.person.male_first_name, - ...faker.definitions.person.male_last_name, - ...faker.definitions.person.suffix, + ...fakerMK.definitions.person.male_prefix, + ...fakerMK.definitions.person.male_first_name, + ...fakerMK.definitions.person.male_last_name, + ...fakerMK.definitions.person.suffix, ]; - const fullName = faker.person.fullName({ sex: 'male' }); + const fullName = fakerMK.person.fullName({ sex: 'male' }); const parts = fullName.split(' '); for (const part of parts) { @@ -191,16 +153,14 @@ describe('person', () => { }); it('should return a female sex-specific name with given firstName and lastName', () => { - faker.locale = 'mk'; - const male_specific = [ - ...faker.definitions.person.female_prefix, + ...fakerMK.definitions.person.female_prefix, 'firstName', 'lastName', - ...faker.definitions.person.suffix, + ...fakerMK.definitions.person.suffix, ]; - const fullName = faker.person.fullName({ + const fullName = fakerMK.person.fullName({ firstName: 'firstName', lastName: 'lastName', sex: 'female', @@ -213,16 +173,14 @@ describe('person', () => { }); it('should return a male sex-specific name with given firstName and lastName', () => { - faker.locale = 'mk'; - const male_specific = [ - ...faker.definitions.person.male_prefix, + ...fakerMK.definitions.person.male_prefix, 'firstName', 'lastName', - ...faker.definitions.person.suffix, + ...fakerMK.definitions.person.suffix, ]; - const fullName = faker.person.fullName({ + const fullName = fakerMK.person.fullName({ firstName: 'firstName', lastName: 'lastName', sex: 'male', @@ -236,11 +194,6 @@ describe('person', () => { }); describe('gender()', () => { - beforeEach(() => { - faker.locale = 'en'; - faker.localeFallback = 'en'; - }); - it('should return a default gender', () => { const gender = faker.person.gender(); @@ -250,11 +203,6 @@ describe('person', () => { }); describe('sex()', () => { - beforeEach(() => { - faker.locale = 'en'; - faker.localeFallback = 'en'; - }); - it('should return a sex', () => { const sex = faker.person.sex(); @@ -273,11 +221,6 @@ describe('person', () => { }); describe('prefix()', () => { - beforeEach(() => { - faker.locale = 'en'; - faker.localeFallback = 'en'; - }); - it('should return a prefix', () => { const prefix = faker.person.prefix(); @@ -286,30 +229,21 @@ describe('person', () => { }); it('should return a female prefix with given string', () => { - faker.locale = 'mk'; - - const prefix = faker.person.prefix('female'); + const prefix = fakerMK.person.prefix('female'); expect(prefix).toBeTypeOf('string'); - expect(faker.definitions.person.female_prefix).toContain(prefix); + expect(fakerMK.definitions.person.female_prefix).toContain(prefix); }); it('should return a male prefix with given string', () => { - faker.locale = 'mk'; - - const prefix = faker.person.prefix('male'); + const prefix = fakerMK.person.prefix('male'); expect(prefix).toBeTypeOf('string'); - expect(faker.definitions.person.male_prefix).toContain(prefix); + expect(fakerMK.definitions.person.male_prefix).toContain(prefix); }); }); describe('suffix()', () => { - beforeEach(() => { - faker.locale = 'en'; - faker.localeFallback = 'en'; - }); - it('should return a suffix', () => { const suffix = faker.person.suffix(); @@ -319,11 +253,6 @@ describe('person', () => { }); describe('jobTitle()', () => { - beforeEach(() => { - faker.locale = 'en'; - faker.localeFallback = 'en'; - }); - it('should return a job title consisting of a descriptor, area, and type', () => { const jobTitle = faker.person.jobTitle(); @@ -340,11 +269,6 @@ describe('person', () => { }); describe('jobDescriptor()', () => { - beforeEach(() => { - faker.locale = 'en'; - faker.localeFallback = 'en'; - }); - it('should return a descriptor', () => { const descriptor = faker.person.jobDescriptor(); @@ -357,11 +281,6 @@ describe('person', () => { }); describe('jobArea()', () => { - beforeEach(() => { - faker.locale = 'en'; - faker.localeFallback = 'en'; - }); - it('should return a level', () => { const level = faker.person.jobArea(); @@ -372,11 +291,6 @@ describe('person', () => { }); describe('jobType()', () => { - beforeEach(() => { - faker.locale = 'en'; - faker.localeFallback = 'en'; - }); - it('should return a job', () => { const job = faker.person.jobType(); diff --git a/test/phone.spec.ts b/test/phone.spec.ts index 7431476b9bd..11b809ff2f8 100644 --- a/test/phone.spec.ts +++ b/test/phone.spec.ts @@ -1,4 +1,4 @@ -import { beforeEach, describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { faker } from '../src'; import { luhnCheck } from '../src/modules/helpers/luhn-check'; import { seededTests } from './support/seededRuns'; @@ -6,10 +6,6 @@ import { seededTests } from './support/seededRuns'; const NON_SEEDED_BASED_RUN = 25; describe('phone', () => { - beforeEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'phone', (t) => { t.it('imei'); diff --git a/test/random.spec.ts b/test/random.spec.ts index e03e74283c5..3818274f516 100644 --- a/test/random.spec.ts +++ b/test/random.spec.ts @@ -1,5 +1,5 @@ -import { beforeEach, describe, expect, it } from 'vitest'; -import { faker, FakerError } from '../src'; +import { describe, expect, it } from 'vitest'; +import { faker, FakerError, fakerZH_CN } from '../src'; import { seededTests } from './support/seededRuns'; import { times } from './support/times'; @@ -7,7 +7,8 @@ const NON_SEEDED_BASED_RUN = 5; describe('random', () => { seededTests(faker, 'random', (t) => { - t.itEach('locale', 'word'); + t.it('word'); + t.skip('locale' as 'word'); // locale() has been pseudo removed t.describeEach( 'alpha', @@ -52,10 +53,6 @@ describe('random', () => { '-', ]; - beforeEach(() => { - faker.locale = 'en'; - }); - it('should return a random word', () => { const actual = faker.random.word(); @@ -77,9 +74,7 @@ describe('random', () => { it.each(times(50))( 'should only contain a word without undesirable non-alpha characters, locale=zh_CN (run %i)', () => { - faker.locale = 'zh_CN'; - - const actual = faker.random.word(); + const actual = fakerZH_CN.random.word(); expect(actual).not.satisfy((word: string) => bannedChars.some((char) => word.includes(char)) @@ -89,10 +84,6 @@ describe('random', () => { }); describe('words', () => { - beforeEach(() => { - faker.locale = 'en'; - }); - it('should return random words', () => { const actual = faker.random.words(); @@ -126,16 +117,6 @@ describe('random', () => { }); }); - describe('locale', () => { - it('should return a random locale', () => { - const actual = faker.random.locale(); - - expect(actual).toBeTruthy(); - expect(actual).toBeTypeOf('string'); - expect(Object.keys(faker.locales)).toContain(actual); - }); - }); - describe('alpha', () => { it('should return single letter when no count provided', () => { const actual = faker.random.alpha(); diff --git a/test/science.spec.ts b/test/science.spec.ts index c6b0a0dc6c5..6ee1585c445 100644 --- a/test/science.spec.ts +++ b/test/science.spec.ts @@ -1,14 +1,10 @@ -import { afterEach, describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { faker } from '../src'; import { seededTests } from './support/seededRuns'; const NON_SEEDED_BASED_RUN = 5; describe('science', () => { - afterEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'science', (t) => { t.itEach('chemicalElement', 'unit'); }); diff --git a/test/scripts/apidoc/examplesAndDeprecations.spec.ts b/test/scripts/apidoc/examplesAndDeprecations.spec.ts index d8fc7361918..5ff635b202c 100644 --- a/test/scripts/apidoc/examplesAndDeprecations.spec.ts +++ b/test/scripts/apidoc/examplesAndDeprecations.spec.ts @@ -21,7 +21,6 @@ import { extractSince, extractTagContent, } from '../../../scripts/apidoc/typedoc'; -import { faker } from '../../../src'; import { loadProjectModules } from './utils'; /* @@ -30,12 +29,6 @@ import { loadProjectModules } from './utils'; * - and running these do not log anything, unless the method is deprecated */ -const locales: Record = { - GH: 'en_GH', - US: 'en_US', - DE: 'de', -}; - beforeAll(initMarkdownRenderer); describe('examples and deprecations', () => { @@ -46,7 +39,6 @@ describe('examples and deprecations', () => { .map((methodName) => vi.spyOn(console, methodName as keyof typeof console)); afterAll(() => { - faker.locale = 'en'; for (const spy of consoleSpies) { spy.mockRestore(); } @@ -54,7 +46,6 @@ describe('examples and deprecations', () => { describe.each(Object.entries(modules))('%s', (moduleName, methodsByName) => { beforeEach(() => { - faker.locale = 'en'; for (const spy of consoleSpies) { spy.mockReset(); } @@ -65,11 +56,7 @@ describe('examples and deprecations', () => { '%s', async (methodName, signature) => { // Extract examples and make them runnable - let examples = extractRawExamples(signature).join('').trim(); - examples = examples.replace( - /faker([A-Z]{2})\./g, - (_, locale: string) => `faker.locale = '${locales[locale]}';\nfaker.` - ); + const examples = extractRawExamples(signature).join('').trim(); expect( examples, @@ -80,9 +67,12 @@ describe('examples and deprecations', () => { const dir = resolve(__dirname, 'temp', moduleName); mkdirSync(dir, { recursive: true }); const path = resolve(dir, `${methodName}.ts`); + const imports = [...new Set(examples.match(/faker[^\.]*(?=\.)/g))]; writeFileSync( path, - `import { faker } from '../../../../../src';\n${examples}` + `import { ${imports.join( + ', ' + )} } from '../../../../../src';\n\n${examples}` ); // Run the examples diff --git a/test/support/seededRuns.ts b/test/support/seededRuns.ts index 21f37b7e7c7..11085ddffa3 100644 --- a/test/support/seededRuns.ts +++ b/test/support/seededRuns.ts @@ -130,7 +130,6 @@ class TestGenerator< */ setup(): void { this.faker.seed(this.seed); - this.faker.locale = 'en'; } /** diff --git a/test/system.spec.ts b/test/system.spec.ts index fc36ce7859a..67d7acf4deb 100644 --- a/test/system.spec.ts +++ b/test/system.spec.ts @@ -1,16 +1,12 @@ import validator from 'validator'; -import { afterEach, describe, expect, it } from 'vitest'; -import { faker } from '../src'; +import { describe, expect, it } from 'vitest'; +import { faker, fakerSK } from '../src'; import { seededTests } from './support/seededRuns'; import { times } from './support/times'; const NON_SEEDED_BASED_RUN = 5; describe('system', () => { - afterEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'system', (t) => { t.itEach( 'commonFileExt', @@ -422,15 +418,10 @@ describe('system', () => { describe('extra tests', () => { describe('commonFileName()', () => { - afterEach(() => { - faker.locale = 'en'; - }); - it('#770', () => { - faker.seed(5423027051750305); - faker.setLocale('sk'); - faker.system.commonFileName('xml'); - faker.system.commonFileName('xml'); + fakerSK.seed(5423027051750305); + fakerSK.system.commonFileName('xml'); + fakerSK.system.commonFileName('xml'); }); }); }); diff --git a/test/vehicle.spec.ts b/test/vehicle.spec.ts index bc86f0bbcfd..282626471df 100644 --- a/test/vehicle.spec.ts +++ b/test/vehicle.spec.ts @@ -1,14 +1,10 @@ -import { afterEach, describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { faker } from '../src'; import { seededTests } from './support/seededRuns'; const NON_SEEDED_BASED_RUN = 5; describe('vehicle', () => { - afterEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'vehicle', (t) => { t.itEach( 'vehicle', diff --git a/test/word.spec.ts b/test/word.spec.ts index 14ac3aaebba..adf7f5309aa 100644 --- a/test/word.spec.ts +++ b/test/word.spec.ts @@ -1,4 +1,4 @@ -import { afterEach, describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { faker } from '../src'; import { filterWordListByLength } from '../src/modules/word/filterWordListByLength'; import { seededTests } from './support/seededRuns'; @@ -6,10 +6,6 @@ import { seededTests } from './support/seededRuns'; const NON_SEEDED_BASED_RUN = 5; describe('word', () => { - afterEach(() => { - faker.locale = 'en'; - }); - seededTests(faker, 'word', (t) => { t.describeEach( 'adjective',