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): nanoid #1716

Merged
merged 5 commits into from
Jan 9, 2023
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions src/modules/string/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,48 @@ export class StringModule {
return RFC4122_TEMPLATE.replace(/[xy]/g, replacePlaceholders);
}

/**
* Generates a [Nano ID](https://github.com/ai/nanoid).
*
* @param length Length of the generated string. Defaults to `21`.
* @param length.min The minimum length of the Nano ID to generate.
* @param length.max The maximum length of the Nano ID to generate.
*
* @example
* faker.string.nanoid() // ptL0KpX_yRMI98JFr6B3n
* faker.string.nanoid(10) // VsvwSdm_Am
* faker.string.nanoid({ min: 13, max: 37 }) // KIRsdEL9jxVgqhBDlm
*
* @since 8.0.0
*/
nanoid(length: number | { min: number; max: number } = 21): string {
length = this.faker.helpers.rangeToNumber(length);
if (length <= 0) {
return '';
}

const generators = [
{
value: () => this.alphanumeric(1),
// a-z is 26 characters
// this times 2 for upper & lower case is 52
// add all numbers 0-9 (10 in total) you get 62
weight: 62,
},
{
value: () => this.faker.helpers.arrayElement(['_', '-']),
Shinigami92 marked this conversation as resolved.
Show resolved Hide resolved
weight: 2,
},
];
let result = '';
while (result.length < length) {
const charGen = this.faker.helpers.weightedArrayElement(generators);
result += charGen();
}

return result;
}

/**
* Returns a string containing only special characters.
*
Expand Down
42 changes: 42 additions & 0 deletions test/__snapshots__/string.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,20 @@ exports[`string > 42 > hexadecimal > with length range 1`] = `"0xBE4ABdd39321aD"

exports[`string > 42 > hexadecimal > with length, casing and empty prefix 1`] = `"8be4abd"`;

exports[`string > 42 > nanoid > noArgs 1`] = `"NbMBr6sk8E3-W0ZCB01wo"`;

exports[`string > 42 > nanoid > noArgs 2`] = `"2Ye5CnYsRGr0Wyn0eeGBP"`;

exports[`string > 42 > nanoid > noArgs 3`] = `"aobKqcz1-roVJkzwXQKxA"`;

exports[`string > 42 > nanoid > noArgs 4`] = `"XBhia0_oi0cIMBVEUQr5m"`;

exports[`string > 42 > nanoid > noArgs 5`] = `"FFAhynYQIef2I6rcTtyH8"`;

exports[`string > 42 > nanoid > with length parameter 1`] = `"NbMBr6sk8E3-W0ZCB01wo2Ye5CnYsR"`;

exports[`string > 42 > nanoid > with length range 1`] = `"WJB993RBH1YPdb_iwqiB8i"`;

exports[`string > 42 > numeric > noArgs 1`] = `"3"`;

exports[`string > 42 > numeric > with allowLeadingZeros 1`] = `"4"`;
Expand Down Expand Up @@ -226,6 +240,20 @@ exports[`string > 1211 > hexadecimal > with length range 1`] = `"0xaDB42F0e3f4A9

exports[`string > 1211 > hexadecimal > with length, casing and empty prefix 1`] = `"eadb42f"`;

exports[`string > 1211 > nanoid > noArgs 1`] = `"sM8_9dqaK0FJViZZsU9C_"`;

exports[`string > 1211 > nanoid > noArgs 2`] = `"0i1q_zaoUZjAoz4ee2QDc"`;

exports[`string > 1211 > nanoid > noArgs 3`] = `"qApz4EyCu9FHt9xrws3AI"`;

exports[`string > 1211 > nanoid > noArgs 4`] = `"5SxX-57HFuA0KnZgRAyUr"`;

exports[`string > 1211 > nanoid > noArgs 5`] = `"T_mrcROKCRDrUWF5dWr0k"`;

exports[`string > 1211 > nanoid > with length parameter 1`] = `"sM8_9dqaK0FJViZZsU9C_0i1q_zaoU"`;

exports[`string > 1211 > nanoid > with length range 1`] = `"TdZFGLlHOLEPqR-_AcmZLoWxYdiHwl-ngjay"`;

exports[`string > 1211 > numeric > noArgs 1`] = `"9"`;

exports[`string > 1211 > numeric > with allowLeadingZeros 1`] = `"9"`;
Expand Down Expand Up @@ -374,6 +402,20 @@ exports[`string > 1337 > hexadecimal > with length range 1`] = `"0xc346ba075bd5"

exports[`string > 1337 > hexadecimal > with length, casing and empty prefix 1`] = `"5c346ba"`;

exports[`string > 1337 > nanoid > noArgs 1`] = `"ydx2eAk_jN5mJ_RM0snwm"`;

exports[`string > 1337 > nanoid > noArgs 2`] = `"tRpr8OTVCXSOGGPC-spDN"`;

exports[`string > 1337 > nanoid > noArgs 3`] = `"GQLX3wG-xgP-RiBh-hv9G"`;

exports[`string > 1337 > nanoid > noArgs 4`] = `"TxLsFyNSRiYIsFStp3G0m"`;

exports[`string > 1337 > nanoid > noArgs 5`] = `"AtcFYs1gw9vinZNdyEHwk"`;

exports[`string > 1337 > nanoid > with length parameter 1`] = `"ydx2eAk_jN5mJ_RM0snwmtRpr8OTVC"`;

exports[`string > 1337 > nanoid > with length range 1`] = `"9hsjwgYJ7nC7YrMNmpA"`;

exports[`string > 1337 > numeric > noArgs 1`] = `"2"`;

exports[`string > 1337 > numeric > with allowLeadingZeros 1`] = `"3"`;
Expand Down
31 changes: 31 additions & 0 deletions test/string.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ describe('string', () => {

t.itRepeated('uuid', 5);

t.describe('nanoid', (t) => {
t.itRepeated('noArgs', 5)
.it('with length parameter', 30)
.it('with length range', { min: 13, max: 37 });
});

t.describe('special', (t) => {
t.it('noArgs')
.itRepeated('with length parameter', 5, 5)
Expand Down Expand Up @@ -657,6 +663,31 @@ describe('string', () => {
});
});

describe(`nanoid`, () => {
it('generates a valid Nano ID', () => {
const id = faker.string.nanoid();
const regex = /^[0-9a-zA-Z_-]+$/;
expect(id).toMatch(regex);
});

it('should have a default length of 21', () => {
const id = faker.string.nanoid();
expect(id).toHaveLength(21);
});

it('should return an empty string when length is negative', () => {
const id = faker.string.nanoid(-1);
expect(id).toBe('');
});

it('should return string with a length within a given range', () => {
const actual = faker.string.nanoid({ min: 13, max: 37 });

expect(actual.length).toBeGreaterThanOrEqual(13);
expect(actual.length).toBeLessThanOrEqual(37);
});
});

describe('special', () => {
it('should return a value of type string with default length of 1', () => {
const actual = faker.string.special();
Expand Down