aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorST-DDT <[email protected]>2024-11-14 22:50:04 +0100
committerGitHub <[email protected]>2024-11-14 21:50:04 +0000
commit188309a59cfe6fbd33e120dedf3bdfef3276d641 (patch)
tree079d062e07065b11ae0bcf8c8cb964174a842080
parenta54c1edb87e88b198966d248d5273c9898c32798 (diff)
downloadfaker-188309a59cfe6fbd33e120dedf3bdfef3276d641.tar.xz
faker-188309a59cfe6fbd33e120dedf3bdfef3276d641.zip
infra(unicorn): consistent-function-scoping (#3255)
-rw-r--r--eslint.config.ts1
-rw-r--r--src/modules/color/index.ts26
-rw-r--r--src/modules/food/index.ts18
-rw-r--r--src/modules/internet/index.ts83
-rw-r--r--src/modules/system/index.ts21
-rw-r--r--test/modules/date.spec.ts26
-rw-r--r--test/modules/git.spec.ts23
-rw-r--r--test/modules/number.spec.ts16
-rw-r--r--test/utils/mersenne.spec.ts8
9 files changed, 132 insertions, 90 deletions
diff --git a/eslint.config.ts b/eslint.config.ts
index aeebdf0e..6077b0a6 100644
--- a/eslint.config.ts
+++ b/eslint.config.ts
@@ -162,7 +162,6 @@ const config: ReturnType<typeof tseslint.config> = tseslint.config(
// TODO @Shinigami92 2023-09-23: The following rules currently conflict with our code.
// Each rule should be checked whether it should be enabled/configured and the problems fixed, or stay disabled permanently.
- 'unicorn/consistent-function-scoping': 'off',
'unicorn/prefer-export-from': 'off',
'unicorn/prevent-abbreviations': 'off',
},
diff --git a/src/modules/color/index.ts b/src/modules/color/index.ts
index 2b355062..10d7023a 100644
--- a/src/modules/color/index.ts
+++ b/src/modules/color/index.ts
@@ -102,6 +102,15 @@ function toBinary(values: number[]): string {
}
/**
+ * Converts the given value to a percentage (`round(value * 100)`).
+ *
+ * @param value The value to convert to a percentage.
+ */
+function toPercentage(value: number): number {
+ return Math.round(value * 100);
+}
+
+/**
* Converts an array of numbers into CSS accepted format.
*
* @param values Array of values to be converted.
@@ -113,7 +122,6 @@ function toCSS(
cssFunction: CssFunctionType = 'rgb',
space: CssSpaceType = 'sRGB'
): string {
- const percentage = (value: number) => Math.round(value * 100);
switch (cssFunction) {
case 'rgba': {
return `rgba(${values[0]}, ${values[1]}, ${values[2]}, ${values[3]})`;
@@ -124,35 +132,35 @@ function toCSS(
}
case 'cmyk': {
- return `cmyk(${percentage(values[0])}%, ${percentage(
+ return `cmyk(${toPercentage(values[0])}%, ${toPercentage(
values[1]
- )}%, ${percentage(values[2])}%, ${percentage(values[3])}%)`;
+ )}%, ${toPercentage(values[2])}%, ${toPercentage(values[3])}%)`;
}
case 'hsl': {
- return `hsl(${values[0]}deg ${percentage(values[1])}% ${percentage(
+ return `hsl(${values[0]}deg ${toPercentage(values[1])}% ${toPercentage(
values[2]
)}%)`;
}
case 'hsla': {
- return `hsl(${values[0]}deg ${percentage(values[1])}% ${percentage(
+ return `hsl(${values[0]}deg ${toPercentage(values[1])}% ${toPercentage(
values[2]
- )}% / ${percentage(values[3])})`;
+ )}% / ${toPercentage(values[3])})`;
}
case 'hwb': {
- return `hwb(${values[0]} ${percentage(values[1])}% ${percentage(
+ return `hwb(${values[0]} ${toPercentage(values[1])}% ${toPercentage(
values[2]
)}%)`;
}
case 'lab': {
- return `lab(${percentage(values[0])}% ${values[1]} ${values[2]})`;
+ return `lab(${toPercentage(values[0])}% ${values[1]} ${values[2]})`;
}
case 'lch': {
- return `lch(${percentage(values[0])}% ${values[1]} ${values[2]})`;
+ return `lch(${toPercentage(values[0])}% ${values[1]} ${values[2]})`;
}
case 'rgb': {
diff --git a/src/modules/food/index.ts b/src/modules/food/index.ts
index 45b91f30..8dd77741 100644
--- a/src/modules/food/index.ts
+++ b/src/modules/food/index.ts
@@ -1,4 +1,17 @@
import { ModuleBase } from '../../internal/module-base';
+
+/**
+ * Converts the given string to title case.
+ *
+ * @param text The text to convert.
+ */
+function toTitleCase(text: string): string {
+ return text
+ .split(' ')
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
+ .join(' ');
+}
+
/**
* Module for generating food-related data.
*
@@ -47,11 +60,6 @@ export class FoodModule extends ModuleBase {
*/
dish(): string {
// A 50/50 mix of specific dishes and dish_patterns
- const toTitleCase = (s: string) =>
- s
- .split(' ')
- .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
- .join(' ');
if (this.faker.datatype.boolean()) {
return toTitleCase(
this.faker.helpers.fake(this.faker.definitions.food.dish_pattern)
diff --git a/src/modules/internet/index.ts b/src/modules/internet/index.ts
index 115bd215..4c78f4cb 100644
--- a/src/modules/internet/index.ts
+++ b/src/modules/internet/index.ts
@@ -1,4 +1,5 @@
import { FakerError } from '../../errors/faker-error';
+import type { Faker } from '../../faker';
import { toBase64Url } from '../../internal/base64';
import { deprecated } from '../../internal/deprecated';
import { ModuleBase } from '../../internal/module-base';
@@ -103,6 +104,50 @@ const ipv4Networks: Record<IPv4Network, string> = {
};
/**
+ * Checks whether the given string is a valid slug for `domainWord`s.
+ *
+ * @param slug The slug to check.
+ */
+function isValidDomainWordSlug(slug: string): boolean {
+ return /^[a-z][a-z-]*[a-z]$/i.exec(slug) !== null;
+}
+
+/**
+ * Tries various ways to produce a valid domain word slug, falling back to a random string if needed.
+ *
+ * @param faker The faker instance to use.
+ * @param word The initial word to slugify.
+ */
+function makeValidDomainWordSlug(faker: Faker, word: string): string {
+ const slug1 = faker.helpers.slugify(word);
+ if (isValidDomainWordSlug(slug1)) {
+ return slug1;
+ }
+
+ const slug2 = faker.helpers.slugify(faker.lorem.word());
+ if (isValidDomainWordSlug(slug2)) {
+ return slug2;
+ }
+
+ return faker.string.alpha({
+ casing: 'lower',
+ length: faker.number.int({ min: 4, max: 8 }),
+ });
+}
+
+/**
+ * Generates a random color in hex format with the given base color.
+ *
+ * @param faker The faker instance to use.
+ * @param base The base color to use.
+ */
+function colorFromBase(faker: Faker, base: number): string {
+ return Math.floor((faker.number.int(256) + base) / 2)
+ .toString(16)
+ .padStart(2, '0');
+}
+
+/**
* Module to generate internet related entries.
*
* ### Overview
@@ -597,29 +642,12 @@ export class InternetModule extends ModuleBase {
domainWord(): string {
// Generate an ASCII "word" in the form `noun-adjective`
// For locales with non-ASCII characters, we fall back to lorem words, or a random string
- const isValidSlug = (slug: string): boolean => {
- return /^[a-z][a-z-]*[a-z]$/i.exec(slug) !== null;
- };
-
- const makeValidSlug = (word: string): string => {
- const slug1 = this.faker.helpers.slugify(word);
- if (isValidSlug(slug1)) {
- return slug1;
- }
- const slug2 = this.faker.helpers.slugify(this.faker.lorem.word());
- if (isValidSlug(slug2)) {
- return slug2;
- }
-
- return this.faker.string.alpha({
- casing: 'lower',
- length: this.faker.number.int({ min: 4, max: 8 }),
- });
- };
-
- const word1 = makeValidSlug(this.faker.word.adjective());
- const word2 = makeValidSlug(this.faker.word.noun());
+ const word1 = makeValidDomainWordSlug(
+ this.faker,
+ this.faker.word.adjective()
+ );
+ const word2 = makeValidDomainWordSlug(this.faker, this.faker.word.noun());
return `${word1}-${word2}`.toLowerCase();
}
@@ -819,14 +847,9 @@ export class InternetModule extends ModuleBase {
): string {
const { redBase = 0, greenBase = 0, blueBase = 0 } = options;
- const colorFromBase = (base: number): string =>
- Math.floor((this.faker.number.int(256) + base) / 2)
- .toString(16)
- .padStart(2, '0');
-
- const red = colorFromBase(redBase);
- const green = colorFromBase(greenBase);
- const blue = colorFromBase(blueBase);
+ const red = colorFromBase(this.faker, redBase);
+ const green = colorFromBase(this.faker, greenBase);
+ const blue = colorFromBase(this.faker, blueBase);
return `#${red}${green}${blue}`;
}
diff --git a/src/modules/system/index.ts b/src/modules/system/index.ts
index aec3525e..1c387e51 100644
--- a/src/modules/system/index.ts
+++ b/src/modules/system/index.ts
@@ -263,17 +263,17 @@ export class SystemModule extends ModuleBase {
let suffix: string;
let prefix = '';
- const digit = () => this.faker.string.numeric({ allowLeadingZeros: true });
switch (interfaceSchema) {
case 'index': {
- suffix = digit();
+ suffix = this.faker.string.numeric();
break;
}
case 'slot': {
- suffix = `${digit()}${
- this.faker.helpers.maybe(() => `f${digit()}`) ?? ''
- }${this.faker.helpers.maybe(() => `d${digit()}`) ?? ''}`;
+ suffix = `${this.faker.string.numeric()}${
+ this.faker.helpers.maybe(() => `f${this.faker.string.numeric()}`) ??
+ ''
+ }${this.faker.helpers.maybe(() => `d${this.faker.string.numeric()}`) ?? ''}`;
break;
}
@@ -283,10 +283,13 @@ export class SystemModule extends ModuleBase {
}
case 'pci': {
- prefix = this.faker.helpers.maybe(() => `P${digit()}`) ?? '';
- suffix = `${digit()}s${digit()}${
- this.faker.helpers.maybe(() => `f${digit()}`) ?? ''
- }${this.faker.helpers.maybe(() => `d${digit()}`) ?? ''}`;
+ prefix =
+ this.faker.helpers.maybe(() => `P${this.faker.string.numeric()}`) ??
+ '';
+ suffix = `${this.faker.string.numeric()}s${this.faker.string.numeric()}${
+ this.faker.helpers.maybe(() => `f${this.faker.string.numeric()}`) ??
+ ''
+ }${this.faker.helpers.maybe(() => `d${this.faker.string.numeric()}`) ?? ''}`;
break;
}
}
diff --git a/test/modules/date.spec.ts b/test/modules/date.spec.ts
index e30da8d9..19a2d0a7 100644
--- a/test/modules/date.spec.ts
+++ b/test/modules/date.spec.ts
@@ -12,6 +12,19 @@ const converterMap = [
const NON_SEEDED_BASED_RUN = 5;
const refDate = '2021-02-21T17:09:15.711Z';
+function calculateAge(birthdate: Date, refDate: Date): number {
+ let age = refDate.getFullYear() - birthdate.getFullYear();
+ if (
+ refDate.getMonth() < birthdate.getMonth() ||
+ (refDate.getMonth() === birthdate.getMonth() &&
+ refDate.getDate() < birthdate.getDate())
+ ) {
+ age--;
+ }
+
+ return age;
+}
+
describe('date', () => {
seededTests(faker, 'date', (t) => {
t.describe('anytime', (t) => {
@@ -530,19 +543,6 @@ describe('date', () => {
});
describe('birthdate', () => {
- function calculateAge(birthdate: Date, refDate: Date): number {
- let age = refDate.getFullYear() - birthdate.getFullYear();
- if (
- refDate.getMonth() < birthdate.getMonth() ||
- (refDate.getMonth() === birthdate.getMonth() &&
- refDate.getDate() < birthdate.getDate())
- ) {
- age--;
- }
-
- return age;
- }
-
it('returns a random birthdate', () => {
const birthdate = faker.date.birthdate();
expect(birthdate).toBeInstanceOf(Date);
diff --git a/test/modules/git.spec.ts b/test/modules/git.spec.ts
index e4692b20..164b19c6 100644
--- a/test/modules/git.spec.ts
+++ b/test/modules/git.spec.ts
@@ -8,6 +8,16 @@ const NON_SEEDED_BASED_RUN = 5;
const refDate = '2020-01-01T00:00:00.000Z';
+function isValidCommitAuthor(email: string): boolean {
+ // `validator.isEmail()` does not support display names
+ // that contain unquoted characters like . output by Git so we need
+ // to quote the display name
+ const quotedEmail = email.replace(/^(.*) </, '"$1" <');
+ return validator.isEmail(quotedEmail, {
+ require_display_name: true,
+ });
+}
+
describe('git', () => {
seededTests(faker, 'git', (t) => {
t.itEach('branch', 'commitMessage');
@@ -56,27 +66,18 @@ describe('git', () => {
expect(parts.length).toBeLessThanOrEqual(7);
expect(parts[0]).toMatch(/^commit [a-f0-9]+$/);
- const isValidAuthor = (email: string) => {
- // `validator.isEmail()` does not support display names
- // that contain unquoted characters like . output by Git so we need
- // to quote the display name
- const quotedEmail = email.replace(/^(.*) </, '"$1" <');
- return validator.isEmail(quotedEmail, {
- require_display_name: true,
- });
- };
const authorRegex = /^Author: .*$/;
if (parts.length === 7) {
expect(parts[1]).toMatch(/^Merge: [a-f0-9]+ [a-f0-9]+$/);
expect(parts[2]).toMatch(authorRegex);
- expect(parts[2].substring(8)).toSatisfy(isValidAuthor);
+ expect(parts[2].substring(8)).toSatisfy(isValidCommitAuthor);
expect(parts[3]).toMatch(/^Date: .+$/);
expect(parts[4]).toBe('');
expect(parts[5]).toMatch(/^\s{4}.+$/);
} else {
expect(parts[1]).toMatch(authorRegex);
- expect(parts[1].substring(8)).toSatisfy(isValidAuthor);
+ expect(parts[1].substring(8)).toSatisfy(isValidCommitAuthor);
expect(parts[2]).toMatch(/^Date: .+$/);
expect(parts[3]).toBe('');
expect(parts[4]).toMatch(/^\s{4}.+$/);
diff --git a/test/modules/number.spec.ts b/test/modules/number.spec.ts
index cfd50b20..3b21f64c 100644
--- a/test/modules/number.spec.ts
+++ b/test/modules/number.spec.ts
@@ -5,6 +5,14 @@ import { seededTests } from '../support/seeded-runs';
import { MERSENNE_MAX_VALUE } from '../utils/mersenne-test-utils';
import { times } from './../support/times';
+function isFloat(value: number): boolean {
+ return value % 1 !== 0;
+}
+
+function isBinary(str: string): boolean {
+ return [...str].every((char) => char === '0' || char === '1');
+}
+
describe('number', () => {
seededTests(faker, 'number', (t) => {
t.describeEach(
@@ -259,10 +267,6 @@ describe('number', () => {
});
describe('float', () => {
- function isFloat(value: number) {
- return value % 1 !== 0;
- }
-
it('should return a float between 0 and 1 (inclusive) by default', () => {
const actual = faker.number.float();
@@ -405,10 +409,6 @@ describe('number', () => {
});
describe('binary', () => {
- function isBinary(str: string) {
- return [...str].every((char) => char === '0' || char === '1');
- }
-
it('generates single binary character when no additional argument was provided', () => {
const binary = faker.number.binary();
diff --git a/test/utils/mersenne.spec.ts b/test/utils/mersenne.spec.ts
index 5e9e4c27..4699b9b0 100644
--- a/test/utils/mersenne.spec.ts
+++ b/test/utils/mersenne.spec.ts
@@ -23,6 +23,10 @@ function newTwister(
return twister;
}
+function randomSeed(): number {
+ return Math.ceil(Math.random() * 1_000_000_000);
+}
+
describe('MersenneTwister19937', () => {
describe('genrandInt32()', () => {
it('should be able to return 0', () => {
@@ -112,10 +116,6 @@ describe.each([
});
});
- function randomSeed(): number {
- return Math.ceil(Math.random() * 1_000_000_000);
- }
-
// Create and log-back the seed for debug purposes
describe.each(
times(NON_SEEDED_BASED_RUN).flatMap(() => [