All files / src rule.ts

100% Statements 27/27
100% Branches 28/28
100% Functions 5/5
100% Lines 27/27

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 6410x 10x 10x 10x     10x         58x 19x 39x 37x 35x   2x                   14x   14x 11x 3x 2x           13x   13x       56x 55x 1x   54x     1x         35x 31x 4x 3x        
import chalk from 'chalk';
import { AntlerError } from './antler-error';
import { AntlerWarning } from './antler-warning';
import { LEVELS } from './constants';
import { Level, Node, RuleConfig, RuleOptions } from './types';
 
export abstract class Rule {
  protected options?: RuleOptions;
  protected level: Level;
 
  public constructor(config: Level | RuleConfig) {
    if (typeof config === 'string') {
      this.setLevel(config);
    } else if (config && typeof config === 'object' && !Array.isArray(config)) {
      this.setLevel(config.level);
      this.setOptions(config.options);
    } else {
      this.error('Invalid config - must be a string or object');
    }
  }
 
  public abstract run(node: Node): void;
 
  protected abstract getName(): string;
 
  protected report(error: Error | string) {
    const message =
      error instanceof Error && error.message ? error.message : error;
 
    if (this.level === 'error') {
      throw new AntlerError(`${this.getName()}: ${message}`);
    } else if (this.level === 'warning') {
      throw new AntlerWarning(`${this.getName()}: ${message}`);
    }
  }
 
  protected error(error: Error | string) {
    const message =
      error instanceof Error && error.message ? error.message : error;
 
    throw new Error(chalk.red(`${this.getName()}: ${message}`));
  }
 
  private setLevel(level?: Level) {
    if (typeof level === 'string') {
      if (LEVELS.indexOf(level) < 0) {
        this.error(`Error level must be one of ${LEVELS.join(', ')}`);
      } else {
        this.level = level;
      }
    } else {
      this.error(`Error level must be one of ${LEVELS.join(', ')}`);
    }
  }
 
  private setOptions(options?: RuleOptions) {
    if (options && typeof options === 'object' && !Array.isArray(options)) {
      this.options = options;
    } else if (typeof options !== 'undefined') {
      this.error('Invalid options - must be an object');
    }
  }
}