aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeyla Jähnig <[email protected]>2022-11-25 16:59:10 +0100
committerGitHub <[email protected]>2022-11-25 16:59:10 +0100
commit7d4d99f00bf1e29c14346bd6a9fab33c8e7d5743 (patch)
tree323754ca575c56ccf688539cfcca66d54c903602
parent0af0fff4a410d7531368c709327ba0798a47091a (diff)
downloadfaker-7d4d99f00bf1e29c14346bd6a9fab33c8e7d5743.tar.xz
faker-7d4d99f00bf1e29c14346bd6a9fab33c8e7d5743.zip
feat(number): move methods to new module (#1122)
Co-authored-by: ST-DDT <[email protected]> Co-authored-by: Eric Cheng <[email protected]> Co-authored-by: Leyla Jähnig <[email protected]> Co-authored-by: Shinigami92 <[email protected]>
-rw-r--r--README.md4
-rw-r--r--docs/.vitepress/api-pages.ts1
-rw-r--r--src/faker.ts18
-rw-r--r--src/index.ts1
-rw-r--r--src/modules/color/index.ts34
-rw-r--r--src/modules/commerce/index.ts10
-rw-r--r--src/modules/datatype/index.ts111
-rw-r--r--src/modules/date/index.ts12
-rw-r--r--src/modules/finance/index.ts20
-rw-r--r--src/modules/git/index.ts2
-rw-r--r--src/modules/helpers/index.ts26
-rw-r--r--src/modules/image/index.ts2
-rw-r--r--src/modules/image/providers/lorempixel.ts2
-rw-r--r--src/modules/internet/index.ts18
-rw-r--r--src/modules/internet/user-agent.ts66
-rw-r--r--src/modules/location/index.ts20
-rw-r--r--src/modules/number/index.ts197
-rw-r--r--src/modules/random/index.ts2
-rw-r--r--src/modules/string/index.ts6
-rw-r--r--src/modules/system/index.ts47
-rw-r--r--src/modules/vehicle/index.ts12
-rw-r--r--test/__snapshots__/number.spec.ts.snap109
-rw-r--r--test/datatype.spec.ts38
-rw-r--r--test/faker.spec.ts6
-rw-r--r--test/finance.spec.ts2
-rw-r--r--test/helpers.spec.ts10
-rw-r--r--test/number.spec.ts354
-rw-r--r--test/string.spec.ts6
28 files changed, 861 insertions, 275 deletions
diff --git a/README.md b/README.md
index 2bf22eb4..d21fc5f5 100644
--- a/README.md
+++ b/README.md
@@ -132,12 +132,12 @@ If you want consistent results, you can set your own seed:
```ts
faker.seed(123);
-const firstRandom = faker.datatype.number();
+const firstRandom = faker.number.int();
// Setting the seed again resets the sequence.
faker.seed(123);
-const secondRandom = faker.datatype.number();
+const secondRandom = faker.number.int();
console.log(firstRandom === secondRandom);
```
diff --git a/docs/.vitepress/api-pages.ts b/docs/.vitepress/api-pages.ts
index 69bb4964..188e24d3 100644
--- a/docs/.vitepress/api-pages.ts
+++ b/docs/.vitepress/api-pages.ts
@@ -18,6 +18,7 @@ export const apiPages = [
{ text: 'Location', link: '/api/location.html' },
{ text: 'Lorem', link: '/api/lorem.html' },
{ text: 'Music', link: '/api/music.html' },
+ { text: 'Number', link: '/api/number.html' },
{ text: 'Person', link: '/api/person.html' },
{ text: 'Phone', link: '/api/phone.html' },
{ text: 'Random', link: '/api/random.html' },
diff --git a/src/faker.ts b/src/faker.ts
index fd7ed522..7870d9c5 100644
--- a/src/faker.ts
+++ b/src/faker.ts
@@ -21,6 +21,7 @@ import type { LocationModule as AddressModule } from './modules/location';
import { LocationModule } from './modules/location';
import { LoremModule } from './modules/lorem';
import { MusicModule } from './modules/music';
+import { NumberModule } from './modules/number';
import type { PersonModule as NameModule } from './modules/person';
import { PersonModule } from './modules/person';
import { PhoneModule } from './modules/phone';
@@ -103,6 +104,7 @@ export class Faker {
readonly lorem: LoremModule = new LoremModule(this);
readonly music: MusicModule = new MusicModule(this);
readonly person: PersonModule = new PersonModule(this);
+ readonly number: NumberModule = new NumberModule(this);
readonly phone: PhoneModule = new PhoneModule(this);
readonly science: ScienceModule = new ScienceModule(this);
readonly string: StringModule = new StringModule(this);
@@ -239,12 +241,12 @@ export class Faker {
* @example
* // Consistent values for tests:
* faker.seed(42)
- * faker.datatype.number(10); // 4
- * faker.datatype.number(10); // 8
+ * faker.number.int(10); // 4
+ * faker.number.int(10); // 8
*
* faker.seed(42)
- * faker.datatype.number(10); // 4
- * faker.datatype.number(10); // 8
+ * faker.number.int(10); // 4
+ * faker.number.int(10); // 8
*
* @example
* // Random but reproducible tests:
@@ -271,12 +273,12 @@ export class Faker {
* @example
* // Consistent values for tests:
* faker.seed([42, 13, 17])
- * faker.datatype.number(10); // 4
- * faker.datatype.number(10); // 8
+ * faker.number.int(10); // 4
+ * faker.number.int(10); // 8
*
* faker.seed([42, 13, 17])
- * faker.datatype.number(10); // 4
- * faker.datatype.number(10); // 8
+ * faker.number.int(10); // 4
+ * faker.number.int(10); // 8
*
* @example
* // Random but reproducible tests:
diff --git a/src/index.ts b/src/index.ts
index 9589c257..5d5c280c 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -63,6 +63,7 @@ export type {
} from './modules/location';
export type { LoremModule } from './modules/lorem';
export type { MusicModule } from './modules/music';
+export type { NumberModule } from './modules/number';
export { Sex } from './modules/person';
export type {
/** @deprecated Use PersonModule instead */
diff --git a/src/modules/color/index.ts b/src/modules/color/index.ts
index 4fd79a06..b232f649 100644
--- a/src/modules/color/index.ts
+++ b/src/modules/color/index.ts
@@ -320,13 +320,9 @@ export class ColorModule {
color = formatHexColor(color, options);
return color;
}
- color = Array.from({ length: 3 }).map(() =>
- this.faker.datatype.number({ min: 0, max: 255 })
- );
+ color = Array.from({ length: 3 }).map(() => this.faker.number.int(255));
if (includeAlpha) {
- color.push(
- this.faker.datatype.float({ min: 0, max: 1, precision: 0.01 })
- );
+ color.push(this.faker.number.float({ max: 1, precision: 0.01 }));
cssFunction = 'rgba';
}
return toColorFormat(color, format, cssFunction);
@@ -385,7 +381,7 @@ export class ColorModule {
cmyk(options?: { format?: ColorFormat }): string | number[];
cmyk(options?: { format?: ColorFormat }): string | number[] {
const color: string | number[] = Array.from({ length: 4 }).map(() =>
- this.faker.datatype.float({ min: 0, max: 1, precision: 0.01 })
+ this.faker.number.float({ max: 1, precision: 0.01 })
);
return toColorFormat(color, options?.format || 'decimal', 'cmyk');
}
@@ -460,9 +456,9 @@ export class ColorModule {
format?: ColorFormat;
includeAlpha?: boolean;
}): string | number[] {
- const hsl: number[] = [this.faker.datatype.number({ min: 0, max: 360 })];
+ const hsl: number[] = [this.faker.number.int(360)];
for (let i = 0; i < (options?.includeAlpha ? 3 : 2); i++) {
- hsl.push(this.faker.datatype.float({ min: 0, max: 1, precision: 0.01 }));
+ hsl.push(this.faker.number.float({ max: 1, precision: 0.01 }));
}
return toColorFormat(
hsl,
@@ -537,9 +533,9 @@ export class ColorModule {
* @since 7.0.0
*/
hwb(options?: { format?: ColorFormat }): string | number[] {
- const hsl: number[] = [this.faker.datatype.number({ min: 0, max: 360 })];
+ const hsl: number[] = [this.faker.number.int(360)];
for (let i = 0; i < 2; i++) {
- hsl.push(this.faker.datatype.float({ min: 0, max: 1, precision: 0.01 }));
+ hsl.push(this.faker.number.float({ max: 1, precision: 0.01 }));
}
return toColorFormat(hsl, options?.format || 'decimal', 'hwb');
}
@@ -596,12 +592,10 @@ export class ColorModule {
*/
lab(options?: { format?: ColorFormat }): string | number[];
lab(options?: { format?: ColorFormat }): string | number[] {
- const lab = [
- this.faker.datatype.float({ min: 0, max: 1, precision: 0.000001 }),
- ];
+ const lab = [this.faker.number.float({ max: 1, precision: 0.000001 })];
for (let i = 0; i < 2; i++) {
lab.push(
- this.faker.datatype.float({ min: -100, max: 100, precision: 0.0001 })
+ this.faker.number.float({ min: -100, max: 100, precision: 0.0001 })
);
}
return toColorFormat(lab, options?.format || 'decimal', 'lab');
@@ -671,13 +665,9 @@ export class ColorModule {
*/
lch(options?: { format?: ColorFormat }): string | number[];
lch(options?: { format?: ColorFormat }): string | number[] {
- const lch = [
- this.faker.datatype.float({ min: 0, max: 1, precision: 0.000001 }),
- ];
+ const lch = [this.faker.number.float({ max: 1, precision: 0.000001 })];
for (let i = 0; i < 2; i++) {
- lch.push(
- this.faker.datatype.number({ min: 0, max: 230, precision: 0.1 })
- );
+ lch.push(this.faker.number.float({ max: 230, precision: 0.1 }));
}
return toColorFormat(lch, options?.format || 'decimal', 'lch');
}
@@ -753,7 +743,7 @@ export class ColorModule {
options = { ...options, space: 'sRGB' };
}
const color = Array.from({ length: 3 }).map(() =>
- this.faker.datatype.float({ min: 0, max: 1, precision: 0.0001 })
+ this.faker.number.float({ max: 1, precision: 0.0001 })
);
return toColorFormat(
color,
diff --git a/src/modules/commerce/index.ts b/src/modules/commerce/index.ts
index 088112c1..99515463 100644
--- a/src/modules/commerce/index.ts
+++ b/src/modules/commerce/index.ts
@@ -67,14 +67,10 @@ export class CommerceModule {
return `${symbol}${0.0}`;
}
- const randValue = this.faker.datatype.number({ max: max, min: min });
+ // TODO @Shinigami92 2022-11-24: https://github.com/faker-js/faker/issues/350
+ const randValue = this.faker.number.int({ min, max });
- return (
- symbol +
- (Math.round(randValue * Math.pow(10, dec)) / Math.pow(10, dec)).toFixed(
- dec
- )
- );
+ return symbol + randValue.toFixed(dec);
}
/**
diff --git a/src/modules/datatype/index.ts b/src/modules/datatype/index.ts
index b40f2f43..22ee1bfe 100644
--- a/src/modules/datatype/index.ts
+++ b/src/modules/datatype/index.ts
@@ -1,7 +1,5 @@
import type { Faker } from '../..';
-import { FakerError } from '../../errors/faker-error';
import { deprecated } from '../../internal/deprecated';
-import type { Mersenne } from '../../internal/mersenne/mersenne';
/**
* Module to generate various primitive values and data types.
@@ -37,36 +35,26 @@ export class DatatypeModule {
* faker.datatype.number({ min: 10, max: 100, precision: 0.01 }) // 36.94
*
* @since 5.5.0
+ *
+ * @deprecated Use `faker.number.int()` instead.
*/
number(
options: number | { min?: number; max?: number; precision?: number } = 99999
): number {
+ deprecated({
+ deprecated: 'faker.datatype.number()',
+ proposed: 'faker.number.int()',
+ since: '8.0',
+ until: '9.0',
+ });
+
if (typeof options === 'number') {
options = { max: options };
}
- const { min = 0, precision = 1 } = options;
- const max = options.max ?? min + 99999;
-
- if (max === min) {
- return min;
- }
-
- if (max < min) {
- throw new FakerError(`Max ${max} should be greater than min ${min}.`);
- }
+ const { min = 0, max = min + 99999, precision = 1 } = options;
- const mersenne: Mersenne =
- // @ts-expect-error: access private member field
- this.faker._mersenne;
-
- const randomNumber = mersenne.next({
- min: min / precision,
- max: max / precision + 1,
- });
-
- // Workaround problem in float point arithmetics for e.g. 6681493 / 0.01
- return randomNumber / (1 / precision);
+ return this.faker.number.float({ min, max, precision });
}
/**
@@ -86,24 +74,19 @@ export class DatatypeModule {
* faker.datatype.float({ min: 10, max: 100, precision: 0.001 }) // 57.315
*
* @since 5.5.0
+ *
+ * @deprecated Use `faker.number.float()` instead.
*/
float(
options?: number | { min?: number; max?: number; precision?: number }
): number {
- if (typeof options === 'number') {
- options = {
- precision: options,
- };
- }
- options = options || {};
- const opts: { precision?: number } = {};
- for (const p in options) {
- opts[p] = options[p];
- }
- if (opts.precision == null) {
- opts.precision = 0.01;
- }
- return this.number(opts);
+ deprecated({
+ deprecated: 'faker.datatype.float()',
+ proposed: 'faker.number.float()',
+ since: '8.0',
+ until: '9.0',
+ });
+ return this.faker.number.float(options);
}
/**
@@ -139,7 +122,7 @@ export class DatatypeModule {
max = Date.UTC(2100, 0);
}
- return new Date(this.number({ min, max }));
+ return new Date(this.faker.number.int({ min, max }));
}
/**
@@ -177,7 +160,7 @@ export class DatatypeModule {
*
* @since 5.5.0
*
- * @deprecated Use faker.string.uuid() instead.
+ * @deprecated Use `faker.string.uuid()` instead.
*/
uuid(): string {
deprecated({
@@ -222,7 +205,7 @@ export class DatatypeModule {
// This check is required to avoid returning false when float() returns 1
return true;
}
- return this.float({ min: 0, max: 1 }) < probability;
+ return this.faker.number.float({ max: 1 }) < probability;
}
/**
@@ -247,7 +230,7 @@ export class DatatypeModule {
*
* @since 6.1.2
*
- * @deprecated Use `faker.string.hexadecimal()` instead.
+ * @deprecated Use `faker.string.hexadecimal()` or `faker.number.hex()` instead.
*/
hexadecimal(
options: {
@@ -258,7 +241,7 @@ export class DatatypeModule {
): string {
deprecated({
deprecated: 'faker.datatype.hexadecimal()',
- proposed: 'faker.string.hexadecimal()',
+ proposed: 'faker.string.hexadecimal() or faker.number.hex()',
since: '8.0',
until: '9.0',
});
@@ -280,7 +263,7 @@ export class DatatypeModule {
properties.forEach((prop) => {
returnObject[prop] = this.boolean()
? this.faker.string.sample()
- : this.number();
+ : this.faker.number.int();
});
return JSON.stringify(returnObject);
@@ -299,7 +282,7 @@ export class DatatypeModule {
*/
array(length = 10): Array<string | number> {
return Array.from<string | number>({ length }).map(() =>
- this.boolean() ? this.faker.string.sample() : this.number()
+ this.boolean() ? this.faker.string.sample() : this.faker.number.int()
);
}
@@ -320,6 +303,8 @@ export class DatatypeModule {
* faker.datatype.bigInt({ min: 10n, max: 100n }) // 36n
*
* @since 6.0.0
+ *
+ * @deprecated Use `faker.number.bigInt()` instead.
*/
bigInt(
options?:
@@ -332,36 +317,12 @@ export class DatatypeModule {
max?: bigint | boolean | number | string;
}
): bigint {
- let min: bigint;
- let max: bigint;
-
- if (typeof options === 'object') {
- min = BigInt(options.min ?? 0);
- max = BigInt(options.max ?? min + BigInt(999999999999999));
- } else {
- min = BigInt(0);
- max = BigInt(options ?? 999999999999999);
- }
-
- if (max === min) {
- return min;
- }
-
- if (max < min) {
- throw new FakerError(`Max ${max} should be larger then min ${min}.`);
- }
-
- const delta = max - min;
-
- const offset =
- BigInt(
- this.faker.string.numeric({
- length: delta.toString(10).length,
- allowLeadingZeros: true,
- })
- ) %
- (delta + BigInt(1));
-
- return min + offset;
+ deprecated({
+ deprecated: 'faker.datatype.bigInt()',
+ proposed: 'faker.number.bigInt()',
+ since: '8.0',
+ until: '9.0',
+ });
+ return this.faker.number.bigInt(options);
}
}
diff --git a/src/modules/date/index.ts b/src/modules/date/index.ts
index d5470dab..673f0e33 100644
--- a/src/modules/date/index.ts
+++ b/src/modules/date/index.ts
@@ -58,7 +58,7 @@ export class DateModule {
};
let past = date.getTime();
- past -= this.faker.datatype.number(range); // some time from now to N years ago, in milliseconds
+ past -= this.faker.number.int(range); // some time from now to N years ago, in milliseconds
date.setTime(past);
return date;
@@ -91,7 +91,7 @@ export class DateModule {
};
let future = date.getTime();
- future += this.faker.datatype.number(range); // some time from now to N years later, in milliseconds
+ future += this.faker.number.int(range); // some time from now to N years later, in milliseconds
date.setTime(future);
return date;
@@ -111,7 +111,7 @@ export class DateModule {
between(from: string | Date | number, to: string | Date | number): Date {
const fromMs = toDate(from).getTime();
const toMs = toDate(to).getTime();
- const dateOffset = this.faker.datatype.number(toMs - fromMs);
+ const dateOffset = this.faker.number.int(toMs - fromMs);
return new Date(fromMs + dateOffset);
}
@@ -176,7 +176,7 @@ export class DateModule {
};
let future = date.getTime();
- future -= this.faker.datatype.number(range); // some time from now to N days ago, in milliseconds
+ future -= this.faker.number.int(range); // some time from now to N days ago, in milliseconds
date.setTime(future);
return date;
@@ -209,7 +209,7 @@ export class DateModule {
};
let future = date.getTime();
- future += this.faker.datatype.number(range); // some time from now to N days later, in milliseconds
+ future += this.faker.number.int(range); // some time from now to N days later, in milliseconds
date.setTime(future);
return date;
@@ -343,6 +343,6 @@ export class DateModule {
throw new FakerError(`Max ${max} should be larger then min ${min}.`);
}
- return new Date(this.faker.datatype.number({ min, max }));
+ return new Date(this.faker.number.int({ min, max }));
}
}
diff --git a/src/modules/finance/index.ts b/src/modules/finance/index.ts
index e739d920..e6533e50 100644
--- a/src/modules/finance/index.ts
+++ b/src/modules/finance/index.ts
@@ -143,10 +143,10 @@ export class FinanceModule {
symbol: string = '',
autoFormat?: boolean
): string {
- const randValue = this.faker.datatype.number({
+ const randValue = this.faker.number.float({
max,
min,
- precision: Math.pow(10, -dec),
+ precision: 10 ** -dec,
});
let formattedString: string;
@@ -231,7 +231,7 @@ export class FinanceModule {
* @since 3.1.0
*/
bitcoinAddress(): string {
- const addressLength = this.faker.datatype.number({ min: 25, max: 39 });
+ const addressLength = this.faker.number.int({ min: 25, max: 39 });
let address = this.faker.helpers.arrayElement(['1', '3']);
@@ -253,7 +253,7 @@ export class FinanceModule {
* @since 5.0.0
*/
litecoinAddress(): string {
- const addressLength = this.faker.datatype.number({ min: 26, max: 33 });
+ const addressLength = this.faker.number.int({ min: 26, max: 33 });
let address = this.faker.helpers.arrayElement(['L', 'M', '3']);
@@ -305,11 +305,7 @@ export class FinanceModule {
* @since 5.0.0
*/
creditCardCVV(): string {
- let cvv = '';
- for (let i = 0; i < 3; i++) {
- cvv += this.faker.datatype.number({ max: 9 }).toString();
- }
- return cvv;
+ return this.faker.string.numeric({ length: 3, allowLeadingZeros: true });
}
/**
@@ -342,7 +338,7 @@ export class FinanceModule {
if (length < 1) {
throw new FakerError('minimum length is 1');
}
- return Array.from({ length }, () => this.faker.datatype.number(9)).join('');
+ return this.faker.string.numeric({ length, allowLeadingZeros: true });
}
/**
@@ -394,7 +390,7 @@ export class FinanceModule {
s += this.faker.helpers.arrayElement(iban.alpha);
} else if (bban.type === 'c') {
if (this.faker.datatype.boolean(0.8)) {
- s += this.faker.datatype.number(9);
+ s += this.faker.number.int(9);
} else {
s += this.faker.helpers.arrayElement(iban.alpha);
}
@@ -408,7 +404,7 @@ export class FinanceModule {
c--;
}
} else {
- s += this.faker.datatype.number(9);
+ s += this.faker.number.int(9);
}
}
c--;
diff --git a/src/modules/git/index.ts b/src/modules/git/index.ts
index 336da820..2ea65063 100644
--- a/src/modules/git/index.ts
+++ b/src/modules/git/index.ts
@@ -145,7 +145,7 @@ export class GitModule {
// Timezone offset
dateParts.push(
GIT_TIMEZONE_FORMAT.format(
- this.faker.datatype.number({ min: -11, max: 12 }) * 100
+ this.faker.number.int({ min: -11, max: 12 }) * 100
)
);
diff --git a/src/modules/helpers/index.ts b/src/modules/helpers/index.ts
index 406f7f19..6caa8eff 100644
--- a/src/modules/helpers/index.ts
+++ b/src/modules/helpers/index.ts
@@ -56,9 +56,9 @@ export class HelpersModule {
let str = '';
for (let i = 0; i < string.length; i++) {
if (string.charAt(i) === symbol) {
- str += this.faker.datatype.number(9);
+ str += this.faker.number.int(9);
} else if (string.charAt(i) === '!') {
- str += this.faker.datatype.number({ min: 2, max: 9 });
+ str += this.faker.number.int({ min: 2, max: 9 });
} else {
str += string.charAt(i);
}
@@ -117,13 +117,13 @@ export class HelpersModule {
for (let i = 0; i < string.length; i++) {
if (string.charAt(i) === '#') {
- str += this.faker.datatype.number(9);
+ str += this.faker.number.int(9);
} else if (string.charAt(i) === '?') {
str += this.arrayElement(alpha);
} else if (string.charAt(i) === '*') {
str += this.faker.datatype.boolean()
? this.arrayElement(alpha)
- : this.faker.datatype.number(9);
+ : this.faker.number.int(9);
} else {
str += string.charAt(i);
}
@@ -197,7 +197,7 @@ export class HelpersModule {
max = min;
min = tmp;
}
- repetitions = this.faker.datatype.number({ min: min, max: max });
+ repetitions = this.faker.number.int({ min, max });
string =
string.slice(0, token.index) +
token[1].repeat(repetitions) +
@@ -229,7 +229,7 @@ export class HelpersModule {
}
string =
string.slice(0, token.index) +
- this.faker.datatype.number({ min: min, max: max }).toString() +
+ this.faker.number.int({ min, max }).toString() +
string.slice(token.index + token[0].length);
token = string.match(RANGE_REG);
}
@@ -289,7 +289,7 @@ export class HelpersModule {
}
for (let i = list.length - 1; i > 0; --i) {
- const j = this.faker.datatype.number(i);
+ const j = this.faker.number.int(i);
[list[i], list[j]] = [list[j], list[i]];
}
@@ -341,7 +341,7 @@ export class HelpersModule {
*
* @example
* faker.helpers.mustache('I found {{count}} instances of "{{word}}".', {
- * count: () => `${faker.datatype.number()}`,
+ * count: () => `${faker.number.int()}`,
* word: "this word",
* }) // 'I found 57591 instances of "this word".'
*
@@ -438,9 +438,7 @@ export class HelpersModule {
array: ReadonlyArray<T> = ['a', 'b', 'c'] as unknown as ReadonlyArray<T>
): T {
const index =
- array.length > 1
- ? this.faker.datatype.number({ max: array.length - 1 })
- : 0;
+ array.length > 1 ? this.faker.number.int({ max: array.length - 1 }) : 0;
return array[index];
}
@@ -470,7 +468,7 @@ export class HelpersModule {
count =
array.length === 0
? 0
- : this.faker.datatype.number({ min: 1, max: array.length });
+ : this.faker.number.int({ min: 1, max: array.length });
} else if (count > array.length) {
count = array.length;
} else if (count < 0) {
@@ -485,7 +483,7 @@ export class HelpersModule {
while (i-- > min) {
index = Math.floor(
- (i + 1) * this.faker.datatype.float({ min: 0, max: 0.99 })
+ (i + 1) * this.faker.number.float({ min: 0, max: 0.99 })
);
temp = arrayCopy[index];
arrayCopy[index] = arrayCopy[i];
@@ -644,7 +642,7 @@ export class HelpersModule {
if (typeof numberOrRange === 'number') {
return numberOrRange;
}
- return this.faker.datatype.number(numberOrRange);
+ return this.faker.number.int(numberOrRange);
}
/**
diff --git a/src/modules/image/index.ts b/src/modules/image/index.ts
index 8113c1f6..e0dd9d22 100644
--- a/src/modules/image/index.ts
+++ b/src/modules/image/index.ts
@@ -111,7 +111,7 @@ export class ImageModule {
}
if (randomize) {
- url += `?lock=${this.faker.datatype.number()}`;
+ url += `?lock=${this.faker.number.int()}`;
}
return url;
diff --git a/src/modules/image/providers/lorempixel.ts b/src/modules/image/providers/lorempixel.ts
index a172517b..f8bb81e5 100644
--- a/src/modules/image/providers/lorempixel.ts
+++ b/src/modules/image/providers/lorempixel.ts
@@ -60,7 +60,7 @@ export class Lorempixel {
}
if (randomize) {
- url += `?${this.faker.datatype.number()}`;
+ url += `?${this.faker.number.int()}`;
}
return url;
diff --git a/src/modules/internet/index.ts b/src/modules/internet/index.ts
index 60e3ac55..a32045d9 100644
--- a/src/modules/internet/index.ts
+++ b/src/modules/internet/index.ts
@@ -46,7 +46,7 @@ export class InternetModule {
* @since 2.0.1
*/
avatar(): string {
- return `https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/${this.faker.datatype.number(
+ return `https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/${this.faker.number.int(
1249
)}.jpg`;
}
@@ -140,9 +140,9 @@ export class InternetModule {
let result: string;
firstName = firstName || this.faker.person.firstName();
lastName = lastName || this.faker.person.lastName();
- switch (this.faker.datatype.number(2)) {
+ switch (this.faker.number.int(2)) {
case 0:
- result = `${firstName}${this.faker.datatype.number(99)}`;
+ result = `${firstName}${this.faker.number.int(99)}`;
break;
case 1:
result =
@@ -152,7 +152,7 @@ export class InternetModule {
result = `${firstName}${this.faker.helpers.arrayElement([
'.',
'_',
- ])}${lastName}${this.faker.datatype.number(99)}`;
+ ])}${lastName}${this.faker.number.int(99)}`;
break;
}
result = result.toString().replace(/'/g, '');
@@ -319,7 +319,7 @@ export class InternetModule {
*/
ipv4(): string {
const randNum = () => {
- return this.faker.datatype.number(255).toFixed(0);
+ return this.faker.number.int(255).toFixed(0);
};
const result: string[] = [];
@@ -380,7 +380,7 @@ export class InternetModule {
* @since 5.4.0
*/
port(): number {
- return this.faker.datatype.number({ min: 0, max: 65535 });
+ return this.faker.number.int(65535);
}
/**
@@ -418,7 +418,7 @@ export class InternetModule {
blueBase: number = 0
): string {
const colorFromBase = (base: number): string =>
- Math.floor((this.faker.datatype.number(256) + base) / 2)
+ Math.floor((this.faker.number.int(256) + base) / 2)
.toString(16)
.padStart(2, '0');
@@ -451,7 +451,7 @@ export class InternetModule {
}
for (i = 0; i < 12; i++) {
- mac += this.faker.datatype.number(15).toString(16);
+ mac += this.faker.number.hex(15);
if (i % 2 === 1 && i !== 11) {
mac += validSep;
}
@@ -506,7 +506,7 @@ export class InternetModule {
pattern = consonant;
}
}
- const n = this.faker.datatype.number(94) + 33;
+ const n = this.faker.number.int(94) + 33;
let char = String.fromCharCode(n);
if (memorable) {
char = char.toLowerCase();
diff --git a/src/modules/internet/user-agent.ts b/src/modules/internet/user-agent.ts
index 972b2574..005e31e6 100644
--- a/src/modules/internet/user-agent.ts
+++ b/src/modules/internet/user-agent.ts
@@ -58,7 +58,7 @@ export function generate(faker: Faker): string {
obj: T
): keyof T => {
//returns a random key from the passed object; keys are weighted by the decimal probability in their value
- const rand = faker.datatype.number({ min: 0, max: 100 }) / 100;
+ const rand = faker.number.int(100) / 100;
let min = 0;
let max = 0;
let return_val: string;
@@ -217,7 +217,7 @@ export function generate(faker: Faker): string {
//generate a random revision
//dots = 2 returns .x.y where x & y are between 0 and 9
for (let x = 0; x < dots; x++) {
- return_val += `.${faker.datatype.number({ min: 0, max: 9 })}`;
+ return_val += `.${faker.string.numeric({ allowLeadingZeros: true })}`;
}
return return_val;
};
@@ -225,53 +225,51 @@ export function generate(faker: Faker): string {
const version_string = {
net() {
return [
- faker.datatype.number({ min: 1, max: 4 }),
- faker.datatype.number({ min: 0, max: 9 }),
- faker.datatype.number({ min: 10000, max: 99999 }),
- faker.datatype.number({ min: 0, max: 9 }),
+ faker.number.int({ min: 1, max: 4 }),
+ faker.number.int(9),
+ faker.number.int({ min: 10000, max: 99999 }),
+ faker.number.int(9),
].join('.');
},
nt() {
- return [
- faker.datatype.number({ min: 5, max: 6 }),
- faker.datatype.number({ min: 0, max: 3 }),
- ].join('.');
+ return [faker.number.int({ min: 5, max: 6 }), faker.number.int(3)].join(
+ '.'
+ );
},
ie() {
- return faker.datatype.number({ min: 7, max: 11 });
+ return faker.number.int({ min: 7, max: 11 });
},
trident() {
- return [
- faker.datatype.number({ min: 3, max: 7 }),
- faker.datatype.number({ min: 0, max: 1 }),
- ].join('.');
+ return [faker.number.int({ min: 3, max: 7 }), faker.number.int(1)].join(
+ '.'
+ );
},
osx(delim?: string) {
return [
10,
- faker.datatype.number({ min: 5, max: 10 }),
- faker.datatype.number({ min: 0, max: 9 }),
+ faker.number.int({ min: 5, max: 10 }),
+ faker.number.int(9),
].join(delim || '.');
},
chrome() {
return [
- faker.datatype.number({ min: 13, max: 39 }),
+ faker.number.int({ min: 13, max: 39 }),
0,
- faker.datatype.number({ min: 800, max: 899 }),
+ faker.number.int({ min: 800, max: 899 }),
0,
].join('.');
},
presto() {
- return `2.9.${faker.datatype.number({ min: 160, max: 190 })}`;
+ return `2.9.${faker.number.int({ min: 160, max: 190 })}`;
},
presto2() {
- return `${faker.datatype.number({ min: 10, max: 12 })}.00`;
+ return `${faker.number.int({ min: 10, max: 12 })}.00`;
},
safari() {
return [
- faker.datatype.number({ min: 531, max: 538 }),
- faker.datatype.number({ min: 0, max: 2 }),
- faker.datatype.number({ min: 0, max: 2 }),
+ faker.number.int({ min: 531, max: 538 }),
+ faker.number.int(2),
+ faker.number.int(2),
].join('.');
},
};
@@ -279,7 +277,7 @@ export function generate(faker: Faker): string {
const browserMap = {
firefox(arch: OS): string {
//https://developer.mozilla.org/en-US/docs/Gecko_user_agent_string_reference
- const firefox_ver = `${faker.datatype.number({
+ const firefox_ver = `${faker.number.int({
min: 5,
max: 15,
})}${randomRevision(2)}`,
@@ -303,7 +301,7 @@ export function generate(faker: Faker): string {
if (ver >= 11) {
//http://msdn.microsoft.com/en-us/library/ie/hh869301(v=vs.85).aspx
- return `Mozilla/5.0 (Windows NT 6.${faker.datatype.number({
+ return `Mozilla/5.0 (Windows NT 6.${faker.number.int({
min: 1,
max: 3,
})}; Trident/7.0; ${
@@ -327,29 +325,23 @@ export function generate(faker: Faker): string {
? `(X11; Linux ${randomProc(arch)}; U; ${randomLang()}${presto_ver}`
: `(Macintosh; Intel Mac OS X ${version_string.osx()} U; ${randomLang()} Presto/${version_string.presto()} Version/${version_string.presto2()})`;
- return `Opera/${faker.datatype.number({
+ return `Opera/${faker.number.int({
min: 9,
max: 14,
- })}.${faker.datatype.number({
- min: 0,
- max: 99,
- })} ${os_ver}`;
+ })}.${faker.number.int(99)} ${os_ver}`;
},
safari(arch: OS): string {
const safari = version_string.safari(),
- ver = `${faker.datatype.number({
+ ver = `${faker.number.int({
min: 4,
max: 7,
- })}.${faker.datatype.number({
- min: 0,
- max: 1,
- })}.${faker.datatype.number({ min: 0, max: 10 })}`,
+ })}.${faker.number.int(1)}.${faker.number.int(10)}`,
os_ver =
arch === 'mac'
? `(Macintosh; ${randomProc('mac')} Mac OS X ${version_string.osx(
'_'
- )} rv:${faker.datatype.number({
+ )} rv:${faker.number.int({
min: 2,
max: 6,
})}.0; ${randomLang()}) `
diff --git a/src/modules/location/index.ts b/src/modules/location/index.ts
index fcb8aabd..a4e6ef9e 100644
--- a/src/modules/location/index.ts
+++ b/src/modules/location/index.ts
@@ -60,7 +60,7 @@ export class LocationModule {
zipCodeByState(state: string): string {
const zipRange = this.faker.definitions.location.postcode_by_state?.[state];
if (zipRange) {
- return String(this.faker.datatype.number(zipRange));
+ return String(this.faker.number.int(zipRange));
}
return this.zipCode();
}
@@ -269,11 +269,7 @@ export class LocationModule {
*/
// TODO @xDivisionByZerox 2022-06-12 this signature should probably be an object for easier maintainability
latitude(max: number = 90, min: number = -90, precision: number = 4): number {
- return this.faker.datatype.number({
- min,
- max,
- precision: parseFloat(`${(0.0).toPrecision(precision)}1`),
- });
+ return this.faker.number.float({ min, max, precision: 10 ** -precision });
}
/**
@@ -295,11 +291,7 @@ export class LocationModule {
min: number = -180,
precision: number = 4
): number {
- return this.faker.datatype.number({
- max: max,
- min: min,
- precision: parseFloat(`${(0.0).toPrecision(precision)}1`),
- });
+ return this.faker.number.float({ max, min, precision: 10 ** -precision });
}
/**
@@ -399,8 +391,7 @@ export class LocationModule {
return [this.latitude(), this.longitude()];
}
- const angleRadians = this.faker.datatype.float({
- min: 0,
+ const angleRadians = this.faker.number.float({
max: 2 * Math.PI,
precision: 0.00001,
}); // in ° radians
@@ -408,8 +399,7 @@ export class LocationModule {
const radiusMetric = isMetric ? radius : radius * 1.60934; // in km
const errorCorrection = 0.995; // avoid float issues
const distanceInKm =
- this.faker.datatype.float({
- min: 0,
+ this.faker.number.float({
max: radiusMetric,
precision: 0.001,
}) * errorCorrection; // in km
diff --git a/src/modules/number/index.ts b/src/modules/number/index.ts
new file mode 100644
index 00000000..c30d5015
--- /dev/null
+++ b/src/modules/number/index.ts
@@ -0,0 +1,197 @@
+import type { Faker } from '../..';
+import { FakerError } from '../../errors/faker-error';
+import type { Mersenne } from '../../internal/mersenne/mersenne';
+
+/**
+ * Module to generate numbers of any kind.
+ */
+export class NumberModule {
+ constructor(private readonly faker: Faker) {
+ // Bind `this` so namespaced is working correctly
+ for (const name of Object.getOwnPropertyNames(NumberModule.prototype)) {
+ if (name === 'constructor' || typeof this[name] !== 'function') {
+ continue;
+ }
+ this[name] = this[name].bind(this);
+ }
+ }
+
+ /**
+ * Returns a single random integer between zero and the given max value or the given range.
+ * The bounds are inclusive.
+ *
+ * @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 `min + 99999`.
+ *
+ * @throws When options define `max < min`.
+ *
+ * @example
+ * faker.number.int() // 55422
+ * faker.number.int(100) // 52
+ * faker.number.int({ min: 1000000 }) // 1031433
+ * faker.number.int({ max: 100 }) // 42
+ * faker.number.int({ min: 10, max: 100 }) // 57
+ *
+ * @since 8.0.0
+ */
+ int(options: number | { min?: number; max?: number } = {}): number {
+ if (typeof options === 'number') {
+ options = { max: options };
+ }
+
+ const { min = 0, max = min + 99999 } = options;
+
+ if (max === min) {
+ return min;
+ }
+
+ if (max < min) {
+ throw new FakerError(`Max ${max} should be greater than min ${min}.`);
+ }
+
+ const mersenne: Mersenne =
+ // @ts-expect-error: access private member field
+ this.faker._mersenne;
+
+ return mersenne.next({ min, max: max + 1 });
+ }
+
+ /**
+ * Returns a single random floating-point number for a given precision or range and precision.
+ *
+ * @param options Precision 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 `99999`.
+ * @param options.precision Precision of the generated number. Defaults to `0.01`.
+ *
+ * @example
+ * faker.number.float() // 51696.36
+ * faker.number.float(1) // 52023.2
+ * faker.number.float({ min: 1000000 }) // 212859.76
+ * faker.number.float({ max: 100 }) // 28.11
+ * faker.number.float({ precision: 0.1 }) // 84055.3
+ * faker.number.float({ min: 10, max: 100, precision: 0.001 }) // 57.315
+ *
+ * @since 8.0.0
+ */
+ float(
+ options: number | { min?: number; max?: number; precision?: number } = {}
+ ): number {
+ if (typeof options === 'number') {
+ options = {
+ precision: options,
+ };
+ }
+
+ const { min = 0, max = min + 99999, precision = 0.01 } = options;
+
+ if (max === min) {
+ return min;
+ }
+
+ if (max < min) {
+ throw new FakerError(`Max ${max} should be greater than min ${min}.`);
+ }
+
+ const factor = 1 / precision;
+ const int = this.int({
+ min: min * factor,
+ max: max * factor,
+ });
+
+ return int / factor;
+ }
+
+ /**
+ * Returns a lowercase [hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal) number.
+ *
+ * @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 `min + 16`.
+ *
+ * @example
+ * faker.number.hex() // 'b'
+ * faker.number.hex(16) // '9'
+ * faker.number.hex({ min: 0, max: 65536 }) // 'af17'
+ *
+ * @since 8.0.0
+ */
+ hex(options: number | { min?: number; max?: number } = {}): string {
+ if (typeof options === 'number') {
+ options = { max: options };
+ }
+
+ const { min = 0, max = min + 16 } = options;
+
+ return this.int({
+ max,
+ min,
+ }).toString(16);
+ }
+
+ /**
+ * Returns a [BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#bigint_type) number.
+ *
+ * @param options Maximum value or options object. Defaults to `{}`.
+ * @param options.min Lower bound for generated bigint. Defaults to `0n`.
+ * @param options.max Upper bound for generated bigint. Defaults to `min + 999999999999999n`.
+ *
+ * @throws When options define `max < min`.
+ *
+ * @example
+ * faker.number.bigInt() // 55422n
+ * faker.number.bigInt(100n) // 52n
+ * faker.number.bigInt({ min: 1000000n }) // 431433n
+ * faker.number.bigInt({ max: 100n }) // 42n
+ * faker.number.bigInt({ min: 10n, max: 100n }) // 36n
+ *
+ * @since 8.0.0
+ */
+ bigInt(
+ options:
+ | bigint
+ | number
+ | string
+ | boolean
+ | {
+ min?: bigint | number | string | boolean;
+ max?: bigint | number | string | boolean;
+ } = {}
+ ): bigint {
+ if (
+ typeof options === 'bigint' ||
+ typeof options === 'number' ||
+ typeof options === 'string' ||
+ typeof options === 'boolean'
+ ) {
+ options = {
+ max: options,
+ };
+ }
+
+ const min = BigInt(options.min ?? 0);
+ const max = BigInt(options.max ?? min + BigInt(999999999999999));
+
+ if (max === min) {
+ return min;
+ }
+
+ if (max < min) {
+ throw new FakerError(`Max ${max} should be larger then min ${min}.`);
+ }
+
+ const delta = max - min;
+
+ const offset =
+ BigInt(
+ this.faker.string.numeric({
+ length: delta.toString(10).length,
+ allowLeadingZeros: true,
+ })
+ ) %
+ (delta + BigInt(1));
+
+ return min + offset;
+ }
+}
diff --git a/src/modules/random/index.ts b/src/modules/random/index.ts
index cb81935b..21e46509 100644
--- a/src/modules/random/index.ts
+++ b/src/modules/random/index.ts
@@ -151,7 +151,7 @@ export class RandomModule {
const words: string[] = [];
if (count == null) {
- count = this.faker.datatype.number({ min: 1, max: 3 });
+ count = this.faker.number.int({ min: 1, max: 3 });
}
for (let i = 0; i < count; i++) {
diff --git a/src/modules/string/index.ts b/src/modules/string/index.ts
index f1a13c1d..de1ec446 100644
--- a/src/modules/string/index.ts
+++ b/src/modules/string/index.ts
@@ -79,7 +79,7 @@ export type NumericChar =
export type AlphaChar = LowerAlphaChar | UpperAlphaChar;
export type AlphaNumericChar = AlphaChar | NumericChar;
-const SAMPLE_MAX_LENGTH = Math.pow(2, 20);
+const SAMPLE_MAX_LENGTH = 2 ** 20;
/**
* Module to generate string related entries.
@@ -416,7 +416,7 @@ export class StringModule {
while (returnString.length < length) {
returnString += String.fromCharCode(
- this.faker.datatype.number(charCodeOption)
+ this.faker.number.int(charCodeOption)
);
}
@@ -434,7 +434,7 @@ export class StringModule {
uuid(): string {
const RFC4122_TEMPLATE = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
const replacePlaceholders = (placeholder: string) => {
- const random = this.faker.datatype.number({ min: 0, max: 15 });
+ const random = this.faker.number.int(15);
const value = placeholder === 'x' ? random : (random & 0x3) | 0x8;
return value.toString(16);
};
diff --git a/src/modules/system/index.ts b/src/modules/system/index.ts
index 12bb25ba..4bf28aff 100644
--- a/src/modules/system/index.ts
+++ b/src/modules/system/index.ts
@@ -228,9 +228,9 @@ export class SystemModule {
*/
semver(): string {
return [
- this.faker.datatype.number(9),
- this.faker.datatype.number(9),
- this.faker.datatype.number(9),
+ this.faker.number.int(9),
+ this.faker.number.int(9),
+ this.faker.number.int(9),
].join('.');
}
@@ -262,35 +262,24 @@ export class SystemModule {
let suffix: string;
let prefix = '';
+ const digit = () => this.faker.string.numeric({ allowLeadingZeros: true });
switch (interfaceSchema) {
case 'index':
- suffix = this.faker.datatype.number(9).toString();
+ suffix = digit();
break;
case 'slot':
- suffix = `${this.faker.datatype.number(9)}${
- this.faker.helpers.maybe(() => `f${this.faker.datatype.number(9)}`) ??
- ''
- }${
- this.faker.helpers.maybe(() => `d${this.faker.datatype.number(9)}`) ??
- ''
- }`;
+ suffix = `${digit()}${
+ this.faker.helpers.maybe(() => `f${digit()}`) ?? ''
+ }${this.faker.helpers.maybe(() => `d${digit()}`) ?? ''}`;
break;
case 'mac':
suffix = this.faker.internet.mac('');
break;
case 'pci':
- prefix =
- this.faker.helpers.maybe(() => `P${this.faker.datatype.number(9)}`) ??
- '';
- suffix = `${this.faker.datatype.number(9)}s${this.faker.datatype.number(
- 9
- )}${
- this.faker.helpers.maybe(() => `f${this.faker.datatype.number(9)}`) ??
- ''
- }${
- this.faker.helpers.maybe(() => `d${this.faker.datatype.number(9)}`) ??
- ''
- }`;
+ prefix = this.faker.helpers.maybe(() => `P${digit()}`) ?? '';
+ suffix = `${digit()}s${digit()}${
+ this.faker.helpers.maybe(() => `f${digit()}`) ?? ''
+ }${this.faker.helpers.maybe(() => `d${digit()}`) ?? ''}`;
break;
}
@@ -322,17 +311,17 @@ export class SystemModule {
const { includeYear = false, includeNonStandard = false } = options;
// create the arrays to hold the available values for each component of the expression
- const minutes = [this.faker.datatype.number({ min: 0, max: 59 }), '*'];
- const hours = [this.faker.datatype.number({ min: 0, max: 23 }), '*'];
- const days = [this.faker.datatype.number({ min: 1, max: 31 }), '*', '?'];
- const months = [this.faker.datatype.number({ min: 1, max: 12 }), '*'];
+ const minutes = [this.faker.number.int(59), '*'];
+ const hours = [this.faker.number.int(23), '*'];
+ const days = [this.faker.number.int({ min: 1, max: 31 }), '*', '?'];
+ const months = [this.faker.number.int({ min: 1, max: 12 }), '*'];
const daysOfWeek = [
- this.faker.datatype.number({ min: 0, max: 6 }),
+ this.faker.number.int(6),
this.faker.helpers.arrayElement(CRON_DAY_OF_WEEK),
'*',
'?',
];
- const years = [this.faker.datatype.number({ min: 1970, max: 2099 }), '*'];
+ const years = [this.faker.number.int({ min: 1970, max: 2099 }), '*'];
const minute = this.faker.helpers.arrayElement(minutes);
const hour = this.faker.helpers.arrayElement(hours);
diff --git a/src/modules/vehicle/index.ts b/src/modules/vehicle/index.ts
index e6bdaeb3..dd08b75f 100644
--- a/src/modules/vehicle/index.ts
+++ b/src/modules/vehicle/index.ts
@@ -100,8 +100,7 @@ export class VehicleModule {
length: 1,
casing: 'upper',
exclude,
- })}${this.faker.datatype.number({ min: 10000, max: 99999 })}` // return five digit #
- .toUpperCase();
+ })}${this.faker.number.int({ min: 10000, max: 99999 })}`; // return five digit #
}
/**
@@ -128,12 +127,9 @@ export class VehicleModule {
return `${this.faker.string.alpha({
length: 2,
casing: 'upper',
- })}${this.faker.datatype.number({
- min: 0,
- max: 9,
- })}${this.faker.datatype.number({
- min: 0,
- max: 9,
+ })}${this.faker.string.numeric({
+ length: 2,
+ allowLeadingZeros: true,
})}${this.faker.string.alpha({
length: 3,
casing: 'upper',
diff --git a/test/__snapshots__/number.spec.ts.snap b/test/__snapshots__/number.spec.ts.snap
new file mode 100644
index 00000000..e89a2a0e
--- /dev/null
+++ b/test/__snapshots__/number.spec.ts.snap
@@ -0,0 +1,109 @@
+// Vitest Snapshot v1
+
+exports[`number > 42 > bigInt > noArgs 1`] = `379177551410048n`;
+
+exports[`number > 42 > bigInt > with big options 1`] = `17723424219505212239212136n`;
+
+exports[`number > 42 > bigInt > with bigint value 1`] = `7n`;
+
+exports[`number > 42 > bigInt > with boolean value 1`] = `1n`;
+
+exports[`number > 42 > bigInt > with number value 1`] = `37n`;
+
+exports[`number > 42 > bigInt > with options 1`] = `1n`;
+
+exports[`number > 42 > bigInt > with string value 1`] = `37n`;
+
+exports[`number > 42 > float > with max 1`] = `25.84`;
+
+exports[`number > 42 > float > with min 1`] = `37411.64`;
+
+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 plain number 1`] = `37453.636891`;
+
+exports[`number > 42 > hex > noArgs 1`] = `"6"`;
+
+exports[`number > 42 > hex > with options 1`] = `"4"`;
+
+exports[`number > 42 > hex > with value 1`] = `"0"`;
+
+exports[`number > 42 > int > noArgs 1`] = `37454`;
+
+exports[`number > 42 > int > with options 1`] = `4`;
+
+exports[`number > 42 > int > with value 1`] = `0`;
+
+exports[`number > 1211 > bigInt > noArgs 1`] = `948721906162743n`;
+
+exports[`number > 1211 > bigInt > with big options 1`] = `22017767508700414061739128n`;
+
+exports[`number > 1211 > bigInt > with bigint value 1`] = `80n`;
+
+exports[`number > 1211 > bigInt > with boolean value 1`] = `1n`;
+
+exports[`number > 1211 > bigInt > with number value 1`] = `8n`;
+
+exports[`number > 1211 > bigInt > with options 1`] = `10n`;
+
+exports[`number > 1211 > bigInt > with string value 1`] = `24n`;
+
+exports[`number > 1211 > float > with max 1`] = `64.07`;
+
+exports[`number > 1211 > float > with min 1`] = `92809.09`;
+
+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 plain number 1`] = `92851.086855`;
+
+exports[`number > 1211 > hex > noArgs 1`] = `"f"`;
+
+exports[`number > 1211 > hex > with options 1`] = `"a"`;
+
+exports[`number > 1211 > hex > with value 1`] = `"1"`;
+
+exports[`number > 1211 > int > noArgs 1`] = `92852`;
+
+exports[`number > 1211 > int > with options 1`] = `10`;
+
+exports[`number > 1211 > int > with value 1`] = `1`;
+
+exports[`number > 1337 > bigInt > noArgs 1`] = `251225403255239n`;
+
+exports[`number > 1337 > bigInt > with big options 1`] = `31258255497061442772623668n`;
+
+exports[`number > 1337 > bigInt > with bigint value 1`] = `3n`;
+
+exports[`number > 1337 > bigInt > with boolean value 1`] = `0n`;
+
+exports[`number > 1337 > bigInt > with number value 1`] = `25n`;
+
+exports[`number > 1337 > bigInt > with options 1`] = `-15n`;
+
+exports[`number > 1337 > bigInt > with string value 1`] = `25n`;
+
+exports[`number > 1337 > float > with max 1`] = `18.08`;
+
+exports[`number > 1337 > float > with min 1`] = `26160.2`;
+
+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 plain number 1`] = `26202.205595`;
+
+exports[`number > 1337 > hex > noArgs 1`] = `"4"`;
+
+exports[`number > 1337 > hex > with options 1`] = `"2"`;
+
+exports[`number > 1337 > hex > with value 1`] = `"0"`;
+
+exports[`number > 1337 > int > noArgs 1`] = `26202`;
+
+exports[`number > 1337 > int > with options 1`] = `2`;
+
+exports[`number > 1337 > int > with value 1`] = `0`;
diff --git a/test/datatype.spec.ts b/test/datatype.spec.ts
index bd675e9a..5571f3b9 100644
--- a/test/datatype.spec.ts
+++ b/test/datatype.spec.ts
@@ -157,19 +157,37 @@ describe('datatype', () => {
expect(foundNegative5).toBeTruthy();
});
- it('provides numbers with a given precision', () => {
- const options = { min: 0, max: 1.5, precision: 0.5 };
+ it('provides numbers with a given precision of 0.5 steps', () => {
const results = Array.from(
new Set(
- Array.from({ length: 50 }, () => faker.datatype.number(options))
+ Array.from({ length: 50 }, () =>
+ faker.datatype.float({
+ min: 0,
+ max: 1.5,
+ precision: 0.5,
+ })
+ )
)
).sort();
- expect(results).toContain(0.5);
- expect(results).toContain(1.0);
+ expect(results).toEqual([0, 0.5, 1, 1.5]);
+ });
- expect(results[0]).toBe(0);
- expect(results[results.length - 1]).toBe(1.5);
+ // TODO @Shinigami92 2022-11-24: https://github.com/faker-js/faker/issues/1595
+ it.todo('provides numbers with a given precision of 0.4 steps', () => {
+ const results = Array.from(
+ new Set(
+ Array.from({ length: 50 }, () =>
+ faker.datatype.float({
+ min: 0,
+ max: 1.9,
+ precision: 0.4,
+ })
+ )
+ )
+ ).sort();
+
+ expect(results).toEqual([0, 0.4, 0.8, 1.2, 1.6]);
});
it('provides numbers with a with exact precision', () => {
@@ -259,11 +277,7 @@ describe('datatype', () => {
)
).sort();
- expect(results).toContain(0.5);
- expect(results).toContain(1.0);
-
- expect(results[0]).toBe(0);
- expect(results[results.length - 1]).toBe(1.5);
+ expect(results).toEqual([0, 0.5, 1, 1.5]);
});
it('provides numbers with a with exact precision', () => {
diff --git a/test/faker.spec.ts b/test/faker.spec.ts
index dac1be5a..d418f19b 100644
--- a/test/faker.spec.ts
+++ b/test/faker.spec.ts
@@ -115,15 +115,15 @@ describe('faker', () => {
it('should reset the sequence when calling `seed`', () => {
const seed = faker.seed();
- const num1 = faker.datatype.number();
+ const num1 = faker.number.int();
const newSeed = faker.seed(seed);
- const num2 = faker.datatype.number();
+ const num2 = faker.number.int();
expect(num1).toBe(num2);
expect(newSeed).toBe(seed);
- const num3 = faker.datatype.number();
+ const num3 = faker.number.int();
expect(num1).not.toBe(num3);
});
diff --git a/test/finance.spec.ts b/test/finance.spec.ts
index 730bfe78..7c90a62a 100644
--- a/test/finance.spec.ts
+++ b/test/finance.spec.ts
@@ -130,7 +130,7 @@ describe('finance', () => {
});
it('should set a specified length', () => {
- let expected = faker.datatype.number(20);
+ let expected = faker.number.int(20);
expected = expected || 4;
diff --git a/test/helpers.spec.ts b/test/helpers.spec.ts
index 412dff30..c56d2589 100644
--- a/test/helpers.spec.ts
+++ b/test/helpers.spec.ts
@@ -109,8 +109,8 @@ describe('helpers', () => {
t.describe('unique', (t) => {
t.it('with customMethod', customUniqueMethod)
.it('with customMethod and args', customUniqueMethod, ['prefix-1-'])
- .it('with () => number', faker.datatype.number)
- .it('with () => number and args', faker.datatype.number, [50]);
+ .it('with () => number', faker.number.int)
+ .it('with () => number and args', faker.number.int, [50]);
});
});
@@ -384,7 +384,7 @@ describe('helpers', () => {
});
it('definition array returns unique array', () => {
- const length = faker.datatype.number({ min: 1, max: 6 });
+ const length = faker.number.int({ min: 1, max: 6 });
const unique = faker.helpers.uniqueArray(
faker.definitions.hacker.noun,
length
@@ -394,7 +394,7 @@ describe('helpers', () => {
});
it('function returns unique array', () => {
- const length = faker.datatype.number({ min: 1, max: 6 });
+ const length = faker.number.int({ min: 1, max: 6 });
const unique = faker.helpers.uniqueArray(faker.lorem.word, length);
expect(unique).not.toContainDuplicates();
expect(unique).toHaveLength(length);
@@ -402,7 +402,7 @@ describe('helpers', () => {
it('empty array returns empty array', () => {
const input = [];
- const length = faker.datatype.number({ min: 1, max: 6 });
+ const length = faker.number.int({ min: 1, max: 6 });
const unique = faker.helpers.uniqueArray(input, length);
expect(unique).toHaveLength(0);
});
diff --git a/test/number.spec.ts b/test/number.spec.ts
new file mode 100644
index 00000000..5ba1a0a4
--- /dev/null
+++ b/test/number.spec.ts
@@ -0,0 +1,354 @@
+import validator from 'validator';
+import { afterEach, describe, expect, it } from 'vitest';
+import { faker, FakerError } from '../src';
+import { seededTests } from './support/seededRuns';
+
+describe('number', () => {
+ afterEach(() => {
+ faker.locale = 'en';
+ });
+
+ seededTests(faker, 'number', (t) => {
+ t.describeEach(
+ 'int',
+ 'hex'
+ )((t) => {
+ t.it('noArgs')
+ .it('with value', 1)
+ .it('with options', { min: 0, max: 10 });
+ });
+
+ t.describe('float', (t) => {
+ t.it('with plain number', 0.000001)
+ .it('with min', { min: -42 })
+ .it('with max', { max: 69 })
+ .it('with min and max', { min: -42, max: 69 })
+ .it('with min, max and precision', {
+ min: -42,
+ max: 69,
+ precision: 0.0001,
+ });
+ });
+
+ t.describe('bigInt', (t) => {
+ t.it('noArgs')
+ .it('with number value', 42)
+ .it('with string value', '69')
+ .it('with boolean value', true)
+ .it('with bigint value', 123n)
+ .it('with options', { min: -42, max: 69 })
+ .it('with big options', {
+ min: 6135715171537515454317351n,
+ max: 32465761264574654845432354n,
+ });
+ });
+ });
+
+ describe(`random seeded tests for seed ${faker.seed()}`, () => {
+ describe('int', () => {
+ it('should return a random number given a maximum value as Number', () => {
+ const actual = faker.number.int(10);
+
+ expect(actual).toBeGreaterThanOrEqual(0);
+ expect(actual).toBeLessThanOrEqual(10);
+ });
+
+ it('should return a random number given a maximum value as Object', () => {
+ const actual = faker.number.int({ max: 10 });
+
+ expect(actual).toBeGreaterThanOrEqual(0);
+ expect(actual).toBeLessThanOrEqual(10);
+ });
+
+ it('should return a random number given a maximum value of 0', () => {
+ const actual = faker.number.int({ max: 0 });
+
+ expect(actual).toBe(0);
+ });
+
+ it('should return a random number given a negative number minimum and maximum value of 0', () => {
+ const actual = faker.number.int({ min: -100, max: 0 });
+
+ expect(actual).toBeGreaterThanOrEqual(-100);
+ expect(actual).toBeLessThanOrEqual(0);
+ });
+
+ it('should return a random number between a range', () => {
+ for (let i = 0; i < 100; i++) {
+ const actual = faker.number.int({ min: 22, max: 33 });
+ expect(actual).toBeGreaterThanOrEqual(22);
+ expect(actual).toBeLessThanOrEqual(33);
+ }
+ });
+
+ it('should return inclusive negative max value', () => {
+ let foundNegative4 = false;
+ let foundNegative5 = false;
+
+ for (let iter = 0; iter < 1000; iter++) {
+ const actual = faker.number.int({ min: -5, max: -4 });
+
+ if (actual === -4) {
+ foundNegative4 = true;
+ } else if (actual === -5) {
+ foundNegative5 = true;
+ }
+
+ expect(actual).toBeGreaterThanOrEqual(-5);
+ expect(actual).toBeLessThanOrEqual(-4);
+
+ if (foundNegative4 && foundNegative5) {
+ break;
+ }
+ }
+
+ expect(foundNegative4).toBeTruthy();
+ expect(foundNegative5).toBeTruthy();
+ });
+
+ it('should not mutate the input object', () => {
+ const input: {
+ min?: number;
+ max?: number;
+ precision?: number;
+ otherProperty: string;
+ } = Object.freeze({
+ min: 1,
+ precision: 1,
+ otherProperty: 'hello darkness my old friend',
+ });
+
+ expect(() => faker.number.int(input)).not.toThrow();
+ });
+
+ it('should throw when min > max', () => {
+ const min = 10;
+ const max = 9;
+
+ expect(() => {
+ faker.number.int({ min, max });
+ }).toThrowError(`Max ${max} should be greater than min ${min}.`);
+ });
+
+ // TODO @Shinigami92 2022-11-24: https://github.com/faker-js/faker/issues/1595
+ it.todo(
+ 'should throw when there is no integer between min and max',
+ () => {
+ expect(() => {
+ faker.number.int({ min: 2.1, max: 2.9 });
+ }).toThrow();
+ }
+ );
+ });
+
+ describe('float', () => {
+ it('should return a random float with a default precision of 2 digits after floating point', () => {
+ const number = faker.number.float();
+ expect(number).toBe(Number(number.toFixed(2)));
+ });
+
+ it('should return a random float given a precision value', () => {
+ const number = faker.number.float(0.001);
+ expect(number).toBe(Number(number.toFixed(3)));
+ });
+
+ it('should return a random number given a max value of 10', () => {
+ const float = faker.number.float({ max: 10 });
+ expect(float).toBeGreaterThanOrEqual(0);
+ expect(float).toBeLessThanOrEqual(10);
+ });
+
+ it('should return 0 given a max value of 0', () => {
+ expect(faker.number.float({ max: 0 })).toBe(0);
+ });
+
+ it('should return a random number given a negative number min and max value of 0', () => {
+ const float = faker.number.float({ min: -100, max: 0 });
+ expect(float).toBeGreaterThanOrEqual(-100);
+ expect(float).toBeLessThanOrEqual(0);
+ });
+
+ it('should return a random number between a range', () => {
+ for (let i = 0; i < 5; i++) {
+ const randomNumber = faker.number.float({ min: 22, max: 33 });
+ expect(randomNumber).toBeGreaterThanOrEqual(22);
+ expect(randomNumber).toBeLessThanOrEqual(33);
+ }
+ });
+
+ it('provides numbers with a given precision of 0.5 steps', () => {
+ const results = Array.from(
+ new Set(
+ Array.from({ length: 50 }, () =>
+ faker.number.float({
+ min: 0,
+ max: 1.5,
+ precision: 0.5,
+ })
+ )
+ )
+ ).sort();
+
+ expect(results).toEqual([0, 0.5, 1, 1.5]);
+ });
+
+ // TODO @Shinigami92 2022-11-24: https://github.com/faker-js/faker/issues/1595
+ it.todo('provides numbers with a given precision of 0.4 steps', () => {
+ const results = Array.from(
+ new Set(
+ Array.from({ length: 50 }, () =>
+ faker.number.float({
+ min: 0,
+ max: 1.9,
+ precision: 0.4,
+ })
+ )
+ )
+ ).sort();
+
+ expect(results).toEqual([0, 0.4, 0.8, 1.2, 1.6]);
+ });
+
+ it('provides numbers with an exact precision', () => {
+ for (let i = 0; i < 100; i++) {
+ const number = faker.number.float({
+ min: 0.5,
+ max: 0.99,
+ precision: 0.01,
+ });
+ expect(number).toBe(Number(number.toFixed(2)));
+ }
+ });
+
+ it('provides number with a precision 0', () => {
+ const float = faker.number.float({ precision: 0 });
+
+ expect(float).toBe(Math.floor(float));
+ });
+
+ it('should not modify the input object', () => {
+ expect(() =>
+ faker.number.float(Object.freeze({ min: 1, max: 2 }))
+ ).not.toThrow();
+ });
+
+ it('should throw when min > max', () => {
+ const min = 10;
+ const max = 9;
+
+ expect(() => {
+ faker.number.float({ min, max });
+ }).toThrowError(`Max ${max} should be greater than min ${min}.`);
+ });
+ });
+
+ describe('hex', () => {
+ it('generates single hex character when no additional argument was provided', () => {
+ const hex = faker.number.hex();
+ expect(hex).toBeTypeOf('string');
+ expect(hex).toHaveLength(1);
+ expect(hex).toSatisfy(validator.isHexadecimal);
+ });
+
+ it('generates a random hex string', () => {
+ const hex = faker.number.hex(5);
+ expect(hex).toSatisfy(validator.isHexadecimal);
+ });
+
+ it('generates a random hex in a specific range', () => {
+ const hex = faker.number.hex({ min: 15, max: 255 });
+
+ const hexNum = parseInt(hex, 16);
+ expect(hexNum).toBeLessThanOrEqual(255);
+ expect(hexNum).greaterThanOrEqual(15);
+ });
+
+ it('should throw when min > max', () => {
+ const min = 10;
+ const max = 9;
+
+ expect(() => {
+ faker.number.hex({ min, max });
+ }).toThrowError(`Max ${max} should be greater than min ${min}.`);
+ });
+ });
+
+ describe('bigInt', () => {
+ it('should generate a bigInt value', () => {
+ const generateBigInt = faker.number.bigInt();
+ expect(generateBigInt).toBeTypeOf('bigint');
+ });
+
+ it('should generate a big bigInt value with low delta', () => {
+ const generateBigInt = faker.number.bigInt({
+ min: 999999999n,
+ max: 1000000000n,
+ });
+ expect(generateBigInt).toBeTypeOf('bigint');
+ expect(generateBigInt).toBeGreaterThanOrEqual(999999999n);
+ expect(generateBigInt).toBeLessThanOrEqual(1000000000n);
+ });
+
+ it('should return a random bigint given a maximum value as BigInt', () => {
+ const generateBigInt = faker.number.bigInt(10n);
+ expect(generateBigInt).toBeGreaterThanOrEqual(0n);
+ expect(generateBigInt).toBeLessThanOrEqual(10n);
+ });
+
+ it('should return a random bigint given a maximum value as Object', () => {
+ const generateBigInt = faker.number.bigInt({ max: 10n });
+ expect(generateBigInt).toBeGreaterThanOrEqual(0n);
+ expect(generateBigInt).toBeLessThanOrEqual(10n);
+ });
+
+ it('should return a random bigint given a maximum value of 0', () => {
+ expect(faker.number.bigInt({ max: 0n })).toBe(0n);
+ });
+
+ it('should return a random bigint given a negative bigint minimum and maximum value of 0', () => {
+ const generateBigInt = faker.number.bigInt({ min: -100n, max: 0n });
+ expect(generateBigInt).toBeGreaterThanOrEqual(-100n);
+ expect(generateBigInt).toBeLessThanOrEqual(0n);
+ });
+
+ it('should return a random bigint between a range', () => {
+ const randomBigInt = faker.number.bigInt({ min: 22, max: 33 });
+ expect(randomBigInt).toBeGreaterThanOrEqual(22);
+ expect(randomBigInt).toBeLessThanOrEqual(33);
+ });
+
+ it('should return a random bigint for a very large range', () => {
+ const randomBigInt = faker.number.bigInt({
+ min: 0n,
+ max: 10000000000000000000000n,
+ });
+ expect(randomBigInt).toBeGreaterThanOrEqual(0n);
+ expect(randomBigInt).toBeLessThanOrEqual(10000000000000000000000n);
+ });
+
+ it('should not mutate the input object', () => {
+ const input: {
+ min?: bigint;
+ max?: bigint;
+ otherProperty: string;
+ } = Object.freeze({
+ min: 1n,
+ otherProperty: 'hello darkness my old friend',
+ });
+
+ expect(() => faker.number.bigInt(input)).not.toThrow();
+ });
+
+ it('should throw when min > max', () => {
+ const min = 10000n;
+ const max = 999n;
+
+ expect(() => {
+ faker.number.bigInt({ min, max });
+ }).toThrowError(
+ new FakerError(`Max ${max} should be larger then min ${min}.`)
+ );
+ });
+ });
+ });
+});
diff --git a/test/string.spec.ts b/test/string.spec.ts
index 32dc2ddf..f3073c0f 100644
--- a/test/string.spec.ts
+++ b/test/string.spec.ts
@@ -513,16 +513,16 @@ describe('string', () => {
});
it('should return empty string if negative length is passed', () => {
- const negativeValue = faker.datatype.number({ min: -1000, max: -1 });
+ const negativeValue = faker.number.int({ min: -1000, max: -1 });
const generatedString = faker.string.sample(negativeValue);
expect(generatedString).toBe('');
expect(generatedString).toHaveLength(0);
});
it('should return string with length of 2^20 if bigger length value is passed', () => {
- const overMaxValue = Math.pow(2, 28);
+ const overMaxValue = 2 ** 28;
const generatedString = faker.string.sample(overMaxValue);
- expect(generatedString).toHaveLength(Math.pow(2, 20));
+ expect(generatedString).toHaveLength(2 ** 20);
});
it('should return string with a specific length', () => {