All files / json-ot/types/ot-string validate.ts

87.5% Statements 42/48
76.92% Branches 20/26
100% Functions 2/2
97.05% Lines 33/34

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    3x 3x 3x 3x 3x 3x     3x 17x 17x   17x 37x 37x   24x 23x 21x 15x 15x   6x 6x   19x     12x 8x 8x 7x     1x 1x 1x 1x 1x         27x   7x 7x 4x    
import type {StringOp, StringOpComponent} from './types';
 
export enum VALIDATE_RESULT {
  SUCCESS = 0,
  INVALID_OP = 1,
  INVALID_COMPONENT = 2,
  ADJACENT_SAME_TYPE = 3,
  NO_TRAILING_RETAIN = 4,
}
 
export const validate = (op: StringOp): VALIDATE_RESULT => {
  Iif (!(op instanceof Array)) return VALIDATE_RESULT.INVALID_OP;
  Iif (op.length === 0) return VALIDATE_RESULT.INVALID_OP;
  let last: StringOpComponent | undefined;
  for (let i = 0; i < op.length; i++) {
    const component = op[i];
    switch (typeof component) {
      case 'number': {
        if (!component) return VALIDATE_RESULT.INVALID_COMPONENT;
        if (component !== Math.round(component)) return VALIDATE_RESULT.INVALID_COMPONENT;
        if (component > 0) {
          const lastComponentIsRetain = typeof last === 'number' && last > 0;
          if (lastComponentIsRetain) return VALIDATE_RESULT.ADJACENT_SAME_TYPE;
        } else {
          const lastComponentIsDelete = typeof last === 'number' && last < 0;
          if (lastComponentIsDelete) return VALIDATE_RESULT.ADJACENT_SAME_TYPE;
        }
        break;
      }
      case 'string': {
        if (!component.length) return VALIDATE_RESULT.INVALID_COMPONENT;
        const lastComponentIsInsert = typeof last === 'string';
        if (lastComponentIsInsert) return VALIDATE_RESULT.ADJACENT_SAME_TYPE;
        break;
      }
      case 'object': {
        Iif (!(component instanceof Array)) return VALIDATE_RESULT.INVALID_COMPONENT;
        Iif (component.length !== 1) return VALIDATE_RESULT.INVALID_COMPONENT;
        const lastComponentIsRetainedDelete = last instanceof Array;
        Iif (lastComponentIsRetainedDelete) return VALIDATE_RESULT.ADJACENT_SAME_TYPE;
        break;
      }
      default:
        return VALIDATE_RESULT.INVALID_COMPONENT;
    }
    last = component;
  }
  const isLastRetain = typeof last === 'number' && last > 0;
  if (isLastRetain) return VALIDATE_RESULT.NO_TRAILING_RETAIN;
  return VALIDATE_RESULT.SUCCESS;
};