Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(number): add parameter fractionDigits in float #1855

Merged
merged 30 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
d1de875
refactor(datatype): legacy float implementation
xDivisionByZerox Feb 17, 2023
cb35103
refactor(number): replace precision with fractionDigits
xDivisionByZerox Feb 17, 2023
c01a82d
fix(datatype): circular deps
xDivisionByZerox Feb 17, 2023
fabc190
docs(number): fix typo in JSDocs
xDivisionByZerox Feb 17, 2023
92ec99c
test(datatype): add legacy error testcase
xDivisionByZerox Feb 17, 2023
12503b3
test(datatype): fix expectations
xDivisionByZerox Feb 17, 2023
07fc370
refactor(number): remove default for fractionalDigits
xDivisionByZerox Feb 18, 2023
efa4846
Merge remote-tracking branch 'origin/next' into refactor/float/change…
xDivisionByZerox Nov 25, 2023
83c75bd
Merge remote-tracking branch 'origin/next' into refactor/float/change…
xDivisionByZerox Jan 4, 2024
f8aafec
test: remove duplicated test case
xDivisionByZerox Jan 5, 2024
7a1f5bc
test: add case with multipleOf in combination with fractionDigits
xDivisionByZerox Jan 5, 2024
ca20b1c
refactor: more linear code flow
xDivisionByZerox Jan 5, 2024
a387b3d
revert: color module uses number fractionDigits
xDivisionByZerox Jan 5, 2024
a8bcc8e
revert: changes to datatype module
xDivisionByZerox Jan 5, 2024
b566c45
test: readd removed min, max and precision option test case
xDivisionByZerox Jan 5, 2024
3c2a839
test: add accidental removed test case
xDivisionByZerox Jan 5, 2024
2b9a74e
revert: accidental changed test name
xDivisionByZerox Jan 5, 2024
9d394bb
docs: adjust throw tags wordings
xDivisionByZerox Jan 5, 2024
89ede36
docs: rephrasing regarding excluding options properties
xDivisionByZerox Jan 5, 2024
b2af5a8
docs: reword fractionDigits description
xDivisionByZerox Jan 5, 2024
23b222c
refactor: remove default from fractionDigits
xDivisionByZerox Jan 5, 2024
a8aed91
refactor: better input validation
xDivisionByZerox Jan 10, 2024
29de20a
refactor: make input validation more linear
xDivisionByZerox Jan 10, 2024
89e8b99
refactor: rephrase error messages
xDivisionByZerox Jan 11, 2024
8557952
chore: fix minor issues
ST-DDT Jan 14, 2024
ee23583
Merge branch 'next' into refactor/float/change-precision-to-fraction-…
ST-DDT Jan 14, 2024
fe99819
chore: use consistent nullish check
ST-DDT Jan 14, 2024
e1d13a5
chore: apply suggestions
ST-DDT Jan 18, 2024
35c8996
Merge branch 'next' into refactor/float/change-precision-to-fraction-…
ST-DDT Jan 18, 2024
0e9171c
Update test/modules/datatype.spec.ts
ST-DDT Jan 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 9 additions & 9 deletions src/modules/color/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ export class ColorModule {

color = Array.from({ length: 3 }, () => this.faker.number.int(255));
if (includeAlpha) {
color.push(this.faker.number.float({ precision: 0.01 }));
color.push(this.faker.number.float({ fractionDigits: 2 }));
cssFunction = 'rgba';
}

Expand Down Expand Up @@ -460,7 +460,7 @@ export class ColorModule {
}): string | number[];
cmyk(options?: { format?: ColorFormat }): string | number[] {
const color: string | number[] = Array.from({ length: 4 }, () =>
this.faker.number.float({ precision: 0.01 })
this.faker.number.float({ fractionDigits: 2 })
);
return toColorFormat(color, options?.format || 'decimal', 'cmyk');
}
Expand Down Expand Up @@ -570,7 +570,7 @@ export class ColorModule {
}): string | number[] {
const hsl: number[] = [this.faker.number.int(360)];
for (let i = 0; i < (options?.includeAlpha ? 3 : 2); i++) {
hsl.push(this.faker.number.float({ precision: 0.01 }));
hsl.push(this.faker.number.float({ fractionDigits: 2 }));
}

return toColorFormat(
Expand Down Expand Up @@ -676,7 +676,7 @@ export class ColorModule {
}): string | number[] {
const hsl: number[] = [this.faker.number.int(360)];
for (let i = 0; i < 2; i++) {
hsl.push(this.faker.number.float({ precision: 0.01 }));
hsl.push(this.faker.number.float({ fractionDigits: 2 }));
}

return toColorFormat(hsl, options?.format || 'decimal', 'hwb');
Expand Down Expand Up @@ -755,10 +755,10 @@ export class ColorModule {
format?: ColorFormat;
}): string | number[];
lab(options?: { format?: ColorFormat }): string | number[] {
const lab = [this.faker.number.float({ precision: 0.000001 })];
const lab = [this.faker.number.float({ fractionDigits: 6 })];
for (let i = 0; i < 2; i++) {
lab.push(
this.faker.number.float({ min: -100, max: 100, precision: 0.0001 })
this.faker.number.float({ min: -100, max: 100, fractionDigits: 4 })
);
}

Expand Down Expand Up @@ -850,9 +850,9 @@ export class ColorModule {
format?: ColorFormat;
}): string | number[];
lch(options?: { format?: ColorFormat }): string | number[] {
const lch = [this.faker.number.float({ precision: 0.000001 })];
const lch = [this.faker.number.float({ fractionDigits: 6 })];
for (let i = 0; i < 2; i++) {
lch.push(this.faker.number.float({ max: 230, precision: 0.1 }));
lch.push(this.faker.number.float({ max: 230, fractionDigits: 1 }));
}

return toColorFormat(lch, options?.format || 'decimal', 'lch');
Expand Down Expand Up @@ -960,7 +960,7 @@ export class ColorModule {
}

const color = Array.from({ length: 3 }, () =>
this.faker.number.float({ precision: 0.0001 })
this.faker.number.float({ fractionDigits: 4 })
);
return toColorFormat(
color,
Expand Down
64 changes: 62 additions & 2 deletions src/modules/datatype/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,56 @@
import type { Faker } from '../..';
import { FakerError } from '../../errors/faker-error';
import { deprecated } from '../../internal/deprecated';

/**
* The legcy implementation for datatype float.
*
* @param options An options object.
* @param options.min Lower bound for generated number. Defaults to `0`.
* @param options.max Upper bound for generated number. Defaults to `min + 99999`.
* @param options.faker A faker instance.
* @param options.precision Precision of the generated number. Defaults to `0.01`.
*
*/
function legacyFloatImplementation(options: {
xDivisionByZerox marked this conversation as resolved.
Show resolved Hide resolved
/**
* A faker instance.
*/
faker: Faker;
/**
* Lower bound for generated number.
*/
min: number;
/**
* Upper bound for generated number.
*/
max: number;
/**
* Precision of the generated number.
*/
precision: number;
}) {
const { max, min, precision, faker } = options;
if (max === min) {
return min;
}

if (max < min) {
throw new FakerError(`Max ${max} should be greater than min ${min}.`);
}

if (precision <= 0) {
throw new FakerError(`Precision should be greater than 0.`);
}

const factor = 1 / precision;
const int = faker.number.int({
min: min * factor,
max: max * factor,
});
return int / factor;
}

/**
* Module to generate various primitive values and data types.
*/
Expand Down Expand Up @@ -81,7 +131,12 @@ export class DatatypeModule {

const { min = 0, max = min + 99999, precision = 1 } = options;

return this.faker.number.float({ min, max, precision });
return legacyFloatImplementation({
faker: this.faker,
max,
min,
precision,
});
}

/**
Expand Down Expand Up @@ -145,7 +200,12 @@ export class DatatypeModule {

const { min = 0, max = min + 99999, precision = 0.01 } = options;

return this.faker.number.float({ min, max, precision });
return legacyFloatImplementation({
faker: this.faker,
max,
min,
precision,
});
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/modules/finance/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ export class FinanceModule {
const randValue = this.faker.number.float({
max,
min,
precision: 10 ** -dec,
fractionDigits: dec,
});

let formattedString: string;
Expand Down
2 changes: 1 addition & 1 deletion src/modules/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ export class HelpersModule {
const random = this.faker.number.float({
min: 0,
max: total,
precision: 1e-9,
fractionDigits: 9,
});
let current = 0;
for (const { weight, value } of array) {
Expand Down
8 changes: 4 additions & 4 deletions src/modules/location/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ export class LocationModule {

const { max = 90, min = legacyMin, precision = legacyPrecision } = options;

return this.faker.number.float({ min, max, precision: 10 ** -precision });
return this.faker.number.float({ min, max, fractionDigits: precision });
}

/**
Expand Down Expand Up @@ -629,7 +629,7 @@ export class LocationModule {

const { max = 180, min = legacyMin, precision = legacyPrecision } = options;

return this.faker.number.float({ max, min, precision: 10 ** -precision });
return this.faker.number.float({ max, min, fractionDigits: precision });
}

/**
Expand Down Expand Up @@ -873,15 +873,15 @@ export class LocationModule {

const angleRadians = this.faker.number.float({
max: 2 * Math.PI,
precision: 0.00001,
fractionDigits: 5,
}); // in ° radians

const radiusMetric = isMetric ? radius : radius * 1.60934; // in km
const errorCorrection = 0.995; // avoid float issues
const distanceInKm =
this.faker.number.float({
max: radiusMetric,
precision: 0.001,
fractionDigits: 3,
}) * errorCorrection; // in km

/**
Expand Down
43 changes: 20 additions & 23 deletions src/modules/number/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,18 @@ export class NumberModule {
* @param options Upper bound or options object. Defaults to `{}`.
* @param options.min Lower bound for generated number. Defaults to `0.0`.
* @param options.max Upper bound for generated number. Defaults to `1.0`.
* @param options.precision Precision of the generated number, for example `0.01` will round to 2 decimal points.
* @param options.fractionDigits The number of digits to appear after the decimal point. Defaults to `16`.
*
* @throws If options.max is smaller than options.min.
* @throws If options.fractionDigits is negative.
*
* @example
* faker.number.float() // 0.5688541042618454
* faker.number.float(3) // 2.367973240558058
* faker.number.float({ min: -1000000 }) //-780678.849672846
* faker.number.float({ max: 100 }) // 17.3687307164073
* faker.number.float({ precision: 0.1 }) // 0.9
* faker.number.float({ min: 10, max: 100, precision: 0.001 }) // 35.415
* faker.number.float({ fractionDigits: 1 }) // 0.9
* faker.number.float({ min: 10, max: 100, fractionDigits: 3 }) // 35.415
*
* @since 8.0.0
*/
Expand All @@ -122,11 +125,11 @@ export class NumberModule {
*/
max?: number;
/**
* Precision of the generated number.
* The number of digits to appear after the decimal point.
*
* @default 0.01
* @default 16
*/
precision?: number;
fractionDigits?: number;
} = {}
): number {
if (typeof options === 'number') {
Expand All @@ -135,7 +138,7 @@ export class NumberModule {
};
}

const { min = 0, max = 1, precision } = options;
const { min = 0, max = 1, fractionDigits = 16 } = options;
xDivisionByZerox marked this conversation as resolved.
Show resolved Hide resolved

if (max === min) {
return min;
Expand All @@ -145,23 +148,17 @@ export class NumberModule {
throw new FakerError(`Max ${max} should be greater than min ${min}.`);
}

if (precision !== undefined) {
if (precision <= 0) {
throw new FakerError(`Precision should be greater than 0.`);
}

const factor = 1 / precision;
const int = this.int({
min: min * factor,
max: max * factor,
});
return int / factor;
} else {
// @ts-expect-error: access private member field
const mersenne: Mersenne = this.faker._mersenne;
const real = mersenne.next();
return real * (max - min) + min;
if (fractionDigits < 0) {
throw new FakerError(
'The fractional digits count should be greater than 0.'
);
}

// @ts-expect-error: access private member field
const mersenne: Mersenne = this.faker._mersenne;
const real = mersenne.next() * (max - min) + min;

return parseFloat(real.toFixed(fractionDigits));
}

/**
Expand Down