Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat(number): add binary and octal random number generation #1708

Merged
58 changes: 58 additions & 0 deletions src/modules/number/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,64 @@ export class NumberModule {
return int / factor;
}

/**
* Returns a [binary](https://en.wikipedia.org/wiki/Binary_number) 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 `1`.
*
* @throws When options define `max < min`.
*
* @example
* faker.number.binary() // '1'
* faker.number.binary(255) // '110101'
* faker.number.binary({ min: 0, max: 65535 }) // '10110101'
*
* @since 8.0.0
*/
binary(options: number | { min?: number; max?: number } = {}): string {
if (typeof options === 'number') {
options = { max: options };
}

const { min = 0, max = 1 } = options;

return this.int({
max,
min,
}).toString(2);
}

/**
* Returns an [octal](https://en.wikipedia.org/wiki/Octal) 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 `7`.
*
* @throws When options define `max < min`.
*
* @example
* faker.number.octal() // '5'
* faker.number.octal(255) // '377'
* faker.number.octal({ min: 0, max: 65535 }) // '4766'
*
* @since 8.0.0
*/
octal(options: number | { min?: number; max?: number } = {}): string {
if (typeof options === 'number') {
options = { max: options };
}

const { min = 0, max = 7 } = options;

return this.int({
max,
min,
}).toString(8);
}

/**
* Returns a lowercase [hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal) number.
*
Expand Down
36 changes: 36 additions & 0 deletions test/__snapshots__/number.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ exports[`number > 42 > bigInt > with options 1`] = `1n`;

exports[`number > 42 > bigInt > with string value 1`] = `37n`;

exports[`number > 42 > binary > noArgs 1`] = `"0"`;

exports[`number > 42 > binary > with options 1`] = `"100"`;

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

exports[`number > 42 > float > with max 1`] = `25.84`;

exports[`number > 42 > float > with min 1`] = `-25.9`;
Expand All @@ -36,6 +42,12 @@ exports[`number > 42 > int > with options 1`] = `4`;

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

exports[`number > 42 > octal > noArgs 1`] = `"2"`;

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

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

exports[`number > 1211 > bigInt > noArgs 1`] = `948721906162743n`;

exports[`number > 1211 > bigInt > with big options 1`] = `22017767508700414061739128n`;
Expand All @@ -50,6 +62,12 @@ exports[`number > 1211 > bigInt > with options 1`] = `10n`;

exports[`number > 1211 > bigInt > with string value 1`] = `24n`;

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

exports[`number > 1211 > binary > with options 1`] = `"1010"`;

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

exports[`number > 1211 > float > with max 1`] = `64.07`;

exports[`number > 1211 > float > with min 1`] = `-2.07`;
Expand All @@ -72,6 +90,12 @@ exports[`number > 1211 > int > with options 1`] = `10`;

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

exports[`number > 1211 > octal > noArgs 1`] = `"7"`;

exports[`number > 1211 > octal > with options 1`] = `"12"`;

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

exports[`number > 1337 > bigInt > noArgs 1`] = `251225403255239n`;

exports[`number > 1337 > bigInt > with big options 1`] = `31258255497061442772623668n`;
Expand All @@ -86,6 +110,12 @@ exports[`number > 1337 > bigInt > with options 1`] = `-15n`;

exports[`number > 1337 > bigInt > with string value 1`] = `25n`;

exports[`number > 1337 > binary > noArgs 1`] = `"0"`;

exports[`number > 1337 > binary > with options 1`] = `"10"`;

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

exports[`number > 1337 > float > with max 1`] = `18.08`;

exports[`number > 1337 > float > with min 1`] = `-30.74`;
Expand All @@ -107,3 +137,9 @@ exports[`number > 1337 > int > noArgs 1`] = `2360108468142080`;
exports[`number > 1337 > int > with options 1`] = `2`;

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

exports[`number > 1337 > octal > noArgs 1`] = `"2"`;

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

exports[`number > 1337 > octal > with value 1`] = `"0"`;
68 changes: 68 additions & 0 deletions test/number.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ describe('number', () => {
seededTests(faker, 'number', (t) => {
t.describeEach(
'int',
'binary',
'octal',
'hex'
)((t) => {
t.it('noArgs')
Expand Down Expand Up @@ -240,6 +242,72 @@ describe('number', () => {
});
});

describe('binary', () => {
it('generates single binary character when no additional argument was provided', () => {
const binary = faker.number.binary();
expect(binary).toBeTypeOf('string');
expect(binary).toHaveLength(1);
expect(binary).toMatch(/^[01]$/);
});

it('generates a random binary string with a custom max value', () => {
const binary = faker.number.binary(5);
const binaryNum = parseInt(binary, 2);
expect(binaryNum).toBeLessThanOrEqual(5);
expect(binary).toMatch(/^[01]+$/);
});

it('generates a random binary in a specific range', () => {
const binary = faker.number.binary({ min: 15, max: 255 });

const binaryNum = parseInt(binary, 2);
expect(binaryNum).toBeLessThanOrEqual(255);
expect(binaryNum).greaterThanOrEqual(15);
});

it('should throw when min > max', () => {
const min = 10;
const max = 9;

expect(() => {
faker.number.binary({ min, max });
}).toThrowError(`Max ${max} should be greater than min ${min}.`);
});
});

describe('octal', () => {
it('generates single octal character when no additional argument was provided', () => {
const octal = faker.number.octal();
expect(octal).toBeTypeOf('string');
expect(octal).toHaveLength(1);
expect(octal).toMatch(/^[0-7]$/);
});

it('generates a random octal string with a custom max value', () => {
const octal = faker.number.octal(5);
const octalNum = parseInt(octal, 8);
expect(octalNum).toBeLessThanOrEqual(5);
expect(octal).toMatch(/^[0-7]+$/);
});

it('generates a random octal in a specific range', () => {
const octal = faker.number.octal({ min: 15, max: 255 });

const octalNum = parseInt(octal, 8);
expect(octalNum).toBeLessThanOrEqual(255);
expect(octalNum).greaterThanOrEqual(15);
});

it('should throw when min > max', () => {
const min = 10;
const max = 9;

expect(() => {
faker.number.octal({ 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();
Expand Down