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(string): add binary and octal random string generation #1710

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/modules/number/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ export class NumberModule {
*
* @throws When options define `max < min`.
*
* @see faker.string.binary() If you would like to generate a `binary string` with a given length (range).
*
* @example
* faker.number.binary() // '1'
* faker.number.binary(255) // '110101'
Expand Down Expand Up @@ -152,6 +154,8 @@ export class NumberModule {
*
* @throws When options define `max < min`.
*
* @see faker.string.octal() If you would like to generate an `octal string` with a given length (range).
*
* @example
* faker.number.octal() // '5'
* faker.number.octal(255) // '377'
Expand Down
87 changes: 87 additions & 0 deletions src/modules/string/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,93 @@ export class StringModule {
).join('');
}

/**
* Returns a [binary](https://en.wikipedia.org/wiki/Binary_number) string.
*
* @param options The optional options object.
* @param options.length The number or range of characters to generate after the prefix. Defaults to `1`.
* @param options.prefix Prefix for the generated number. Defaults to `'0b'`.
*
* @see faker.number.binary() If you would like to generate a `binary number` (within a range).
*
* @example
* faker.string.binary() // '0b1'
* faker.string.binary({ length: 10 }) // '0b1101011011'
* faker.string.binary({ length: { min: 5, max: 10 } }) // '0b11101011'
* faker.string.binary({ prefix: '0b' }) // '0b1'
* faker.string.binary({ length: 10, prefix: 'bin_' }) // 'bin_1101011011'
*
* @since 8.0.0
*/
binary(
options: {
length?: number | { min: number; max: number };
prefix?: string;
} = {}
): string {
const { prefix = '0b' } = options;
const length = this.faker.helpers.rangeToNumber(options.length ?? 1);
if (length <= 0) {
return prefix;
}

let binaryString = '';

for (let i = 0; i < length; i++) {
binaryString += this.faker.helpers.arrayElement(['0', '1']);
}

return `${prefix}${binaryString}`;
}

/**
* Returns an [octal](https://en.wikipedia.org/wiki/Octal) string.
*
* @param options The optional options object.
* @param options.length The number or range of characters to generate after the prefix. Defaults to `1`.
* @param options.prefix Prefix for the generated number. Defaults to `'0o'`.
*
* @see faker.number.octal() If you would like to generate an `octal number` (within a range).
*
* @example
* faker.string.octal() // '0o3'
* faker.string.octal({ length: 10 }) // '0o1526216210'
* faker.string.octal({ length: { min: 5, max: 10 } }) // '0o15263214'
* faker.string.octal({ prefix: '0o' }) // '0o7'
* faker.string.octal({ length: 10, prefix: 'oct_' }) // 'oct_1542153414'
*
* @since 8.0.0
*/
octal(
options: {
length?: number | { min: number; max: number };
prefix?: string;
} = {}
): string {
const { prefix = '0o' } = options;
const length = this.faker.helpers.rangeToNumber(options.length ?? 1);
if (length <= 0) {
return prefix;
}

let octalString = '';

for (let i = 0; i < length; i++) {
octalString += this.faker.helpers.arrayElement([
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
]);
}

return `${prefix}${octalString}`;
}

/**
* Returns a [hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal) string.
*
Expand Down
60 changes: 60 additions & 0 deletions test/__snapshots__/string.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ exports[`string > 42 > alphanumeric > with length range 1`] = `"NWbJMBB9r963sR"`

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

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

exports[`string > 42 > binary > with custom prefix 1`] = `"bin_0"`;

exports[`string > 42 > binary > with length 1`] = `"0b011011"`;

exports[`string > 42 > binary > with length and empty prefix 1`] = `"0110111"`;

exports[`string > 42 > binary > with length range 1`] = `"0b11011110000001"`;

exports[`string > 42 > hexadecimal > noArgs 1`] = `"0x8"`;

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

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

exports[`string > 42 > octal > noArgs 1`] = `"0o2"`;

exports[`string > 42 > octal > with custom prefix 1`] = `"oct_2"`;

exports[`string > 42 > octal > with length 1`] = `"0o267156"`;

exports[`string > 42 > octal > with length and empty prefix 1`] = `"2671564"`;

exports[`string > 42 > octal > with length range 1`] = `"0o67156441310036"`;

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

exports[`string > 42 > sample > with length parameter 1`] = `"Cky2e"`;
Expand Down Expand Up @@ -180,6 +200,16 @@ exports[`string > 1211 > alphanumeric > with length range 1`] = `"sTMd8Z2F9GdLql

exports[`string > 1211 > alphanumeric > with length, casing and exclude 1`] = `"yexv53z"`;

exports[`string > 1211 > binary > noArgs 1`] = `"0b1"`;

exports[`string > 1211 > binary > with custom prefix 1`] = `"bin_1"`;

exports[`string > 1211 > binary > with length 1`] = `"0b101100"`;

exports[`string > 1211 > binary > with length and empty prefix 1`] = `"1011001"`;

exports[`string > 1211 > binary > with length range 1`] = `"0b01100101010100011101"`;

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

exports[`string > 1211 > hexadecimal > with casing = lower 1`] = `"0xe"`;
Expand Down Expand Up @@ -218,6 +248,16 @@ exports[`string > 1211 > numeric > with length range 1`] = `"4872190616274316780

exports[`string > 1211 > numeric > with length, allowLeadingZeros and exclude 1`] = `"9798609"`;

exports[`string > 1211 > octal > noArgs 1`] = `"0o7"`;

exports[`string > 1211 > octal > with custom prefix 1`] = `"oct_7"`;

exports[`string > 1211 > octal > with length 1`] = `"0o737611"`;

exports[`string > 1211 > octal > with length and empty prefix 1`] = `"7376117"`;

exports[`string > 1211 > octal > with length range 1`] = `"0o37611705151632155606"`;

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

exports[`string > 1211 > sample > with length parameter 1`] = `"wKti5"`;
Expand Down Expand Up @@ -308,6 +348,16 @@ exports[`string > 1337 > alphanumeric > with length range 1`] = `"y9dhxs2jewAg"`

exports[`string > 1337 > alphanumeric > with length, casing and exclude 1`] = `"ag45age"`;

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

exports[`string > 1337 > binary > with custom prefix 1`] = `"bin_0"`;

exports[`string > 1337 > binary > with length 1`] = `"0b010001"`;

exports[`string > 1337 > binary > with length and empty prefix 1`] = `"0100010"`;

exports[`string > 1337 > binary > with length range 1`] = `"0b100010000110"`;

exports[`string > 1337 > hexadecimal > noArgs 1`] = `"0x5"`;

exports[`string > 1337 > hexadecimal > with casing = lower 1`] = `"0x5"`;
Expand Down Expand Up @@ -346,6 +396,16 @@ exports[`string > 1337 > numeric > with length range 1`] = `"512254032552"`;

exports[`string > 1337 > numeric > with length, allowLeadingZeros and exclude 1`] = `"6706677"`;

exports[`string > 1337 > octal > noArgs 1`] = `"0o2"`;

exports[`string > 1337 > octal > with custom prefix 1`] = `"oct_2"`;

exports[`string > 1337 > octal > with length 1`] = `"0o241124"`;

exports[`string > 1337 > octal > with length and empty prefix 1`] = `"2411243"`;

exports[`string > 1337 > octal > with length range 1`] = `"0o411243021442"`;

exports[`string > 1337 > sample > noArgs 1`] = `"9U/4:SK$>6"`;

exports[`string > 1337 > sample > with length parameter 1`] = `"9U/4:"`;
Expand Down
100 changes: 100 additions & 0 deletions test/string.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,28 @@ describe('string', () => {
});
});

t.describe('binary', (t) => {
t.it('noArgs')
.it('with length', { length: 6 })
.it('with length range', { length: { min: 10, max: 20 } })
.it('with custom prefix', { prefix: 'bin_' })
.it('with length and empty prefix', {
length: 7,
prefix: '',
});
});

t.describe('octal', (t) => {
t.it('noArgs')
.it('with length', { length: 6 })
.it('with length range', { length: { min: 10, max: 20 } })
.it('with custom prefix', { prefix: 'oct_' })
.it('with length and empty prefix', {
length: 7,
prefix: '',
});
});

t.describe('hexadecimal', (t) => {
t.it('noArgs')
.it('with length', { length: 6 })
Expand Down Expand Up @@ -344,6 +366,84 @@ describe('string', () => {
});
});

describe(`binary`, () => {
it('generates a single binary character when no additional argument was provided', () => {
const binary = faker.string.binary();
expect(binary).toMatch(/^0b[01]$/i);
expect(binary).toHaveLength(3);
});

it('generates a random binary string with fixed length and no prefix', () => {
const binary = faker.string.binary({
length: 5,
prefix: '',
});
expect(binary).toMatch(/^[01]*$/i);
expect(binary).toHaveLength(5);
});

it.each([0, -1, -100])(
'should return the prefix when length is <= 0',
(length) => {
const binary = faker.string.binary({ length });

expect(binary).toBe('0b');
}
);

it('should return a binary string with a random amount of characters and no prefix', () => {
const binary = faker.string.binary({
length: { min: 10, max: 20 },
prefix: '',
});

expect(binary).toBeDefined();
expect(binary).toBeTypeOf('string');

expect(binary.length).toBeGreaterThanOrEqual(10);
expect(binary.length).toBeLessThanOrEqual(20);
});
});

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

it('generates a random octal string with fixed length and no prefix', () => {
const octal = faker.string.octal({
length: 5,
prefix: '',
});
expect(octal).toMatch(/^[0-7]*$/i);
expect(octal).toHaveLength(5);
});

it.each([0, -1, -100])(
'should return the prefix when length is <= 0',
(length) => {
const octal = faker.string.octal({ length });

expect(octal).toBe('0o');
}
);

it('should return an octal string with a random amount of characters and no prefix', () => {
const octal = faker.string.octal({
length: { min: 10, max: 20 },
prefix: '',
});

expect(octal).toBeDefined();
expect(octal).toBeTypeOf('string');

expect(octal.length).toBeGreaterThanOrEqual(10);
expect(octal.length).toBeLessThanOrEqual(20);
});
});

describe(`hexadecimal`, () => {
it('generates single hex character when no additional argument was provided', () => {
const hex = faker.string.hexadecimal();
Expand Down