Skip to content

Commit

Permalink
fix(typing): randSequence (#388)
Browse files Browse the repository at this point in the history
* fix(typing): randSequence

* fix: failed pipeline

* fix: failed pipeline

* fix: failed UTs
  • Loading branch information
kobenguyent authored Jan 7, 2025
1 parent e89b27b commit 6f1919f
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 62 deletions.
60 changes: 43 additions & 17 deletions packages/falso/src/lib/sequence.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { fake, FakeOptions, Return } from './core/core';
import { FakeOptions, Return } from './core/core';
import { random } from './random';

export const numericChars = '0123456789';
Expand All @@ -15,16 +15,32 @@ function generator(size = 8, chars = numericAlphaChars) {
return result;
}

type CharTypes = 'numeric' | 'alpha' | 'alphaNumeric' | 'special';

type RandomSequenceOptions = {
size?: number;
chars?: string;
} & FakeOptions;

type RandomSequenceOptions2 = {
size?: number;
charType?: 'numeric' | 'alpha' | 'alphaNumeric' | 'special';
charType?: CharTypes;
chars?: string;
} & FakeOptions;

// Helper type to determine the return type based on `charType`
type ReturnTypeFromCharType<CharType extends CharTypes | undefined> =
CharType extends 'numeric' | 'alpha' | 'alphaNumeric' | 'special'
? string
: string[];

/**
* Simulating the `fake` function.
*/
function fake<T>(generatorFn: () => T, options?: any): T {
return generatorFn(); // Assuming `fake` returns the value produced by generatorFn
}

/**
* Generate a random sequence.
*
Expand All @@ -44,22 +60,16 @@ type RandomSequenceOptions2 = {
*
* @example
*
* randSequence({ charType: 'numeric' }) // numeric | alpha | alphaNumeric | special
* randSequence({ charType: 'numeric' })
*
* @example
*
* randSequence({ length: 10 })
*
*/
export function randSequence<Options extends RandomSequenceOptions = never>(
options?: RandomSequenceOptions
): Return<string, Options>;
export function randSequence<Options extends RandomSequenceOptions2 = never>(
options?: RandomSequenceOptions2
): Return<string, Options>;
export function randSequence<
Options extends RandomSequenceOptions & RandomSequenceOptions2 = never
>(options?: Options) {
options?: Options
): Return<ReturnTypeFromCharType<Options['charType']>, Options> {
if (options?.charType && !options?.chars) {
switch (options.charType) {
case 'alpha':
Expand All @@ -70,21 +80,37 @@ export function randSequence<
`${alphaChars}${alphaChars.toUpperCase()}`
),
options
);
) as Return<ReturnTypeFromCharType<Options['charType']>, Options>;
case 'alphaNumeric':
return fake(() => generator(options?.size, numericAlphaChars), options);
return fake(
() => generator(options?.size, numericAlphaChars),
options
) as Return<ReturnTypeFromCharType<Options['charType']>, Options>;
case 'numeric':
return fake(() => generator(options?.size, numericChars), options);
return fake(
() => generator(options?.size, numericChars),
options
) as Return<ReturnTypeFromCharType<Options['charType']>, Options>;
case 'special':
return fake(() => generator(options?.size, specialChars), options);
return fake(
() => generator(options?.size, specialChars),
options
) as Return<ReturnTypeFromCharType<Options['charType']>, Options>;
default:
return neverChecker(options.charType);
}
} else {
return fake(() => generator(options?.size, options?.chars), options);
const result = fake(
() => generator(options?.size, options?.chars),
options
);
return result as Return<
ReturnTypeFromCharType<Options['charType']>,
Options
>;
}
}

function neverChecker(value: never) {
function neverChecker(value: never): never {
throw new Error(`Invalid charType: ${value}`);
}
105 changes: 60 additions & 45 deletions packages/falso/src/tests/sequence.spec.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,80 @@
import { randSequence } from '../lib/sequence';

describe('randSequence', () => {
const numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
const letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
const specials = '<>@!#$%^&*()_+[]{}?:;|\'"\\,./~`-=';
const letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
const specials = '<>@!#$%^&*()_+[]{}?:;|\'"\\,./~`-=';

it('should create one sequence', () => {
expect(typeof randSequence()).toBe('string');
expect(randSequence().length).toBe(8);
describe('randSequence', () => {
// Test Default Behavior
it('should generate a string of default length 8 with default chars', () => {
const result = randSequence();
expect(result).toHaveLength(8); // Default length should be 8
expect(typeof result).toBe('string'); // Result should be a string
});

it('should create array of sequences', () => {
const result = randSequence({ length: 10 });

expect(Array.isArray(result)).toBe(true);
expect(result.length).toBe(10);
expect(result[0].length).toBe(8);
expect(result[0]).not.toEqual(result[1]);
// Test with 'numeric' charType
it('should generate a string with numeric characters when charType is "numeric"', () => {
const result = randSequence({ charType: 'numeric' });
expect(result).toHaveLength(8); // Default size
expect(result).toMatch(/^\d+$/); // Result should only contain digits
});

it('should create one sequence with char pattern', () => {
const result = randSequence({ chars: 'ABCD', size: 10 });

expect(typeof result).toBe('string');
expect(result.length).toBe(10);
expect(result.split('').some((char) => letters.includes(char))).toBe(true);
// Test with 'alpha' charType
it('should generate a string with alphabetic characters when charType is "alpha"', () => {
const result = randSequence({ charType: 'alpha' });
expect(result).toHaveLength(8); // Default size
expect(result).toMatch(/^[a-zA-Z]+$/); // Result should only contain alphabetic characters
});

it('should create sequence with charType: alpha', () => {
const result = randSequence({ charType: 'alpha', size: 10 });

expect(result.length).toBe(10);
expect(typeof result).toBe('string');
expect(
result.split('').some((char) => numbers.includes(parseInt(char)))
).toBe(false);
// Test with 'alphaNumeric' charType
it('should generate a string with alphanumeric characters when charType is "alphaNumeric"', () => {
const result = randSequence({ charType: 'alphaNumeric' });
expect(result).toHaveLength(8); // Default size
expect(result).toMatch(/^[a-zA-Z0-9]+$/); // Result should only contain alphanumeric characters
});

it('should create sequence with charType: alphaNumeric', () => {
const result = randSequence({ charType: 'alphaNumeric' });
// Test with 'special' charType
it('should generate a string with special characters when charType is "special"', () => {
const result = randSequence({ charType: 'special' });
expect(result).toHaveLength(8); // Default size
expect(result.split('').some((char) => letters.includes(char))).toBe(false);
expect(result.split('').every((char) => specials.includes(char))).toBe(
true
);
});

expect(result.length).toBe(8);
expect(typeof result).toBe('string');
// Test with custom 'chars' value
it('should generate a string based on custom chars', () => {
const result = randSequence({ chars: 'abcd1234' });
expect(result).toHaveLength(8); // Default size
expect(result).toMatch(/^[abcd1234]+$/); // Result should only contain characters from the custom string
});

it('should create sequence with charType: numeric', () => {
const result = randSequence({ charType: 'numeric' });
// Test for Invalid `charType`
it('should throw an error for invalid charType', () => {
// Use a try-catch to check if the error is thrown
expect(() => randSequence({ charType: 'invalidType' as any })).toThrow(
'Invalid charType: invalidType'
);
});

expect(result.length).toBe(8);
expect(typeof result).toBe('string');
expect(result.split('').some((char) => letters.includes(char))).toBe(false);
// Test with custom size
it('should generate a string of custom length when size is provided', () => {
const result = randSequence({ size: 12 });
expect(result).toHaveLength(12); // Custom size
expect(typeof result).toBe('string'); // Result should be a string
});

it('should create sequence with charType: special', () => {
const result = randSequence({ charType: 'special' });
// Test with custom size and 'numeric' charType
it('should generate a numeric string of custom length', () => {
const result = randSequence({ size: 10, charType: 'numeric' });
expect(result).toHaveLength(10); // Custom size
expect(result).toMatch(/^\d+$/); // Result should only contain digits
});

expect(result.length).toBe(8);
expect(typeof result).toBe('string');
expect(result.split('').some((char) => letters.includes(char))).toBe(false);
expect(result.split('').every((char) => specials.includes(char))).toBe(
true
);
// Test with custom size and 'alpha' charType
it('should generate an alphabetic string of custom length', () => {
const result = randSequence({ size: 6, charType: 'alpha' });
expect(result).toHaveLength(6); // Custom size
expect(result).toMatch(/^[a-zA-Z]+$/); // Result should only contain alphabetic characters
});
});

0 comments on commit 6f1919f

Please sign in to comment.