Skip to content

Commit 80e0a96

Browse files
authored
feat(string): add binary and octal random string generation (#1710)
1 parent d3229fc commit 80e0a96

File tree

4 files changed

+251
-0
lines changed

4 files changed

+251
-0
lines changed

src/modules/number/index.ts

+4
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ export class NumberModule {
123123
*
124124
* @throws When options define `max < min`.
125125
*
126+
* @see faker.string.binary() If you would like to generate a `binary string` with a given length (range).
127+
*
126128
* @example
127129
* faker.number.binary() // '1'
128130
* faker.number.binary(255) // '110101'
@@ -152,6 +154,8 @@ export class NumberModule {
152154
*
153155
* @throws When options define `max < min`.
154156
*
157+
* @see faker.string.octal() If you would like to generate an `octal string` with a given length (range).
158+
*
155159
* @example
156160
* faker.number.octal() // '5'
157161
* faker.number.octal(255) // '377'

src/modules/string/index.ts

+87
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,93 @@ export class StringModule {
241241
).join('');
242242
}
243243

244+
/**
245+
* Returns a [binary](https://en.wikipedia.org/wiki/Binary_number) string.
246+
*
247+
* @param options The optional options object.
248+
* @param options.length The number or range of characters to generate after the prefix. Defaults to `1`.
249+
* @param options.prefix Prefix for the generated number. Defaults to `'0b'`.
250+
*
251+
* @see faker.number.binary() If you would like to generate a `binary number` (within a range).
252+
*
253+
* @example
254+
* faker.string.binary() // '0b1'
255+
* faker.string.binary({ length: 10 }) // '0b1101011011'
256+
* faker.string.binary({ length: { min: 5, max: 10 } }) // '0b11101011'
257+
* faker.string.binary({ prefix: '0b' }) // '0b1'
258+
* faker.string.binary({ length: 10, prefix: 'bin_' }) // 'bin_1101011011'
259+
*
260+
* @since 8.0.0
261+
*/
262+
binary(
263+
options: {
264+
length?: number | { min: number; max: number };
265+
prefix?: string;
266+
} = {}
267+
): string {
268+
const { prefix = '0b' } = options;
269+
const length = this.faker.helpers.rangeToNumber(options.length ?? 1);
270+
if (length <= 0) {
271+
return prefix;
272+
}
273+
274+
let binaryString = '';
275+
276+
for (let i = 0; i < length; i++) {
277+
binaryString += this.faker.helpers.arrayElement(['0', '1']);
278+
}
279+
280+
return `${prefix}${binaryString}`;
281+
}
282+
283+
/**
284+
* Returns an [octal](https://en.wikipedia.org/wiki/Octal) string.
285+
*
286+
* @param options The optional options object.
287+
* @param options.length The number or range of characters to generate after the prefix. Defaults to `1`.
288+
* @param options.prefix Prefix for the generated number. Defaults to `'0o'`.
289+
*
290+
* @see faker.number.octal() If you would like to generate an `octal number` (within a range).
291+
*
292+
* @example
293+
* faker.string.octal() // '0o3'
294+
* faker.string.octal({ length: 10 }) // '0o1526216210'
295+
* faker.string.octal({ length: { min: 5, max: 10 } }) // '0o15263214'
296+
* faker.string.octal({ prefix: '0o' }) // '0o7'
297+
* faker.string.octal({ length: 10, prefix: 'oct_' }) // 'oct_1542153414'
298+
*
299+
* @since 8.0.0
300+
*/
301+
octal(
302+
options: {
303+
length?: number | { min: number; max: number };
304+
prefix?: string;
305+
} = {}
306+
): string {
307+
const { prefix = '0o' } = options;
308+
const length = this.faker.helpers.rangeToNumber(options.length ?? 1);
309+
if (length <= 0) {
310+
return prefix;
311+
}
312+
313+
let octalString = '';
314+
315+
for (let i = 0; i < length; i++) {
316+
octalString += this.faker.helpers.arrayElement([
317+
'0',
318+
'1',
319+
'2',
320+
'3',
321+
'4',
322+
'5',
323+
'6',
324+
'7',
325+
]);
326+
}
327+
328+
return `${prefix}${octalString}`;
329+
}
330+
244331
/**
245332
* Returns a [hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal) string.
246333
*

test/__snapshots__/string.spec.ts.snap

+60
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@ exports[`string > 42 > alphanumeric > with length range 1`] = `"NWbJMBB9r963sR"`
5252

5353
exports[`string > 42 > alphanumeric > with length, casing and exclude 1`] = `"cvy4kvh"`;
5454

55+
exports[`string > 42 > binary > noArgs 1`] = `"0b0"`;
56+
57+
exports[`string > 42 > binary > with custom prefix 1`] = `"bin_0"`;
58+
59+
exports[`string > 42 > binary > with length 1`] = `"0b011011"`;
60+
61+
exports[`string > 42 > binary > with length and empty prefix 1`] = `"0110111"`;
62+
63+
exports[`string > 42 > binary > with length range 1`] = `"0b11011110000001"`;
64+
5565
exports[`string > 42 > hexadecimal > noArgs 1`] = `"0x8"`;
5666

5767
exports[`string > 42 > hexadecimal > with casing = lower 1`] = `"0x8"`;
@@ -90,6 +100,16 @@ exports[`string > 42 > numeric > with length range 1`] = `"79177551410048"`;
90100

91101
exports[`string > 42 > numeric > with length, allowLeadingZeros and exclude 1`] = `"6890887"`;
92102

103+
exports[`string > 42 > octal > noArgs 1`] = `"0o2"`;
104+
105+
exports[`string > 42 > octal > with custom prefix 1`] = `"oct_2"`;
106+
107+
exports[`string > 42 > octal > with length 1`] = `"0o267156"`;
108+
109+
exports[`string > 42 > octal > with length and empty prefix 1`] = `"2671564"`;
110+
111+
exports[`string > 42 > octal > with length range 1`] = `"0o67156441310036"`;
112+
93113
exports[`string > 42 > sample > noArgs 1`] = `"Cky2eiXX/J"`;
94114

95115
exports[`string > 42 > sample > with length parameter 1`] = `"Cky2e"`;
@@ -180,6 +200,16 @@ exports[`string > 1211 > alphanumeric > with length range 1`] = `"sTMd8Z2F9GdLql
180200
181201
exports[`string > 1211 > alphanumeric > with length, casing and exclude 1`] = `"yexv53z"`;
182202
203+
exports[`string > 1211 > binary > noArgs 1`] = `"0b1"`;
204+
205+
exports[`string > 1211 > binary > with custom prefix 1`] = `"bin_1"`;
206+
207+
exports[`string > 1211 > binary > with length 1`] = `"0b101100"`;
208+
209+
exports[`string > 1211 > binary > with length and empty prefix 1`] = `"1011001"`;
210+
211+
exports[`string > 1211 > binary > with length range 1`] = `"0b01100101010100011101"`;
212+
183213
exports[`string > 1211 > hexadecimal > noArgs 1`] = `"0xE"`;
184214
185215
exports[`string > 1211 > hexadecimal > with casing = lower 1`] = `"0xe"`;
@@ -218,6 +248,16 @@ exports[`string > 1211 > numeric > with length range 1`] = `"4872190616274316780
218248
219249
exports[`string > 1211 > numeric > with length, allowLeadingZeros and exclude 1`] = `"9798609"`;
220250
251+
exports[`string > 1211 > octal > noArgs 1`] = `"0o7"`;
252+
253+
exports[`string > 1211 > octal > with custom prefix 1`] = `"oct_7"`;
254+
255+
exports[`string > 1211 > octal > with length 1`] = `"0o737611"`;
256+
257+
exports[`string > 1211 > octal > with length and empty prefix 1`] = `"7376117"`;
258+
259+
exports[`string > 1211 > octal > with length range 1`] = `"0o37611705151632155606"`;
260+
221261
exports[`string > 1211 > sample > noArgs 1`] = `"wKti5-}$_/"`;
222262
223263
exports[`string > 1211 > sample > with length parameter 1`] = `"wKti5"`;
@@ -308,6 +348,16 @@ exports[`string > 1337 > alphanumeric > with length range 1`] = `"y9dhxs2jewAg"`
308348
309349
exports[`string > 1337 > alphanumeric > with length, casing and exclude 1`] = `"ag45age"`;
310350
351+
exports[`string > 1337 > binary > noArgs 1`] = `"0b0"`;
352+
353+
exports[`string > 1337 > binary > with custom prefix 1`] = `"bin_0"`;
354+
355+
exports[`string > 1337 > binary > with length 1`] = `"0b010001"`;
356+
357+
exports[`string > 1337 > binary > with length and empty prefix 1`] = `"0100010"`;
358+
359+
exports[`string > 1337 > binary > with length range 1`] = `"0b100010000110"`;
360+
311361
exports[`string > 1337 > hexadecimal > noArgs 1`] = `"0x5"`;
312362
313363
exports[`string > 1337 > hexadecimal > with casing = lower 1`] = `"0x5"`;
@@ -346,6 +396,16 @@ exports[`string > 1337 > numeric > with length range 1`] = `"512254032552"`;
346396
347397
exports[`string > 1337 > numeric > with length, allowLeadingZeros and exclude 1`] = `"6706677"`;
348398
399+
exports[`string > 1337 > octal > noArgs 1`] = `"0o2"`;
400+
401+
exports[`string > 1337 > octal > with custom prefix 1`] = `"oct_2"`;
402+
403+
exports[`string > 1337 > octal > with length 1`] = `"0o241124"`;
404+
405+
exports[`string > 1337 > octal > with length and empty prefix 1`] = `"2411243"`;
406+
407+
exports[`string > 1337 > octal > with length range 1`] = `"0o411243021442"`;
408+
349409
exports[`string > 1337 > sample > noArgs 1`] = `"9U/4:SK$>6"`;
350410
351411
exports[`string > 1337 > sample > with length parameter 1`] = `"9U/4:"`;

test/string.spec.ts

+100
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,28 @@ describe('string', () => {
3939
});
4040
});
4141

42+
t.describe('binary', (t) => {
43+
t.it('noArgs')
44+
.it('with length', { length: 6 })
45+
.it('with length range', { length: { min: 10, max: 20 } })
46+
.it('with custom prefix', { prefix: 'bin_' })
47+
.it('with length and empty prefix', {
48+
length: 7,
49+
prefix: '',
50+
});
51+
});
52+
53+
t.describe('octal', (t) => {
54+
t.it('noArgs')
55+
.it('with length', { length: 6 })
56+
.it('with length range', { length: { min: 10, max: 20 } })
57+
.it('with custom prefix', { prefix: 'oct_' })
58+
.it('with length and empty prefix', {
59+
length: 7,
60+
prefix: '',
61+
});
62+
});
63+
4264
t.describe('hexadecimal', (t) => {
4365
t.it('noArgs')
4466
.it('with length', { length: 6 })
@@ -344,6 +366,84 @@ describe('string', () => {
344366
});
345367
});
346368

369+
describe(`binary`, () => {
370+
it('generates a single binary character when no additional argument was provided', () => {
371+
const binary = faker.string.binary();
372+
expect(binary).toMatch(/^0b[01]$/i);
373+
expect(binary).toHaveLength(3);
374+
});
375+
376+
it('generates a random binary string with fixed length and no prefix', () => {
377+
const binary = faker.string.binary({
378+
length: 5,
379+
prefix: '',
380+
});
381+
expect(binary).toMatch(/^[01]*$/i);
382+
expect(binary).toHaveLength(5);
383+
});
384+
385+
it.each([0, -1, -100])(
386+
'should return the prefix when length is <= 0',
387+
(length) => {
388+
const binary = faker.string.binary({ length });
389+
390+
expect(binary).toBe('0b');
391+
}
392+
);
393+
394+
it('should return a binary string with a random amount of characters and no prefix', () => {
395+
const binary = faker.string.binary({
396+
length: { min: 10, max: 20 },
397+
prefix: '',
398+
});
399+
400+
expect(binary).toBeDefined();
401+
expect(binary).toBeTypeOf('string');
402+
403+
expect(binary.length).toBeGreaterThanOrEqual(10);
404+
expect(binary.length).toBeLessThanOrEqual(20);
405+
});
406+
});
407+
408+
describe(`octal`, () => {
409+
it('generates single octal character when no additional argument was provided', () => {
410+
const octal = faker.string.octal();
411+
expect(octal).toMatch(/^0o[0-7]$/i);
412+
expect(octal).toHaveLength(3);
413+
});
414+
415+
it('generates a random octal string with fixed length and no prefix', () => {
416+
const octal = faker.string.octal({
417+
length: 5,
418+
prefix: '',
419+
});
420+
expect(octal).toMatch(/^[0-7]*$/i);
421+
expect(octal).toHaveLength(5);
422+
});
423+
424+
it.each([0, -1, -100])(
425+
'should return the prefix when length is <= 0',
426+
(length) => {
427+
const octal = faker.string.octal({ length });
428+
429+
expect(octal).toBe('0o');
430+
}
431+
);
432+
433+
it('should return an octal string with a random amount of characters and no prefix', () => {
434+
const octal = faker.string.octal({
435+
length: { min: 10, max: 20 },
436+
prefix: '',
437+
});
438+
439+
expect(octal).toBeDefined();
440+
expect(octal).toBeTypeOf('string');
441+
442+
expect(octal.length).toBeGreaterThanOrEqual(10);
443+
expect(octal.length).toBeLessThanOrEqual(20);
444+
});
445+
});
446+
347447
describe(`hexadecimal`, () => {
348448
it('generates single hex character when no additional argument was provided', () => {
349449
const hex = faker.string.hexadecimal();

0 commit comments

Comments
 (0)