Skip to content

Commit

Permalink
Merge branch 'next' into test/cleanup/randomSeed
Browse files Browse the repository at this point in the history
  • Loading branch information
ST-DDT authored Nov 19, 2024
2 parents 10f0e33 + eae226e commit bf4e3a3
Show file tree
Hide file tree
Showing 16 changed files with 1,014 additions and 475 deletions.
3 changes: 3 additions & 0 deletions .versionrc.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"scripts": {
"postbump": "export VERSION=$(jq -r .version package.json); sed -i -E \"s/@faker-js\\/faker@v[0-9]+\\.[0-9]+\\.[0-9]+(-(alpha|beta|rc)\\.[0-9]+)?/@faker-js\\/faker@v$VERSION/g\" docs/guide/usage.md; git add docs/guide/usage.md"
},
"skip": {
"tag": true
},
Expand Down
1 change: 0 additions & 1 deletion eslint.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
},
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"docs:test:e2e:ci": "run-s docs:build:ci docs:test:e2e:run",
"docs:test:e2e:run": "run-p --race docs:serve \"cypress run\"",
"docs:test:e2e:open": "run-p --race docs:serve \"cypress open\"",
"release": "commit-and-tag-version",
"release": "commit-and-tag-version --commit-all",
"prepublishOnly": "pnpm run clean && pnpm install && pnpm run build",
"preflight": "pnpm install && run-s generate format lint build test:update-snapshots ts-check"
},
Expand Down
800 changes: 425 additions & 375 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

9 changes: 2 additions & 7 deletions scripts/apidocs/processing/class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
processClassConstructors,
processClassMethods,
processInterfaceMethods,
processProjectFunctions,
processUtilityFunctions,
} from './method';

/**
Expand Down Expand Up @@ -192,12 +192,7 @@ export function processProjectUtilities(project: Project): RawApiDocsPage {
deprecated: undefined,
description: 'A list of all the utilities available in Faker.js.',
examples: [],
methods: processProjectFunctions(
project,
'mergeLocales',
'generateMersenne32Randomizer',
'generateMersenne53Randomizer'
),
methods: processUtilityFunctions(project),
};
}

Expand Down
10 changes: 4 additions & 6 deletions scripts/apidocs/processing/method.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
type MethodDeclaration,
} from 'ts-morph';
import { groupBy } from '../../../src/internal/group-by';
import { valuesForKeys } from '../utils/value-checks';
import { newProcessingError } from './error';
import type {
RawApiDocsSignature,
Expand Down Expand Up @@ -138,12 +137,11 @@ function getAllFunctions(
);
}

export function processProjectFunctions(
project: Project,
...names: string[]
): RawApiDocsMethod[] {
export function processUtilityFunctions(project: Project): RawApiDocsMethod[] {
return processMethodLikes(
valuesForKeys(getAllFunctions(project), names),
Object.values(getAllFunctions(project)).filter((fn) =>
fn.getSourceFile().getFilePath().includes('/src/utils/')
),
(f) => f.getNameOrThrow()
);
}
Expand Down
26 changes: 17 additions & 9 deletions src/modules/color/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,15 @@ function toBinary(values: number[]): string {
return binary.join(' ');
}

/**
* 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.
*
Expand All @@ -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]})`;
Expand All @@ -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': {
Expand Down
18 changes: 13 additions & 5 deletions src/modules/food/index.ts
Original file line number Diff line number Diff line change
@@ -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.
*
Expand Down Expand Up @@ -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)
Expand Down
83 changes: 53 additions & 30 deletions src/modules/internet/index.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -102,6 +103,50 @@ const ipv4Networks: Record<IPv4Network, string> = {
[IPv4Network.Multicast]: '224.0.0.0/4',
};

/**
* 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.
*
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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}`;
}
Expand Down
21 changes: 12 additions & 9 deletions src/modules/system/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
}
}
Expand Down
26 changes: 13 additions & 13 deletions test/modules/date.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down Expand Up @@ -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);
Expand Down
Loading

0 comments on commit bf4e3a3

Please sign in to comment.