diff --git a/.eslintrc.js b/.eslintrc.js index 4e12b747a1f..cba7d990fd1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -34,6 +34,15 @@ module.exports = defineConfig({ '@typescript-eslint/ban-ts-comment': 'warn', '@typescript-eslint/consistent-type-imports': 'error', '@typescript-eslint/explicit-module-boundary-types': 'error', + '@typescript-eslint/naming-convention': [ + 'error', + { + format: ['PascalCase'], + selector: ['class', 'interface', 'typeAlias', 'enumMember'], + leadingUnderscore: 'forbid', + trailingUnderscore: 'forbid', + }, + ], '@typescript-eslint/no-inferrable-types': [ 'error', { ignoreParameters: true }, @@ -43,23 +52,15 @@ module.exports = defineConfig({ '@typescript-eslint/no-unsafe-call': 'off', '@typescript-eslint/no-unsafe-member-access': 'off', '@typescript-eslint/no-unsafe-return': 'warn', - '@typescript-eslint/restrict-template-expressions': [ + '@typescript-eslint/padding-line-between-statements': [ 'error', - { - allowNumber: true, - allowBoolean: true, - }, + { blankLine: 'always', prev: 'block-like', next: '*' }, ], - '@typescript-eslint/unbound-method': 'off', - '@typescript-eslint/naming-convention': [ + '@typescript-eslint/restrict-template-expressions': [ 'error', - { - format: ['PascalCase'], - selector: ['class', 'interface', 'typeAlias', 'enumMember'], - leadingUnderscore: 'forbid', - trailingUnderscore: 'forbid', - }, + { allowNumber: true, allowBoolean: true }, ], + '@typescript-eslint/unbound-method': 'off', }, overrides: [ { diff --git a/scripts/apidoc/apiDocsWriter.ts b/scripts/apidoc/apiDocsWriter.ts index 1f0709bb170..cd8dd2e5936 100644 --- a/scripts/apidoc/apiDocsWriter.ts +++ b/scripts/apidoc/apiDocsWriter.ts @@ -161,6 +161,7 @@ export function writeApiSearchIndex(project: ProjectReflection): void { }, ]; } + return apiSection; }) .sort((a, b) => a.text.localeCompare(b.text)); diff --git a/scripts/apidoc/moduleMethods.ts b/scripts/apidoc/moduleMethods.ts index 10bce054735..dd4f528a42b 100644 --- a/scripts/apidoc/moduleMethods.ts +++ b/scripts/apidoc/moduleMethods.ts @@ -46,6 +46,7 @@ export function extractModuleName(module: DeclarationReflection): string { } else if (name === 'NameModule') { return 'Person'; } + return name.replace(/Module$/, ''); } diff --git a/scripts/apidoc/parameterDefaults.ts b/scripts/apidoc/parameterDefaults.ts index 243d7e45a1a..b889fe243ed 100644 --- a/scripts/apidoc/parameterDefaults.ts +++ b/scripts/apidoc/parameterDefaults.ts @@ -52,6 +52,7 @@ function cleanParameterDefault(value?: string): string | undefined { if (value == null) { return undefined; } + // Strip type casts: "'foobar' as unknown as T" => "'foobar'" return value.replace(/ as unknown as [A-Za-z<>]+/, ''); } @@ -124,6 +125,7 @@ function patchSignatureParameterDefaults( if (signatureParameters.length !== parameterDefaults.length) { throw new Error('Unexpected parameter length mismatch'); } + signatureParameters.forEach( (param, index) => (param.defaultValue = parameterDefaults[index] || param.defaultValue) diff --git a/scripts/apidoc/signature.ts b/scripts/apidoc/signature.ts index 72036a434b1..22eed26812c 100644 --- a/scripts/apidoc/signature.ts +++ b/scripts/apidoc/signature.ts @@ -142,6 +142,7 @@ export function analyzeSignature( if (signatureTypeParameters.length !== 0) { signatureTypeParametersString = `<${signatureTypeParameters.join(', ')}>`; } + const signatureParametersString = signatureParameters.join(', '); let examples: string; @@ -150,6 +151,7 @@ export function analyzeSignature( } else { examples = `faker.${methodName}${signatureTypeParametersString}(${signatureParametersString}): ${signature.type?.toString()}\n`; } + faker.seed(0); if (moduleName) { try { @@ -230,6 +232,7 @@ function analyzeParameterOptions( if (!parameterType) { return []; } + if (parameterType.type === 'union') { return parameterType.types.flatMap((type) => analyzeParameterOptions(name, type) @@ -243,7 +246,7 @@ function analyzeParameterOptions( description: mdToHtml( toBlock( property.comment ?? - (property.type as ReflectionType)?.declaration.signatures?.[0] + (property.type as ReflectionType)?.declaration?.signatures?.[0] .comment ) ), @@ -261,6 +264,7 @@ function typeToText(type_?: Type, short = false): string { if (!type_) { return '?'; } + const type = type_ as SomeType; switch (type.type) { case 'array': @@ -283,6 +287,7 @@ function typeToText(type_?: Type, short = false): string { .map((t) => typeToText(t, short)) .join(', ')}>`; } + case 'reflection': return declarationTypeToText(type.declaration, short); case 'indexedAccess': @@ -335,6 +340,7 @@ function signatureTypeToText(signature?: SignatureReflection): string { if (!signature) { return '(???) => ?'; } + return `(${signature.parameters ?.map((p) => `${p.name}: ${typeToText(p.type)}`) .join(', ')}) => ${typeToText(signature.type)}`; @@ -350,18 +356,22 @@ function extractDefaultFromComment(comment?: Comment): string | undefined { if (!comment) { return; } + const summary = comment.summary; const text = joinTagParts(summary).trim(); if (!text) { return; } + const result = /^(.*)[ \n]Defaults to `([^`]+)`\.(.*)$/s.exec(text); if (!result) { return; } + if (result[3].trim()) { throw new Error(`Found description text after the default value:\n${text}`); } + summary.splice(summary.length - 2, 2); const lastSummaryPart = summary[summary.length - 1]; lastSummaryPart.text = lastSummaryPart.text.replace(/[ \n]Defaults to $/, ''); diff --git a/scripts/apidoc/utils.ts b/scripts/apidoc/utils.ts index ef26a67dded..9dad1b1457a 100644 --- a/scripts/apidoc/utils.ts +++ b/scripts/apidoc/utils.ts @@ -122,6 +122,7 @@ export function extractSeeAlsos(signature?: SignatureReflection): string[] { if (link.startsWith('-')) { link = link.slice(1).trim(); } + return link; }) .filter((link) => link) diff --git a/scripts/bundle.ts b/scripts/bundle.ts index a94d31830b9..e08b7de4378 100644 --- a/scripts/bundle.ts +++ b/scripts/bundle.ts @@ -12,6 +12,7 @@ const target = ['ES2019', 'node14.17']; if (existsSync(localeDir)) { rmSync(localeDir, { recursive: true, force: true }); } + mkdirSync(localeDir); for (const locale of Object.keys(locales)) { writeFileSync( diff --git a/scripts/generateLocales.ts b/scripts/generateLocales.ts index d5540672b31..37f21ec9e6d 100644 --- a/scripts/generateLocales.ts +++ b/scripts/generateLocales.ts @@ -82,6 +82,7 @@ function removeIndexTs(files: string[]): string[] { if (index !== -1) { files.splice(index, 1); } + return files; } @@ -152,6 +153,7 @@ function tryLoadLocalesMainIndexFile(pathModules: string): LocaleDefinition { console.error(`Failed to load ${pathModules} or manually parse it.`, e); } } + return localeDef; } @@ -177,6 +179,7 @@ function generateLocalesIndexFile( )}';` ); } + content.push( ...modules.map((m) => `import ${escapeImport(m)} from './${m}';`) ); diff --git a/src/faker.ts b/src/faker.ts index 7870d9c5618..a5a6dbc275b 100644 --- a/src/faker.ts +++ b/src/faker.ts @@ -62,6 +62,7 @@ export class Faker { `Locale ${locale} is not supported. You might want to add the requested locale first to \`faker.locales\`.` ); } + this._locale = locale; } @@ -75,6 +76,7 @@ export class Faker { `Locale ${localeFallback} is not supported. You might want to add the requested locale first to \`faker.locales\`.` ); } + this._localeFallback = localeFallback; } diff --git a/src/internal/mersenne/twister.ts b/src/internal/mersenne/twister.ts index f7757842b1d..15189e6775c 100644 --- a/src/internal/mersenne/twister.ts +++ b/src/internal/mersenne/twister.ts @@ -129,6 +129,7 @@ export default class MersenneTwister19937 { sum = this.addition32(sum, this.unsigned32(n2 << i)); } } + return sum; } @@ -194,10 +195,12 @@ export default class MersenneTwister19937 { this.mt[0] = this.mt[this.N - 1]; i = 1; } + if (j >= keyLength) { j = 0; } } + for (k = this.N - 1; k; k--) { // mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941)) - i this.mt[i] = this.subtraction32( @@ -218,6 +221,7 @@ export default class MersenneTwister19937 { i = 1; } } + this.mt[0] = 0x80000000; // MSB is 1; assuring non-zero initial array } diff --git a/src/locales/de_CH/person/female_first_name.ts b/src/locales/de_CH/person/female_first_name.ts new file mode 100644 index 00000000000..d3404c269d6 --- /dev/null +++ b/src/locales/de_CH/person/female_first_name.ts @@ -0,0 +1,140 @@ +export default [ + 'Alice', + 'Andrea', + 'Angela', + 'Anita', + 'Anna', + 'Anne', + 'Anne-Marie', + 'Annemarie', + 'Astrid', + 'Barbara', + 'Beatrice', + 'Beatrix', + 'Bernadette', + 'Bettina', + 'Brigitta', + 'Brigitte', + 'Carmen', + 'Caroline', + 'Catherine', + 'Chantal', + 'Charlotte', + 'Christa', + 'Christiane', + 'Christina', + 'Christine', + 'Claire', + 'Claudia', + 'Claudine', + 'Corinne', + 'Cornelia', + 'Daniela', + 'Danielle', + 'Denise', + 'Dominique', + 'Dora', + 'Doris', + 'Edith', + 'Eliane', + 'Elisabeth', + 'Elsa', + 'Elsbeth', + 'Erica', + 'Erika', + 'Esther', + 'Eva', + 'Eveline', + 'Evelyne', + 'Fabienne', + 'Florence', + 'Françoise', + 'Franziska', + 'Gabriela', + 'Gabrielle', + 'Gertrud', + 'Gisela', + 'Hanna', + 'Heidi', + 'Helen', + 'Helena', + 'Helene', + 'Hildegard', + 'Ingrid', + 'Irene', + 'Iris', + 'Isabelle', + 'Jacqueline', + 'Janine', + 'Jean', + 'Johanna', + 'Jolanda', + 'Josette', + 'Josiane', + 'Judith', + 'Julia', + 'Karin', + 'Katharina', + 'Laura', + 'Laurence', + 'Liliane', + 'Liselotte', + 'Lydia', + 'Madeleine', + 'Maja', + 'Manuela', + 'Margrit', + 'Margrith', + 'Maria', + 'Marianne', + 'Marion', + 'Marlène', + 'Marlies', + 'Marlis', + 'Martha', + 'Martina', + 'Martine', + 'Maya', + 'Michele', + 'Micheline', + 'Monica', + 'Monika', + 'Monique', + 'Myriam', + 'Nadia', + 'Nadja', + 'Nathalie', + 'Nelly', + 'Nicole', + 'Paola', + 'Patricia', + 'Petra', + 'Pia', + 'Priska', + 'Regina', + 'Regula', + 'Renata', + 'Renate', + 'Ruth', + 'Sabine', + 'Sandra', + 'Silvia', + 'Simone', + 'Sonia', + 'Sonja', + 'Stéphanie', + 'Susanna', + 'Susanne', + 'Suzanne', + 'Sylvia', + 'Sylvie', + 'Therese', + 'Toni', + 'Ursula', + 'Verena', + 'Véronique', + 'Vreni', + 'Yolande', + 'Yvette', + 'Yvonne', +]; diff --git a/src/locales/de_CH/person/first_name.ts b/src/locales/de_CH/person/first_name.ts index f704f6dbe32..40a647ec054 100644 --- a/src/locales/de_CH/person/first_name.ts +++ b/src/locales/de_CH/person/first_name.ts @@ -1,338 +1,8 @@ -export default [ - 'Adolf', - 'Adrian', - 'Agnes', - 'Alain', - 'Albert', - 'Alberto', - 'Aldo', - 'Alex', - 'Alexander', - 'Alexandre', - 'Alfons', - 'Alfred', - 'Alice', - 'Alois', - 'André', - 'Andrea', - 'Andreas', - 'Angela', - 'Angelo', - 'Anita', - 'Anna', - 'Anne', - 'Anne-Marie', - 'Annemarie', - 'Antoine', - 'Anton', - 'Antonio', - 'Armin', - 'Arnold', - 'Arthur', - 'Astrid', - 'Barbara', - 'Beat', - 'Beatrice', - 'Beatrix', - 'Bernadette', - 'Bernard', - 'Bernhard', - 'Bettina', - 'Brigitta', - 'Brigitte', - 'Bruno', - 'Carlo', - 'Carmen', - 'Caroline', - 'Catherine', - 'Chantal', - 'Charles', - 'Charlotte', - 'Christa', - 'Christian', - 'Christiane', - 'Christina', - 'Christine', - 'Christoph', - 'Christophe', - 'Claire', - 'Claude', - 'Claudia', - 'Claudine', - 'Claudio', - 'Corinne', - 'Cornelia', - 'Daniel', - 'Daniela', - 'Daniele', - 'Danielle', - 'David', - 'Denis', - 'Denise', - 'Didier', - 'Dieter', - 'Dominik', - 'Dominique', - 'Dora', - 'Doris', - 'Edgar', - 'Edith', - 'Eduard', - 'Edwin', - 'Eliane', - 'Elisabeth', - 'Elsa', - 'Elsbeth', - 'Emil', - 'Enrico', - 'Eric', - 'Erica', - 'Erich', - 'Erika', - 'Ernst', - 'Erwin', - 'Esther', - 'Eugen', - 'Eva', - 'Eveline', - 'Evelyne', - 'Fabienne', - 'Felix', - 'Ferdinand', - 'Florence', - 'Francesco', - 'Francis', - 'Franco', - 'François', - 'Françoise', - 'Frank', - 'Franz', - 'Franziska', - 'Frédéric', - 'Fredy', - 'Fridolin', - 'Friedrich', - 'Fritz', - 'Gabriel', - 'Gabriela', - 'Gabrielle', - 'Georg', - 'Georges', - 'Gérald', - 'Gérard', - 'Gerhard', - 'Gertrud', - 'Gianni', - 'Gilbert', - 'Giorgio', - 'Giovanni', - 'Gisela', - 'Giuseppe', - 'Gottfried', - 'Guido', - 'Guy', - 'Hanna', - 'Hans', - 'Hans-Peter', - 'Hans-Rudolf', - 'Hans-Ulrich', - 'Hansjörg', - 'Hanspeter', - 'Hansruedi', - 'Hansueli', - 'Harry', - 'Heidi', - 'Heinrich', - 'Heinz', - 'Helen', - 'Helena', - 'Helene', - 'Helmut', - 'Henri', - 'Herbert', - 'Hermann', - 'Hildegard', - 'Hubert', - 'Hugo', - 'Ingrid', - 'Irene', - 'Iris', - 'Isabelle', - 'Jacqueline', - 'Jacques', - 'Jakob', - 'Jan', - 'Janine', - 'Jean', - 'Jean-Claude', - 'Jean-Daniel', - 'Jean-François', - 'Jean-Jacques', - 'Jean-Louis', - 'Jean-Luc', - 'Jean-Marc', - 'Jean-Marie', - 'Jean-Paul', - 'Jean-Pierre', - 'Johann', - 'Johanna', - 'Johannes', - 'John', - 'Jolanda', - 'Jörg', - 'Josef', - 'Joseph', - 'Josette', - 'Josiane', - 'Judith', - 'Julia', - 'Jürg', - 'Karin', - 'Karl', - 'Katharina', - 'Klaus', - 'Konrad', - 'Kurt', - 'Laura', - 'Laurence', - 'Laurent', - 'Leo', - 'Liliane', - 'Liselotte', - 'Louis', - 'Luca', - 'Luigi', - 'Lukas', - 'Lydia', - 'Madeleine', - 'Maja', - 'Manfred', - 'Manuel', - 'Manuela', - 'Marc', - 'Marcel', - 'Marco', - 'Margrit', - 'Margrith', - 'Maria', - 'Marianne', - 'Mario', - 'Marion', - 'Markus', - 'Marlène', - 'Marlies', - 'Marlis', - 'Martha', - 'Martin', - 'Martina', - 'Martine', - 'Massimo', - 'Matthias', - 'Maurice', - 'Max', - 'Maya', - 'Michael', - 'Michel', - 'Michele', - 'Micheline', - 'Monica', - 'Monika', - 'Monique', - 'Myriam', - 'Nadia', - 'Nadja', - 'Nathalie', - 'Nelly', - 'Nicolas', - 'Nicole', - 'Niklaus', - 'Norbert', - 'Olivier', - 'Oskar', - 'Otto', - 'Paola', - 'Paolo', - 'Pascal', - 'Patricia', - 'Patrick', - 'Paul', - 'Peter', - 'Petra', - 'Philipp', - 'Philippe', - 'Pia', - 'Pierre', - 'Pierre-Alain', - 'Pierre-André', - 'Pius', - 'Priska', - 'Rainer', - 'Raymond', - 'Regina', - 'Regula', - 'Reinhard', - 'Remo', - 'Renata', - 'Renate', - 'Renato', - 'Rene', - 'René', - 'Reto', - 'Richard', - 'Rita', - 'Robert', - 'Roberto', - 'Roger', - 'Roland', - 'Rolf', - 'Roman', - 'Rosa', - 'Rosemarie', - 'Rosmarie', - 'Rudolf', - 'Ruedi', - 'Ruth', - 'Sabine', - 'Samuel', - 'Sandra', - 'Sandro', - 'Serge', - 'Silvia', - 'Silvio', - 'Simon', - 'Simone', - 'Sonia', - 'Sonja', - 'Stefan', - 'Stephan', - 'Stéphane', - 'Stéphanie', - 'Susanna', - 'Susanne', - 'Suzanne', - 'Sylvia', - 'Sylvie', - 'Theo', - 'Theodor', - 'Therese', - 'Thomas', - 'Toni', - 'Ueli', - 'Ulrich', - 'Urs', - 'Ursula', - 'Verena', - 'Véronique', - 'Victor', - 'Viktor', - 'Vreni', - 'Walter', - 'Werner', - 'Willi', - 'Willy', - 'Wolfgang', - 'Yolande', - 'Yves', - 'Yvette', - 'Yvonne', -]; +// We don't have a generic first name list for this locale +// So simply concatenate male and female lists and remove any duplicates +// This avoids falling back to fallback locale +import { mergeArrays } from './../../../internal/merge'; +import female_first_name from './female_first_name'; +import male_first_name from './male_first_name'; + +export default mergeArrays(female_first_name, male_first_name); diff --git a/src/locales/de_CH/person/index.ts b/src/locales/de_CH/person/index.ts index f66f9c6a3cc..2ba33f8c482 100644 --- a/src/locales/de_CH/person/index.ts +++ b/src/locales/de_CH/person/index.ts @@ -3,14 +3,18 @@ * Run 'pnpm run generate:locales' to update. */ import type { PersonDefinitions } from '../../..'; +import female_first_name from './female_first_name'; import first_name from './first_name'; import last_name from './last_name'; +import male_first_name from './male_first_name'; import name_ from './name'; import prefix from './prefix'; const person: PersonDefinitions = { + female_first_name, first_name, last_name, + male_first_name, name: name_, prefix, }; diff --git a/src/locales/de_CH/person/male_first_name.ts b/src/locales/de_CH/person/male_first_name.ts new file mode 100644 index 00000000000..157493ea25d --- /dev/null +++ b/src/locales/de_CH/person/male_first_name.ts @@ -0,0 +1,181 @@ +export default [ + 'Alfons', + 'Alfred', + 'Alois', + 'André', + 'Andreas', + 'Angelo', + 'Antoine', + 'Anton', + 'Antonio', + 'Armin', + 'Arnold', + 'Arthur', + 'Beat', + 'Bernard', + 'Bernhard', + 'Bruno', + 'Carlo', + 'Charles', + 'Christian', + 'Christoph', + 'Christophe', + 'Claude', + 'Claudio', + 'Daniel', + 'Daniele', + 'David', + 'Denis', + 'Didier', + 'Dieter', + 'Dominik', + 'Dominique', + 'Edgar', + 'Eduard', + 'Edwin', + 'Emil', + 'Enrico', + 'Eric', + 'Erich', + 'Ernst', + 'Erwin', + 'Eugen', + 'Felix', + 'Ferdinand', + 'Francesco', + 'Francis', + 'Franco', + 'François', + 'Frank', + 'Franz', + 'Frédéric', + 'Fredy', + 'Fridolin', + 'Friedrich', + 'Fritz', + 'Gabriel', + 'Georg', + 'Georges', + 'Gérald', + 'Gérard', + 'Gerhard', + 'Gianni', + 'Gilbert', + 'Giorgio', + 'Giovanni', + 'Giuseppe', + 'Gottfried', + 'Guido', + 'Guy', + 'Hans', + 'Hans-Peter', + 'Hans-Rudolf', + 'Hans-Ulrich', + 'Hansjörg', + 'Hanspeter', + 'Hansruedi', + 'Hansueli', + 'Harry', + 'Heinrich', + 'Heinz', + 'Helmut', + 'Henri', + 'Herbert', + 'Hermann', + 'Hubert', + 'Hugo', + 'Jacques', + 'Jakob', + 'Jan', + 'Jean-Claude', + 'Jean-Daniel', + 'Jean-François', + 'Jean-Jacques', + 'Jean-Louis', + 'Jean-Luc', + 'Jean-Marc', + 'Jean-Marie', + 'Jean-Paul', + 'Jean-Pierre', + 'Johann', + 'Johannes', + 'John', + 'Jörg', + 'Josef', + 'Joseph', + 'Jürg', + 'Karl', + 'Klaus', + 'Konrad', + 'Kurt', + 'Laurent', + 'Leo', + 'Louis', + 'Luca', + 'Luigi', + 'Lukas', + 'Manfred', + 'Manuel', + 'Marc', + 'Marcel', + 'Marco', + 'Mario', + 'Markus', + 'Martin', + 'Massimo', + 'Matthias', + 'Maurice', + 'Max', + 'Michael', + 'Michel', + 'Nicolas', + 'Niklaus', + 'Norbert', + 'Olivier', + 'Oskar', + 'Otto', + 'Paolo', + 'Pascal', + 'Patrick', + 'Paul', + 'Peter', + 'Philipp', + 'Philippe', + 'Pierre', + 'Pierre-Alain', + 'Pierre-André', + 'Pius', + 'Rainer', + 'Raymond', + 'Reinhard', + 'Remo', + 'Renato', + 'Rene', + 'René', + 'Reto', + 'Richard', + 'Rudolf', + 'Ruedi', + 'Samuel', + 'Sandro', + 'Serge', + 'Silvio', + 'Simon', + 'Stefan', + 'Stephan', + 'Stéphane', + 'Theo', + 'Theodor', + 'Thomas', + 'Ueli', + 'Ulrich', + 'Urs', + 'Victor', + 'Viktor', + 'Walter', + 'Werner', + 'Willi', + 'Willy', + 'Wolfgang', + 'Yves', +]; diff --git a/src/modules/animal/index.ts b/src/modules/animal/index.ts index 4a0af052523..3cd9d71ef20 100644 --- a/src/modules/animal/index.ts +++ b/src/modules/animal/index.ts @@ -10,6 +10,7 @@ export class AnimalModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } diff --git a/src/modules/color/index.ts b/src/modules/color/index.ts index 167fc225591..23e41694eb3 100644 --- a/src/modules/color/index.ts +++ b/src/modules/color/index.ts @@ -58,9 +58,11 @@ function formatHexColor( hexColor = hexColor.toLowerCase(); break; } + if (options?.prefix) { hexColor = options.prefix + hexColor; } + return hexColor; } @@ -78,6 +80,7 @@ function toBinary(values: number[]): string { const bytes = new Uint8Array(buffer); return toBinary(Array.from(bytes)).split(' ').join(''); } + return (value >>> 0).toString(2).padStart(8, '0'); }); return binary.join(' '); @@ -161,6 +164,7 @@ export class ColorModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } @@ -320,11 +324,13 @@ export class ColorModule { color = formatHexColor(color, options); return color; } + color = Array.from({ length: 3 }, () => this.faker.number.int(255)); if (includeAlpha) { color.push(this.faker.number.float()); cssFunction = 'rgba'; } + return toColorFormat(color, format, cssFunction); } @@ -460,6 +466,7 @@ export class ColorModule { for (let i = 0; i < (options?.includeAlpha ? 3 : 2); i++) { hsl.push(this.faker.number.float()); } + return toColorFormat( hsl, options?.format || 'decimal', @@ -537,6 +544,7 @@ export class ColorModule { for (let i = 0; i < 2; i++) { hsl.push(this.faker.number.float()); } + return toColorFormat(hsl, options?.format || 'decimal', 'hwb'); } @@ -598,6 +606,7 @@ export class ColorModule { this.faker.number.float({ min: -100, max: 100, precision: 0.0001 }) ); } + return toColorFormat(lab, options?.format || 'decimal', 'lab'); } @@ -669,6 +678,7 @@ export class ColorModule { for (let i = 0; i < 2; i++) { lch.push(this.faker.number.float({ max: 230, precision: 0.1 })); } + return toColorFormat(lch, options?.format || 'decimal', 'lch'); } @@ -742,6 +752,7 @@ export class ColorModule { if (options?.format === 'css' && !options?.space) { options = { ...options, space: 'sRGB' }; } + const color = Array.from({ length: 3 }, () => this.faker.number.float({ precision: 0.0001 }) ); diff --git a/src/modules/commerce/index.ts b/src/modules/commerce/index.ts index 99515463bc7..4afa881988f 100644 --- a/src/modules/commerce/index.ts +++ b/src/modules/commerce/index.ts @@ -10,6 +10,7 @@ export class CommerceModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } diff --git a/src/modules/company/index.ts b/src/modules/company/index.ts index d4b181f6be7..70c40521a9f 100644 --- a/src/modules/company/index.ts +++ b/src/modules/company/index.ts @@ -10,6 +10,7 @@ export class CompanyModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } diff --git a/src/modules/database/index.ts b/src/modules/database/index.ts index d0985c53f4f..922f4b0ea65 100644 --- a/src/modules/database/index.ts +++ b/src/modules/database/index.ts @@ -10,6 +10,7 @@ export class DatabaseModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } diff --git a/src/modules/datatype/index.ts b/src/modules/datatype/index.ts index f9c2bac6759..f62d3a680a0 100644 --- a/src/modules/datatype/index.ts +++ b/src/modules/datatype/index.ts @@ -11,6 +11,7 @@ export class DatatypeModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } @@ -211,14 +212,17 @@ export class DatatypeModule { probability: options, }; } + const { probability = 0.5 } = options; if (probability <= 0) { return false; } + if (probability >= 1) { // This check is required to avoid returning false when float() returns 1 return true; } + return this.faker.number.float() < probability; } diff --git a/src/modules/date/index.ts b/src/modules/date/index.ts index e8bdde283eb..c9c2eb5a556 100644 --- a/src/modules/date/index.ts +++ b/src/modules/date/index.ts @@ -28,6 +28,7 @@ export class DateModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } diff --git a/src/modules/finance/iban.ts b/src/modules/finance/iban.ts index 9b4780c537f..2eb6fbba4f2 100644 --- a/src/modules/finance/iban.ts +++ b/src/modules/finance/iban.ts @@ -1401,6 +1401,7 @@ const iban: Iban = { for (let i = 0; i < digitStr.length; i++) { m = (m * 10 + +digitStr[i]) % 97; } + return m; }, pattern10: ['01', '02', '03', '04', '05', '06', '07', '08', '09'], diff --git a/src/modules/finance/index.ts b/src/modules/finance/index.ts index 9c34faa21d2..bc540afc9ee 100644 --- a/src/modules/finance/index.ts +++ b/src/modules/finance/index.ts @@ -12,6 +12,7 @@ export class FinanceModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } @@ -34,6 +35,7 @@ export class FinanceModule { for (let i = 0; i < length; i++) { template += '#'; } + length = null; return this.faker.helpers.replaceSymbolWithNumber(template); } @@ -219,6 +221,7 @@ export class FinanceModule { this.faker.definitions.finance.currency )['symbol']; } + return symbol; } @@ -292,6 +295,7 @@ export class FinanceModule { const formats = this.faker.helpers.objectValue(localeFormat); // There could be multiple formats format = this.faker.helpers.arrayElement(formats); } + format = format.replace(/\//g, ''); return this.faker.helpers.replaceCreditCardSymbols(format); } @@ -338,6 +342,7 @@ export class FinanceModule { if (length < 1) { throw new FakerError('minimum length is 1'); } + return this.faker.string.numeric({ length, allowLeadingZeros: true }); } @@ -409,10 +414,13 @@ export class FinanceModule { s += this.faker.number.int(9); } } + c--; } + s = s.substring(0, count); } + let checksum: string | number = 98 - iban.mod97(iban.toDigitString(`${s}${ibanFormat.country}00`)); diff --git a/src/modules/git/index.ts b/src/modules/git/index.ts index 31df251871e..4d8e2cd01b3 100644 --- a/src/modules/git/index.ts +++ b/src/modules/git/index.ts @@ -28,6 +28,7 @@ export class GitModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } diff --git a/src/modules/hacker/index.ts b/src/modules/hacker/index.ts index d842d74e2a3..aadf839a779 100644 --- a/src/modules/hacker/index.ts +++ b/src/modules/hacker/index.ts @@ -10,6 +10,7 @@ export class HackerModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } diff --git a/src/modules/helpers/index.ts b/src/modules/helpers/index.ts index 2ccc311e21e..3bdc2f68362 100644 --- a/src/modules/helpers/index.ts +++ b/src/modules/helpers/index.ts @@ -14,6 +14,7 @@ export class HelpersModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } @@ -65,6 +66,7 @@ export class HelpersModule { str += string.charAt(i); } } + return str; } @@ -130,6 +132,7 @@ export class HelpersModule { str += string.charAt(i); } } + return str; } @@ -199,6 +202,7 @@ export class HelpersModule { max = min; min = tmp; } + repetitions = this.faker.number.int({ min, max }); string = string.slice(0, token.index) + @@ -206,6 +210,7 @@ export class HelpersModule { string.slice(token.index + token[0].length); token = string.match(RANGE_REP_REG); } + // Deal with repeat `{num}` token = string.match(REP_REG); while (token != null) { @@ -229,12 +234,14 @@ export class HelpersModule { max = min; min = tmp; } + string = string.slice(0, token.index) + this.faker.number.int({ min, max }).toString() + string.slice(token.index + token[0].length); token = string.match(RANGE_REG); } + return string; } @@ -320,6 +327,7 @@ export class HelpersModule { const array = Array.from(set); return this.shuffle(array).splice(0, length); } + const set = new Set(); try { if (typeof source === 'function') { @@ -330,6 +338,7 @@ export class HelpersModule { } catch { // Ignore } + return Array.from(set); } @@ -356,6 +365,7 @@ export class HelpersModule { if (str == null) { return ''; } + for (const p in data) { const re = new RegExp(`{{${p}}}`, 'g'); const value = data[p]; @@ -365,6 +375,7 @@ export class HelpersModule { str = str.replace(re, value); } } + return str; } @@ -390,12 +401,14 @@ export class HelpersModule { if (this.faker.datatype.boolean(options)) { return callback(); } + return undefined; } /** * Returns a random key from given object or `undefined` if no key could be found. * + * @template T The type of the object to select from. * @param object The object to be used. * * @example @@ -411,6 +424,7 @@ export class HelpersModule { /** * Returns a random value from given object or `undefined` if no key could be found. * + * @template T The type of object to select from. * @param object The object to be used. * * @example @@ -738,6 +752,7 @@ export class HelpersModule { if (typeof numberOrRange === 'number') { return numberOrRange; } + return this.faker.number.int(numberOrRange); } @@ -788,6 +803,7 @@ export class HelpersModule { /** * Generates an array containing values returned by the given method. * + * @template T The type of elements. * @param method The method used to generate the values. * @param options The optional options object. * @param options.count The number or range of elements to generate. Defaults to `3`. diff --git a/src/modules/helpers/luhn-check.ts b/src/modules/helpers/luhn-check.ts index 9cfcc577798..7d841878261 100644 --- a/src/modules/helpers/luhn-check.ts +++ b/src/modules/helpers/luhn-check.ts @@ -35,8 +35,10 @@ function luhnChecksum(str: string): number { n = (n % 10) + 1; } } + sum += n; alternate = !alternate; } + return sum % 10; } diff --git a/src/modules/helpers/unique.ts b/src/modules/helpers/unique.ts index 31fddec8c94..fd240c2f0de 100644 --- a/src/modules/helpers/unique.ts +++ b/src/modules/helpers/unique.ts @@ -28,6 +28,7 @@ function defaultCompare( if (obj[key] === undefined) { return -1; } + return 0; } diff --git a/src/modules/image/index.ts b/src/modules/image/index.ts index cf59627db46..6a2d6144fed 100644 --- a/src/modules/image/index.ts +++ b/src/modules/image/index.ts @@ -30,6 +30,7 @@ export class ImageModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } diff --git a/src/modules/image/providers/placeholder.ts b/src/modules/image/providers/placeholder.ts index d2cc9f51004..9691a9ff7f5 100644 --- a/src/modules/image/providers/placeholder.ts +++ b/src/modules/image/providers/placeholder.ts @@ -13,6 +13,7 @@ export class Placeholder { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } diff --git a/src/modules/internet/index.ts b/src/modules/internet/index.ts index 2bac0668928..8f5cc8bbba6 100644 --- a/src/modules/internet/index.ts +++ b/src/modules/internet/index.ts @@ -33,6 +33,7 @@ export class InternetModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } @@ -173,10 +174,12 @@ export class InternetModule { if (charMapping[char]) { return charMapping[char]; } + if (char.charCodeAt(0) < 0x80) { // Keep ASCII characters return char; } + // Final fallback return the Unicode char code value for Chinese, Japanese, Korean etc, base-36 encoded return char.charCodeAt(0).toString(36); }) @@ -224,6 +227,7 @@ export class InternetModule { ])}${lastName}${this.faker.number.int(99)}`; break; } + result = result.toString().replace(/'/g, ''); result = result.replace(/ /g, ''); return result; @@ -493,6 +497,7 @@ export class InternetModule { mac += validSep; } } + return mac; } @@ -536,6 +541,7 @@ export class InternetModule { if (prefix.length >= length) { return prefix; } + if (memorable) { if (prefix.match(consonant)) { pattern = vowel; @@ -543,16 +549,20 @@ export class InternetModule { pattern = consonant; } } + const n = this.faker.number.int(94) + 33; let char = String.fromCharCode(n); if (memorable) { char = char.toLowerCase(); } + if (!char.match(pattern)) { return _password(length, memorable, pattern, prefix); } + return _password(length, memorable, pattern, prefix + char); }; + return _password(len, memorable, pattern, prefix); } diff --git a/src/modules/internet/user-agent.ts b/src/modules/internet/user-agent.ts index 005e31e62d2..40bc025f12d 100644 --- a/src/modules/internet/user-agent.ts +++ b/src/modules/internet/user-agent.ts @@ -70,6 +70,7 @@ export function generate(faker: Faker): string { if (rand >= min && rand <= max) { break; } + min = min + obj[key]; } } @@ -219,6 +220,7 @@ export function generate(faker: Faker): string { for (let x = 0; x < dots; x++) { return_val += `.${faker.string.numeric({ allowLeadingZeros: true })}`; } + return return_val; }; diff --git a/src/modules/location/index.ts b/src/modules/location/index.ts index a53c11d7abc..4e25cbb955c 100644 --- a/src/modules/location/index.ts +++ b/src/modules/location/index.ts @@ -10,6 +10,7 @@ export class LocationModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } @@ -39,6 +40,7 @@ export class LocationModule { format = this.faker.helpers.arrayElement(localeFormat); } } + return this.faker.helpers.replaceSymbols(format); } @@ -62,6 +64,7 @@ export class LocationModule { if (zipRange) { return String(this.faker.number.int(zipRange)); } + return this.zipCode(); } @@ -309,6 +312,7 @@ export class LocationModule { this.faker.definitions.location.direction ); } + return this.faker.helpers.arrayElement( this.faker.definitions.location.direction_abbr ); @@ -333,6 +337,7 @@ export class LocationModule { this.faker.definitions.location.direction.slice(0, 4) ); } + return this.faker.helpers.arrayElement( this.faker.definitions.location.direction_abbr.slice(0, 4) ); @@ -357,6 +362,7 @@ export class LocationModule { this.faker.definitions.location.direction.slice(4, 8) ); } + return this.faker.helpers.arrayElement( this.faker.definitions.location.direction_abbr.slice(4, 8) ); @@ -419,6 +425,7 @@ export class LocationModule { newCoordinate[0] = Math.sign(newCoordinate[0]) * 180 - newCoordinate[0]; newCoordinate[1] += 180; } + // Box longitude [-180°, 180°] newCoordinate[1] = (((newCoordinate[1] % 360) + 540) % 360) - 180; diff --git a/src/modules/lorem/index.ts b/src/modules/lorem/index.ts index 8e989ab60de..37fb2cd7aff 100644 --- a/src/modules/lorem/index.ts +++ b/src/modules/lorem/index.ts @@ -11,6 +11,7 @@ export class LoremModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } diff --git a/src/modules/music/index.ts b/src/modules/music/index.ts index 482ee2b0c8b..e25ade687de 100644 --- a/src/modules/music/index.ts +++ b/src/modules/music/index.ts @@ -10,6 +10,7 @@ export class MusicModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } diff --git a/src/modules/number/index.ts b/src/modules/number/index.ts index d3f27453429..54352fcd364 100644 --- a/src/modules/number/index.ts +++ b/src/modules/number/index.ts @@ -12,6 +12,7 @@ export class NumberModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } @@ -56,6 +57,7 @@ export class NumberModule { `No integer value between ${min} and ${max} found.` ); } + throw new FakerError(`Max ${max} should be greater than min ${min}.`); } diff --git a/src/modules/person/index.ts b/src/modules/person/index.ts index b9369a965d5..59202fb0058 100644 --- a/src/modules/person/index.ts +++ b/src/modules/person/index.ts @@ -65,6 +65,7 @@ export class PersonModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } diff --git a/src/modules/phone/index.ts b/src/modules/phone/index.ts index 3e6d9815df5..437464bff59 100644 --- a/src/modules/phone/index.ts +++ b/src/modules/phone/index.ts @@ -10,6 +10,7 @@ export class PhoneModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } diff --git a/src/modules/random/index.ts b/src/modules/random/index.ts index 1f4b499b505..88f81c63ee6 100644 --- a/src/modules/random/index.ts +++ b/src/modules/random/index.ts @@ -18,6 +18,7 @@ export class RandomModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } @@ -206,6 +207,7 @@ export class RandomModule { if (typeof options === 'number') { return this.faker.string.alpha(options); } + return this.faker.string.alpha({ length: options.count, casing: options.casing, diff --git a/src/modules/science/index.ts b/src/modules/science/index.ts index 51203a3a47c..7dba5d3daf2 100644 --- a/src/modules/science/index.ts +++ b/src/modules/science/index.ts @@ -39,6 +39,7 @@ export class ScienceModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } diff --git a/src/modules/string/index.ts b/src/modules/string/index.ts index 32f76b722fd..ab16dc34bf8 100644 --- a/src/modules/string/index.ts +++ b/src/modules/string/index.ts @@ -91,6 +91,7 @@ export class StringModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } @@ -440,6 +441,7 @@ export class StringModule { const value = placeholder === 'x' ? random : (random & 0x3) | 0x8; return value.toString(16); }; + return RFC4122_TEMPLATE.replace(/[xy]/g, replacePlaceholders); } diff --git a/src/modules/system/index.ts b/src/modules/system/index.ts index ca78929e111..202f989960b 100644 --- a/src/modules/system/index.ts +++ b/src/modules/system/index.ts @@ -42,6 +42,7 @@ export class SystemModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } diff --git a/src/modules/vehicle/index.ts b/src/modules/vehicle/index.ts index dd08b75fb0c..9c9841b08be 100644 --- a/src/modules/vehicle/index.ts +++ b/src/modules/vehicle/index.ts @@ -10,6 +10,7 @@ export class VehicleModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } diff --git a/src/modules/word/index.ts b/src/modules/word/index.ts index 22a22a0b65d..414fe62241a 100644 --- a/src/modules/word/index.ts +++ b/src/modules/word/index.ts @@ -12,6 +12,7 @@ export class WordModule { if (name === 'constructor' || typeof this[name] !== 'function') { continue; } + this[name] = this[name].bind(this); } } @@ -392,6 +393,7 @@ export class WordModule { if (typeof options === 'number') { options = { count: options }; } + const { count = { min: 1, max: 3 } } = options; return this.faker.helpers diff --git a/test/all_functional.spec.ts b/test/all_functional.spec.ts index 0d630d47a6d..abc34d82cef 100644 --- a/test/all_functional.spec.ts +++ b/test/all_functional.spec.ts @@ -63,6 +63,7 @@ function modulesList(): { [module: string]: string[] } { } else { console.log(`Skipping ${mod} - No testable methods`); } + return result; }, {}); diff --git a/test/date.spec.ts b/test/date.spec.ts index 75f203cca5f..d8e617d6529 100644 --- a/test/date.spec.ts +++ b/test/date.spec.ts @@ -346,6 +346,7 @@ describe('date', () => { for (let i = 1; i < dates.length; i++) { expect(dates[i]).greaterThan(dates[i - 1]); } + expect(dates[dates.length - 1]).lessThan(to); } ); diff --git a/test/scripts/apidoc/examplesAndDeprecations.spec.ts b/test/scripts/apidoc/examplesAndDeprecations.spec.ts index 772307a9d04..df1769b4364 100644 --- a/test/scripts/apidoc/examplesAndDeprecations.spec.ts +++ b/test/scripts/apidoc/examplesAndDeprecations.spec.ts @@ -3,8 +3,20 @@ import { resolve } from 'node:path'; import type { DeclarationReflection, SignatureReflection } from 'typedoc'; import { ReflectionKind } from 'typedoc'; import type { SpyInstance } from 'vitest'; -import { afterAll, beforeEach, describe, expect, it, vi } from 'vitest'; +import { + afterAll, + beforeAll, + beforeEach, + describe, + expect, + it, + vi, +} from 'vitest'; import { selectApiModules } from '../../../scripts/apidoc/moduleMethods'; +import { + analyzeSignature, + initMarkdownRenderer, +} from '../../../scripts/apidoc/signature'; import { extractRawExamples, extractSeeAlsos, @@ -27,6 +39,8 @@ const locales: Record = { DE: 'de', }; +beforeAll(initMarkdownRenderer); + describe('examples and deprecations', () => { const project = loadProject(); @@ -107,6 +121,18 @@ describe('examples and deprecations', () => { } } + // Verify @param tags + analyzeSignature(signature, moduleName, methodName).parameters.forEach( + (param) => { + const { name, description } = param; + const plainDescription = description.replace(/<[^>]+>/g, '').trim(); + expect( + plainDescription, + `Expect param ${name} to have a description` + ).not.toBe('Missing'); + } + ); + // Verify @see tag extractSeeAlsos(signature).forEach((link) => { if (link.startsWith('faker.')) { diff --git a/test/support/seededRuns.ts b/test/support/seededRuns.ts index aa6d5a9b249..2c1cbab775a 100644 --- a/test/support/seededRuns.ts +++ b/test/support/seededRuns.ts @@ -219,6 +219,7 @@ class TestGenerator< for (const method of methods) { this.it(method); } + return this; } @@ -244,6 +245,7 @@ class TestGenerator< ).toBeFalsy(); variantNames.add(name); }; + const tester: MethodTester = { it(name: string, ...args: Parameters) { expectVariantNotTested(name); @@ -279,6 +281,7 @@ class TestGenerator< for (const method of methods) { this.describe(method, factory); } + return this; }; }