Skip to content

Commit d3229fc

Browse files
authored
feat(number): add binary and octal random number generation (#1708)
1 parent 84b3c20 commit d3229fc

File tree

3 files changed

+162
-0
lines changed

3 files changed

+162
-0
lines changed

src/modules/number/index.ts

+58
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,64 @@ export class NumberModule {
114114
return int / factor;
115115
}
116116

117+
/**
118+
* Returns a [binary](https://en.wikipedia.org/wiki/Binary_number) number.
119+
*
120+
* @param options Maximum value or options object. Defaults to `{}`.
121+
* @param options.min Lower bound for generated number. Defaults to `0`.
122+
* @param options.max Upper bound for generated number. Defaults to `1`.
123+
*
124+
* @throws When options define `max < min`.
125+
*
126+
* @example
127+
* faker.number.binary() // '1'
128+
* faker.number.binary(255) // '110101'
129+
* faker.number.binary({ min: 0, max: 65535 }) // '10110101'
130+
*
131+
* @since 8.0.0
132+
*/
133+
binary(options: number | { min?: number; max?: number } = {}): string {
134+
if (typeof options === 'number') {
135+
options = { max: options };
136+
}
137+
138+
const { min = 0, max = 1 } = options;
139+
140+
return this.int({
141+
max,
142+
min,
143+
}).toString(2);
144+
}
145+
146+
/**
147+
* Returns an [octal](https://en.wikipedia.org/wiki/Octal) number.
148+
*
149+
* @param options Maximum value or options object. Defaults to `{}`.
150+
* @param options.min Lower bound for generated number. Defaults to `0`.
151+
* @param options.max Upper bound for generated number. Defaults to `7`.
152+
*
153+
* @throws When options define `max < min`.
154+
*
155+
* @example
156+
* faker.number.octal() // '5'
157+
* faker.number.octal(255) // '377'
158+
* faker.number.octal({ min: 0, max: 65535 }) // '4766'
159+
*
160+
* @since 8.0.0
161+
*/
162+
octal(options: number | { min?: number; max?: number } = {}): string {
163+
if (typeof options === 'number') {
164+
options = { max: options };
165+
}
166+
167+
const { min = 0, max = 7 } = options;
168+
169+
return this.int({
170+
max,
171+
min,
172+
}).toString(8);
173+
}
174+
117175
/**
118176
* Returns a lowercase [hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal) number.
119177
*

test/__snapshots__/number.spec.ts.snap

+36
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ exports[`number > 42 > bigInt > with options 1`] = `1n`;
1414

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

17+
exports[`number > 42 > binary > noArgs 1`] = `"0"`;
18+
19+
exports[`number > 42 > binary > with options 1`] = `"100"`;
20+
21+
exports[`number > 42 > binary > with value 1`] = `"0"`;
22+
1723
exports[`number > 42 > float > with max 1`] = `25.84`;
1824

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

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

45+
exports[`number > 42 > octal > noArgs 1`] = `"2"`;
46+
47+
exports[`number > 42 > octal > with options 1`] = `"4"`;
48+
49+
exports[`number > 42 > octal > with value 1`] = `"0"`;
50+
3951
exports[`number > 1211 > bigInt > noArgs 1`] = `948721906162743n`;
4052

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

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

65+
exports[`number > 1211 > binary > noArgs 1`] = `"1"`;
66+
67+
exports[`number > 1211 > binary > with options 1`] = `"1010"`;
68+
69+
exports[`number > 1211 > binary > with value 1`] = `"1"`;
70+
5371
exports[`number > 1211 > float > with max 1`] = `64.07`;
5472

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

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

93+
exports[`number > 1211 > octal > noArgs 1`] = `"7"`;
94+
95+
exports[`number > 1211 > octal > with options 1`] = `"12"`;
96+
97+
exports[`number > 1211 > octal > with value 1`] = `"1"`;
98+
7599
exports[`number > 1337 > bigInt > noArgs 1`] = `251225403255239n`;
76100

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

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

113+
exports[`number > 1337 > binary > noArgs 1`] = `"0"`;
114+
115+
exports[`number > 1337 > binary > with options 1`] = `"10"`;
116+
117+
exports[`number > 1337 > binary > with value 1`] = `"0"`;
118+
89119
exports[`number > 1337 > float > with max 1`] = `18.08`;
90120

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

109139
exports[`number > 1337 > int > with value 1`] = `0`;
140+
141+
exports[`number > 1337 > octal > noArgs 1`] = `"2"`;
142+
143+
exports[`number > 1337 > octal > with options 1`] = `"2"`;
144+
145+
exports[`number > 1337 > octal > with value 1`] = `"0"`;

test/number.spec.ts

+68
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ describe('number', () => {
1111
seededTests(faker, 'number', (t) => {
1212
t.describeEach(
1313
'int',
14+
'binary',
15+
'octal',
1416
'hex'
1517
)((t) => {
1618
t.it('noArgs')
@@ -240,6 +242,72 @@ describe('number', () => {
240242
});
241243
});
242244

245+
describe('binary', () => {
246+
it('generates single binary character when no additional argument was provided', () => {
247+
const binary = faker.number.binary();
248+
expect(binary).toBeTypeOf('string');
249+
expect(binary).toHaveLength(1);
250+
expect(binary).toMatch(/^[01]$/);
251+
});
252+
253+
it('generates a random binary string with a custom max value', () => {
254+
const binary = faker.number.binary(5);
255+
const binaryNum = parseInt(binary, 2);
256+
expect(binaryNum).toBeLessThanOrEqual(5);
257+
expect(binary).toMatch(/^[01]+$/);
258+
});
259+
260+
it('generates a random binary in a specific range', () => {
261+
const binary = faker.number.binary({ min: 15, max: 255 });
262+
263+
const binaryNum = parseInt(binary, 2);
264+
expect(binaryNum).toBeLessThanOrEqual(255);
265+
expect(binaryNum).greaterThanOrEqual(15);
266+
});
267+
268+
it('should throw when min > max', () => {
269+
const min = 10;
270+
const max = 9;
271+
272+
expect(() => {
273+
faker.number.binary({ min, max });
274+
}).toThrowError(`Max ${max} should be greater than min ${min}.`);
275+
});
276+
});
277+
278+
describe('octal', () => {
279+
it('generates single octal character when no additional argument was provided', () => {
280+
const octal = faker.number.octal();
281+
expect(octal).toBeTypeOf('string');
282+
expect(octal).toHaveLength(1);
283+
expect(octal).toMatch(/^[0-7]$/);
284+
});
285+
286+
it('generates a random octal string with a custom max value', () => {
287+
const octal = faker.number.octal(5);
288+
const octalNum = parseInt(octal, 8);
289+
expect(octalNum).toBeLessThanOrEqual(5);
290+
expect(octal).toMatch(/^[0-7]+$/);
291+
});
292+
293+
it('generates a random octal in a specific range', () => {
294+
const octal = faker.number.octal({ min: 15, max: 255 });
295+
296+
const octalNum = parseInt(octal, 8);
297+
expect(octalNum).toBeLessThanOrEqual(255);
298+
expect(octalNum).greaterThanOrEqual(15);
299+
});
300+
301+
it('should throw when min > max', () => {
302+
const min = 10;
303+
const max = 9;
304+
305+
expect(() => {
306+
faker.number.octal({ min, max });
307+
}).toThrowError(`Max ${max} should be greater than min ${min}.`);
308+
});
309+
});
310+
243311
describe('hex', () => {
244312
it('generates single hex character when no additional argument was provided', () => {
245313
const hex = faker.number.hex();

0 commit comments

Comments
 (0)