All files / json-random/src string.ts

95.83% Statements 23/24
85.71% Branches 6/7
100% Functions 1/1
95% Lines 19/20

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69                                                                        4x 30254x 27563x 27563x   809x 809x     244x 244x 244x 26267x 244x     26286x 26286x 26286x 26574x 26574x   26286x     224x 224x            
/**
 * Tokens used to specify random string generation options
 */
export type Token = TokenLiteral | TokenPick | TokenRepeat | TokenChar | TokenList;
 
/**
 * A string literal to use as-is.
 */
export type TokenLiteral = string;
 
/**
 * Picks a random token from the provided tokens.
 */
export type TokenPick = [type: 'pick', ...from: Token[]];
 
/**
 * Repeats `pattern` a random number of times between `min` and `max`.
 */
export type TokenRepeat = [type: 'repeat', min: number, max: number, pattern: Token];
 
/**
 * Specifies a Unicode code point range from which to pick a random character.
 * The `count` parameter specifies how many characters to pick, defaults to 1.
 */
export type TokenChar = [type: 'char', min: number, max: number, count?: number];
 
/**
 * Executes a list of `every` tokens in sequence.
 */
export type TokenList = [type: 'list', ...every: Token[]];
 
/**
 * Generates a random string based on the provided token.
 * @param token The token defining the random string generation.
 * @returns A randomly generated string.
 */
export function randomString(token: Token): string {
  if (typeof token === 'string') return token;
  const rnd = Math.random();
  switch (token[0]) {
    case 'pick': {
      const [, ...from] = token;
      return randomString(from[Math.floor(rnd * from.length)]);
    }
    case 'repeat': {
      const [, min, max, pattern] = token;
      const count = Math.floor(rnd * (max - min + 1)) + min;
      let str = '';
      for (let i = 0; i < count; i++) str += randomString(pattern);
      return str;
    }
    case 'char': {
      const [, min, max, count = 1] = token;
      let str = '';
      for (let i = 0; i < count; i++) {
        const codePoint = Math.floor(rnd * (max - min + 1)) + min;
        str += String.fromCodePoint(codePoint);
      }
      return str;
    }
    case 'list': {
      const [, ...every] = token;
      return every.map(randomString).join('');
    }
    default:
      throw new Error('Invalid token type');
  }
}