aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDivisionByZero <[email protected]>2024-01-18 17:14:48 +0100
committerGitHub <[email protected]>2024-01-18 17:14:48 +0100
commit41d87789c7ff353acfd0f5ca88a99c0d1fd3b500 (patch)
tree28d5a0a2e72881ed0202e2b2c86a4fb3b590e69d
parentd71bc47a4a7b127b41068016cbed3584a35b47ea (diff)
downloadfaker-41d87789c7ff353acfd0f5ca88a99c0d1fd3b500.tar.xz
faker-41d87789c7ff353acfd0f5ca88a99c0d1fd3b500.zip
feat(number): add parameter `fractionDigits` in float (#1855)
Co-authored-by: ST-DDT <[email protected]>
-rw-r--r--src/modules/finance/index.ts2
-rw-r--r--src/modules/location/index.ts8
-rw-r--r--src/modules/number/index.ts49
-rw-r--r--test/modules/__snapshots__/number.spec.ts.snap6
-rw-r--r--test/modules/datatype.spec.ts14
-rw-r--r--test/modules/number.spec.ts44
6 files changed, 109 insertions, 14 deletions
diff --git a/src/modules/finance/index.ts b/src/modules/finance/index.ts
index 4caa77b0..219c2702 100644
--- a/src/modules/finance/index.ts
+++ b/src/modules/finance/index.ts
@@ -601,7 +601,7 @@ export class FinanceModule extends ModuleBase {
const randValue = this.faker.number.float({
max,
min,
- multipleOf: 10 ** -dec,
+ fractionDigits: dec,
});
const formattedString = autoFormat
diff --git a/src/modules/location/index.ts b/src/modules/location/index.ts
index b06af49e..608e65a6 100644
--- a/src/modules/location/index.ts
+++ b/src/modules/location/index.ts
@@ -579,7 +579,7 @@ export class LocationModule extends ModuleBase {
const { max = 90, min = legacyMin, precision = legacyPrecision } = options;
- return this.faker.number.float({ min, max, multipleOf: 10 ** -precision });
+ return this.faker.number.float({ min, max, fractionDigits: precision });
}
/**
@@ -732,7 +732,7 @@ export class LocationModule extends ModuleBase {
const { max = 180, min = legacyMin, precision = legacyPrecision } = options;
- return this.faker.number.float({ max, min, multipleOf: 10 ** -precision });
+ return this.faker.number.float({ max, min, fractionDigits: precision });
}
/**
@@ -1207,7 +1207,7 @@ export class LocationModule extends ModuleBase {
const angleRadians = this.faker.number.float({
max: 2 * Math.PI,
- multipleOf: 0.00001,
+ fractionDigits: 5,
}); // in ° radians
const radiusMetric = isMetric ? radius : radius * 1.60934; // in km
@@ -1215,7 +1215,7 @@ export class LocationModule extends ModuleBase {
const distanceInKm =
this.faker.number.float({
max: radiusMetric,
- multipleOf: 0.001,
+ fractionDigits: 3,
}) * errorCorrection; // in km
/**
diff --git a/src/modules/number/index.ts b/src/modules/number/index.ts
index 2d1af9cc..cb329382 100644
--- a/src/modules/number/index.ts
+++ b/src/modules/number/index.ts
@@ -97,10 +97,16 @@ export class NumberModule extends SimpleModuleBase {
* @param options.multipleOf The generated number will be a multiple of this property.
* This property can be used to limit the result to a specific number of decimal digits.
* For example `0.01` will round to 2 decimal points.
- * If multipleOf is passed, the upper bound is inclusive.
+ * If `multipleOf` is passed, the upper bound is inclusive.
+ * This option is incompatible with the `fractionDigits` option.
+ * @param options.fractionDigits The maximum number of digits to appear after the decimal point.
+ * This option is incompatible with the `multipleOf` option.
*
* @throws When `min` is greater than `max`.
* @throws When `precision` is negative.
+ * @throws When `multipleOf` is negative.
+ * @throws When `fractionDigits` is negative.
+ * @throws When `fractionDigits` and `multipleOf` is passed in the same options object.
*
* @example
* faker.number.float() // 0.5688541042618454
@@ -108,7 +114,9 @@ export class NumberModule extends SimpleModuleBase {
* faker.number.float({ min: -1000000 }) //-780678.849672846
* faker.number.float({ max: 100 }) // 17.3687307164073
* faker.number.float({ multipleOf: 0.25 }) // 3.75
- * faker.number.float({ min: 10, max: 100, multipleOf: 0.001 }) // 35.415
+ * faker.number.float({ fractionDigits: 1 }) // 0.9
+ * faker.number.float({ min: 10, max: 100, multipleOf: 0.02 }) // 35.42
+ * faker.number.float({ min: 10, max: 100, fractionDigits: 3 }) // 65.716
*
* @since 8.0.0
*/
@@ -129,6 +137,10 @@ export class NumberModule extends SimpleModuleBase {
*/
max?: number;
/**
+ * The number of digits to appear after the decimal point.
+ */
+ fractionDigits?: number;
+ /*
* Precision of the generated number.
*
* @deprecated Use `multipleOf` instead.
@@ -147,10 +159,17 @@ export class NumberModule extends SimpleModuleBase {
};
}
- // eslint-disable-next-line deprecation/deprecation
- const { min = 0, max = 1, precision, multipleOf = precision } = options;
+ const {
+ min = 0,
+ max = 1,
+ fractionDigits,
+ precision,
+ multipleOf: originalMultipleOf = precision,
+ multipleOf = precision ??
+ (fractionDigits == null ? undefined : 10 ** -fractionDigits),
+ } = options;
- if (precision !== undefined) {
+ if (precision != null) {
deprecated({
deprecated: 'faker.number.float({ precision })',
proposed: 'faker.number.float({ multipleOf })',
@@ -167,7 +186,25 @@ export class NumberModule extends SimpleModuleBase {
throw new FakerError(`Max ${max} should be greater than min ${min}.`);
}
- if (multipleOf !== undefined) {
+ if (fractionDigits != null) {
+ if (originalMultipleOf != null) {
+ throw new FakerError(
+ 'multipleOf and fractionDigits cannot be set at the same time.'
+ );
+ }
+
+ if (!Number.isInteger(fractionDigits)) {
+ throw new FakerError('fractionDigits should be an integer.');
+ }
+
+ if (fractionDigits < 0) {
+ throw new FakerError(
+ 'fractionDigits should be greater than or equal to 0.'
+ );
+ }
+ }
+
+ if (multipleOf != null) {
if (multipleOf <= 0) {
// TODO @xDivisionByZerox: Clean up in v9.0
throw new FakerError(`multipleOf/precision should be greater than 0.`);
diff --git a/test/modules/__snapshots__/number.spec.ts.snap b/test/modules/__snapshots__/number.spec.ts.snap
index c04b4fe5..fc528fd9 100644
--- a/test/modules/__snapshots__/number.spec.ts.snap
+++ b/test/modules/__snapshots__/number.spec.ts.snap
@@ -26,6 +26,8 @@ exports[`number > 42 > float > with min 1`] = `-25.894775084685534`;
exports[`number > 42 > float > with min and max 1`] = `-0.4260473116301`;
+exports[`number > 42 > float > with min, max and fractionDigits 1`] = `-0.4261`;
+
exports[`number > 42 > float > with min, max and multipleOf 1`] = `-0.4261`;
exports[`number > 42 > float > with min, max and precision 1`] = `-0.4261`;
@@ -76,6 +78,8 @@ exports[`number > 1211 > float > with min 1`] = `-2.073633389081806`;
exports[`number > 1211 > float > with min and max 1`] = `61.06573706539348`;
+exports[`number > 1211 > float > with min, max and fractionDigits 1`] = `61.0658`;
+
exports[`number > 1211 > float > with min, max and multipleOf 1`] = `61.0658`;
exports[`number > 1211 > float > with min, max and precision 1`] = `61.0658`;
@@ -126,6 +130,8 @@ exports[`number > 1337 > float > with min 1`] = `-30.732938923640177`;
exports[`number > 1337 > float > with min and max 1`] = `-12.915260942419991`;
+exports[`number > 1337 > float > with min, max and fractionDigits 1`] = `-12.9153`;
+
exports[`number > 1337 > float > with min, max and multipleOf 1`] = `-12.9153`;
exports[`number > 1337 > float > with min, max and precision 1`] = `-12.9153`;
diff --git a/test/modules/datatype.spec.ts b/test/modules/datatype.spec.ts
index 75f2897c..7a75ce58 100644
--- a/test/modules/datatype.spec.ts
+++ b/test/modules/datatype.spec.ts
@@ -320,15 +320,23 @@ describe('datatype', () => {
const max = 9;
expect(() => {
- faker.datatype.number({ min, max });
+ faker.datatype.float({ min, max });
}).toThrow(
new FakerError(`Max ${max} should be greater than min ${min}.`)
);
});
- it('should throw when precision is negative', () => {
+ it('should throw when precision <= 0', () => {
+ const min = 1;
+ const max = 2;
+
+ expect(() => {
+ faker.datatype.float({ min, max, precision: 0 });
+ }).toThrow(
+ new FakerError('multipleOf/precision should be greater than 0.')
+ );
expect(() => {
- faker.datatype.float({ precision: -0.01 });
+ faker.datatype.float({ min, max, precision: -1 });
}).toThrow(
new FakerError('multipleOf/precision should be greater than 0.')
);
diff --git a/test/modules/number.spec.ts b/test/modules/number.spec.ts
index c61498fa..922819c0 100644
--- a/test/modules/number.spec.ts
+++ b/test/modules/number.spec.ts
@@ -28,6 +28,11 @@ describe('number', () => {
max: 69,
precision: 0.0001,
})
+ .it('with min, max and fractionDigits', {
+ min: -42,
+ max: 69,
+ fractionDigits: 4,
+ })
.it('with min, max and multipleOf', {
min: -42,
max: 69,
@@ -281,6 +286,45 @@ describe('number', () => {
expect(results).toEqual([0, 0.4, 0.8, 1.2, 1.6]);
});
+ it.each(times(100))(
+ 'provides numbers with an exact fractional digits',
+ () => {
+ const actual = faker.number.float({
+ min: 0.5,
+ max: 0.99,
+ fractionDigits: 2,
+ });
+ expect(actual).toBe(Number(actual.toFixed(2)));
+ }
+ );
+
+ it('throws an error if fractionDigits and multipleOf is provided at the same time', () => {
+ expect(() =>
+ faker.number.float({
+ min: 0,
+ max: 10,
+ multipleOf: 0.25,
+ fractionDigits: 6,
+ })
+ ).toThrow(
+ new FakerError(
+ 'multipleOf and fractionDigits cannot be set at the same time.'
+ )
+ );
+ });
+
+ it('throws an error for non integer fractionDigits numbers', () => {
+ expect(() => faker.number.float({ fractionDigits: 1.337 })).toThrow(
+ new FakerError('fractionDigits should be an integer.')
+ );
+ });
+
+ it('throws an error for negative fractionDigits', () => {
+ expect(() => faker.number.float({ fractionDigits: -2 })).toThrow(
+ new FakerError('fractionDigits should be greater than or equal to 0.')
+ );
+ });
+
it('provides numbers with a given precision of 0.2', () => {
const results = [
...new Set(