diff options
| author | DivisionByZero <[email protected]> | 2024-01-18 17:14:48 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-01-18 17:14:48 +0100 |
| commit | 41d87789c7ff353acfd0f5ca88a99c0d1fd3b500 (patch) | |
| tree | 28d5a0a2e72881ed0202e2b2c86a4fb3b590e69d | |
| parent | d71bc47a4a7b127b41068016cbed3584a35b47ea (diff) | |
| download | faker-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.ts | 2 | ||||
| -rw-r--r-- | src/modules/location/index.ts | 8 | ||||
| -rw-r--r-- | src/modules/number/index.ts | 49 | ||||
| -rw-r--r-- | test/modules/__snapshots__/number.spec.ts.snap | 6 | ||||
| -rw-r--r-- | test/modules/datatype.spec.ts | 14 | ||||
| -rw-r--r-- | test/modules/number.spec.ts | 44 |
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( |
