Skip to content

Commit

Permalink
feat: datatype.number and number not parameter introduced for int
Browse files Browse the repository at this point in the history
… and `float` generators.
  • Loading branch information
amaster507 committed Dec 30, 2022
1 parent e296ff2 commit 458e0dd
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 17 deletions.
20 changes: 14 additions & 6 deletions src/modules/datatype/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ export class DatatypeModule {
* @param options Maximum value or 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.not A number that the generated number cannot be equal to. Defaults to `undefined`.
* @param options.precision Precision of the generated number. Defaults to `1`.
*
* @throws When options define `max < min`.
* @throws When options define `max === min === Math.round(not)`.
* @throws When tries too many times to generate a number not equal to `options.not`.
*
* @see faker.number.int() for the default precision of `1`
* @see faker.number.float() for a custom precision
Expand All @@ -42,7 +45,9 @@ export class DatatypeModule {
* @deprecated Use `faker.number.int()` or `faker.number.float()` instead.
*/
number(
options: number | { min?: number; max?: number; precision?: number } = 99999
options:
| number
| { min?: number; max?: number; not?: number; precision?: number } = 99999
): number {
deprecated({
deprecated: 'faker.datatype.number()',
Expand All @@ -55,9 +60,9 @@ export class DatatypeModule {
options = { max: options };
}

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

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

/**
Expand All @@ -66,6 +71,7 @@ export class DatatypeModule {
* @param options Precision or options object.
* @param options.min Lower bound for generated number. Defaults to `0`.
* @param options.max Upper bound for generated number. Defaults to `99999`.
* @param options.not A number that the generated number cannot be equal to. Defaults to `undefined`.
* @param options.precision Precision of the generated number. Defaults to `0.01`.
*
* @see faker.number.float()
Expand All @@ -83,7 +89,9 @@ export class DatatypeModule {
* @deprecated Use `faker.number.float()` instead.
*/
float(
options: number | { min?: number; max?: number; precision?: number } = {}
options:
| number
| { min?: number; max?: number; not?: number; precision?: number } = {}
): number {
deprecated({
deprecated: 'faker.datatype.float()',
Expand All @@ -98,9 +106,9 @@ export class DatatypeModule {
};
}

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

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

/**
Expand Down
71 changes: 61 additions & 10 deletions src/modules/number/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ export class NumberModule {
* @param options Maximum value or options object. Defaults to `{}`.
* @param options.min Lower bound for generated number. Defaults to `0`.
* @param options.max Upper bound for generated number. Defaults to `Number.MAX_SAFE_INTEGER`.
* @param options.not A number that the generated number cannot be equal to. Defaults to `undefined`.
*
* @throws When options define `max < min`.
* @throws When options define `max === min === rounded(not)`.
* @throws When tries too many times to generate a number not `options.not`.
*
* @see faker.string.numeric() If you would like to generate a `string` of digits with a given length (range).
*
Expand All @@ -37,16 +40,24 @@ export class NumberModule {
*
* @since 8.0.0
*/
int(options: number | { min?: number; max?: number } = {}): number {
int(
options: number | { min?: number; max?: number; not?: number } = {}
): number {
if (typeof options === 'number') {
options = { max: options };
}

const { min = 0, max = Number.MAX_SAFE_INTEGER } = options;
const { min = 0, max = Number.MAX_SAFE_INTEGER, not } = options;
const effectiveMin = Math.ceil(min);
const effectiveMax = Math.floor(max);
const effectiveNot = not === undefined ? undefined : Math.round(not);

if (effectiveMin === effectiveMax) {
if (effectiveMin === effectiveNot) {
throw new FakerError(
`No integer vlaue between ${min} and ${max} that is also not rounded to ${not}`
);
}
return effectiveMin;
}

Expand All @@ -63,7 +74,21 @@ export class NumberModule {
// @ts-expect-error: access private member field
this.faker._mersenne;

return mersenne.next({ min: effectiveMin, max: effectiveMax + 1 });
const tries = 100;
let i = 0;
let result: number = undefined;
do {
result = mersenne.next({ min: effectiveMin, max: effectiveMax + 1 });
i++;
} while (i < tries && result === effectiveNot);

if (result === effectiveNot) {
throw new FakerError(
`Tried ${tries} times to generate an integer not ${not} to no success.`
);
}

return result;
}

/**
Expand All @@ -72,8 +97,12 @@ 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.not A number that the generated number cannot be equal to. Defaults to `undefined`.
* @param options.precision Precision of the generated number. Defaults to `0.01`.
*
* @throws When options define `max === min === not`.
* @throws When tries too many times to generate a number not `options.not`.
*
* @example
* faker.number.float() // 0.89
* faker.number.float(3) // 1.14
Expand All @@ -85,17 +114,24 @@ export class NumberModule {
* @since 8.0.0
*/
float(
options: number | { min?: number; max?: number; precision?: number } = {}
options:
| number
| { min?: number; max?: number; not?: number; precision?: number } = {}
): number {
if (typeof options === 'number') {
options = {
max: options,
};
}

const { min = 0, max = 1, precision = 0.01 } = options;
const { min = 0, max = 1, not, precision = 0.01 } = options;

if (max === min) {
if (max === not) {
throw new FakerError(
`No float between ${min} and ${max} that is also not ${not}.`
);
}
return min;
}

Expand All @@ -104,12 +140,27 @@ export class NumberModule {
}

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

return int / factor;
const tries = 100;
let i = 0;
let result: number = undefined;

do {
i++;
const int = this.int({
min: min * factor,
max: max * factor,
});
result = int / factor;
} while (i < tries && result === not);

if (result === not) {
throw new FakerError(
`Tried ${tries} times to generate a float not ${not} to no success.`
);
}

return result;
}

/**
Expand Down
36 changes: 36 additions & 0 deletions test/__snapshots__/datatype.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ exports[`datatype > 42 > float > with min and max 1`] = `-0.43`;
exports[`datatype > 42 > float > with min, max and precision 1`] = `-0.4261`;
exports[`datatype > 42 > float > with min, max, and not 1`] = `-0.43`;
exports[`datatype > 42 > float > with min, max, not, and precision 1`] = `-0.4261`;
exports[`datatype > 42 > float > with not 1`] = `37453.64`;
exports[`datatype > 42 > hexadecimal > noArgs 1`] = `"0x8"`;
exports[`datatype > 42 > hexadecimal > with casing 1`] = `"0x8"`;
Expand Down Expand Up @@ -115,6 +121,12 @@ exports[`datatype > 42 > number > with min and max 1`] = `-1`;

exports[`datatype > 42 > number > with min, max and precision 1`] = `-0.43`;

exports[`datatype > 42 > number > with min, max, and not 1`] = `-1`;

exports[`datatype > 42 > number > with min, max, not, and precision 1`] = `-0.43`;

exports[`datatype > 42 > number > with not 1`] = `37454`;

exports[`datatype > 42 > string > noArgs 1`] = `"Cky2eiXX/J"`;

exports[`datatype > 42 > string > with length 1`] = `"Cky2eiXX/J/*&Kq@X.b]\\"&{dnx4!1}2Z=YQ!I#<QYF"`;
Expand Down Expand Up @@ -213,6 +225,12 @@ exports[`datatype > 1211 > float > with min and max 1`] = `61.07`;

exports[`datatype > 1211 > float > with min, max and precision 1`] = `61.0658`;

exports[`datatype > 1211 > float > with min, max, and not 1`] = `61.07`;

exports[`datatype > 1211 > float > with min, max, not, and precision 1`] = `61.0658`;

exports[`datatype > 1211 > float > with not 1`] = `92851.09`;

exports[`datatype > 1211 > hexadecimal > noArgs 1`] = `"0xE"`;

exports[`datatype > 1211 > hexadecimal > with casing 1`] = `"0xe"`;
Expand Down Expand Up @@ -245,6 +263,12 @@ exports[`datatype > 1211 > number > with min and max 1`] = `61`;

exports[`datatype > 1211 > number > with min, max and precision 1`] = `61.07`;

exports[`datatype > 1211 > number > with min, max, and not 1`] = `61`;

exports[`datatype > 1211 > number > with min, max, not, and precision 1`] = `61.07`;

exports[`datatype > 1211 > number > with not 1`] = `92852`;

exports[`datatype > 1211 > string > noArgs 1`] = `"wKti5-}$_/"`;

exports[`datatype > 1211 > string > with length 1`] = `"wKti5-}$_/\`4hHA0afl\\"h^]dnwI<q|p|5KWu3/CZ|J"`;
Expand Down Expand Up @@ -341,6 +365,12 @@ exports[`datatype > 1337 > float > with min and max 1`] = `-12.92`;
exports[`datatype > 1337 > float > with min, max and precision 1`] = `-12.9153`;
exports[`datatype > 1337 > float > with min, max, and not 1`] = `-12.92`;
exports[`datatype > 1337 > float > with min, max, not, and precision 1`] = `-12.9153`;
exports[`datatype > 1337 > float > with not 1`] = `26202.2`;
exports[`datatype > 1337 > hexadecimal > noArgs 1`] = `"0x5"`;
exports[`datatype > 1337 > hexadecimal > with casing 1`] = `"0x5"`;
Expand Down Expand Up @@ -373,6 +403,12 @@ exports[`datatype > 1337 > number > with min and max 1`] = `-13`;
exports[`datatype > 1337 > number > with min, max and precision 1`] = `-12.92`;
exports[`datatype > 1337 > number > with min, max, and not 1`] = `-13`;
exports[`datatype > 1337 > number > with min, max, not, and precision 1`] = `-12.92`;
exports[`datatype > 1337 > number > with not 1`] = `26202`;
exports[`datatype > 1337 > string > noArgs 1`] = `"9U/4:SK$>6"`;
exports[`datatype > 1337 > string > with length 1`] = `"9U/4:SK$>6QX9@{:e=+kD)[B,e|/Jqjjj!BLGDWQgC"`;
Expand Down
66 changes: 66 additions & 0 deletions test/__snapshots__/number.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,38 @@ exports[`number > 42 > float > with min and max 1`] = `-0.43`;

exports[`number > 42 > float > with min, max and precision 1`] = `-0.4261`;

exports[`number > 42 > float > with min, max, and not 1`] = `-0.43`;

exports[`number > 42 > float > with min, max, not, and precision 1`] = `-0.4261`;

exports[`number > 42 > float > with not 1`] = `0.37`;

exports[`number > 42 > float > with plain number 1`] = `1.5`;

exports[`number > 42 > hex > noArgs 1`] = `"5"`;

exports[`number > 42 > hex > with max 1`] = `"4"`;

exports[`number > 42 > hex > with min 1`] = `"5"`;

exports[`number > 42 > hex > with min and max 1`] = `"4"`;

exports[`number > 42 > hex > with not 1`] = `"5"`;

exports[`number > 42 > hex > with options 1`] = `"4"`;

exports[`number > 42 > hex > with value 1`] = `"0"`;

exports[`number > 42 > int > noArgs 1`] = `3373557438480384`;

exports[`number > 42 > int > with max 1`] = `4`;

exports[`number > 42 > int > with min 1`] = `3373557438480384`;

exports[`number > 42 > int > with min and max 1`] = `4`;

exports[`number > 42 > int > with not 1`] = `3373557438480384`;

exports[`number > 42 > int > with options 1`] = `4`;

exports[`number > 42 > int > with value 1`] = `0`;
Expand All @@ -58,16 +80,38 @@ exports[`number > 1211 > float > with min and max 1`] = `61.07`;

exports[`number > 1211 > float > with min, max and precision 1`] = `61.0658`;

exports[`number > 1211 > float > with min, max, and not 1`] = `61.07`;

exports[`number > 1211 > float > with min, max, not, and precision 1`] = `61.0658`;

exports[`number > 1211 > float > with not 1`] = `0.93`;

exports[`number > 1211 > float > with plain number 1`] = `3.72`;

exports[`number > 1211 > hex > noArgs 1`] = `"e"`;

exports[`number > 1211 > hex > with max 1`] = `"a"`;

exports[`number > 1211 > hex > with min 1`] = `"e"`;

exports[`number > 1211 > hex > with min and max 1`] = `"a"`;

exports[`number > 1211 > hex > with not 1`] = `"e"`;

exports[`number > 1211 > hex > with options 1`] = `"a"`;

exports[`number > 1211 > hex > with value 1`] = `"1"`;

exports[`number > 1211 > int > noArgs 1`] = `8363366036799488`;

exports[`number > 1211 > int > with max 1`] = `10`;

exports[`number > 1211 > int > with min 1`] = `8363366036799488`;

exports[`number > 1211 > int > with min and max 1`] = `10`;

exports[`number > 1211 > int > with not 1`] = `8363366036799488`;

exports[`number > 1211 > int > with options 1`] = `10`;

exports[`number > 1211 > int > with value 1`] = `1`;
Expand All @@ -94,16 +138,38 @@ exports[`number > 1337 > float > with min and max 1`] = `-12.92`;

exports[`number > 1337 > float > with min, max and precision 1`] = `-12.9153`;

exports[`number > 1337 > float > with min, max, and not 1`] = `-12.92`;

exports[`number > 1337 > float > with min, max, not, and precision 1`] = `-12.9153`;

exports[`number > 1337 > float > with not 1`] = `0.26`;

exports[`number > 1337 > float > with plain number 1`] = `1.05`;

exports[`number > 1337 > hex > noArgs 1`] = `"4"`;

exports[`number > 1337 > hex > with max 1`] = `"2"`;

exports[`number > 1337 > hex > with min 1`] = `"4"`;

exports[`number > 1337 > hex > with min and max 1`] = `"2"`;

exports[`number > 1337 > hex > with not 1`] = `"4"`;

exports[`number > 1337 > hex > with options 1`] = `"2"`;

exports[`number > 1337 > hex > with value 1`] = `"0"`;

exports[`number > 1337 > int > noArgs 1`] = `2360108468142080`;

exports[`number > 1337 > int > with max 1`] = `2`;

exports[`number > 1337 > int > with min 1`] = `2360108468142080`;

exports[`number > 1337 > int > with min and max 1`] = `2`;

exports[`number > 1337 > int > with not 1`] = `2360108468142080`;

exports[`number > 1337 > int > with options 1`] = `2`;

exports[`number > 1337 > int > with value 1`] = `0`;

0 comments on commit 458e0dd

Please sign in to comment.