All files / src/rules xml_consistency.ts

96.2% Statements 76/79
79.16% Branches 19/24
100% Functions 6/6
96.2% Lines 76/79

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 70 71 72 73 74 75 76 77 78 791x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 8930x 8930x 8930x 8930x 8930x 26618x 26618x 26618x 26618x 26618x 26618x 26618x 8930x 8930x 8485x 8485x 8930x 8930x 202x 202x 8930x 8930x 211x 211x 8930x 8930x 266x 266x 266x 266x 202x 202x 64x 64x 64x 64x 64x 8x 8x 64x 64x 64x 266x 9x 9x   9x 1x 9x 1x 1x 9x 64x 266x 5x 5x   5x   5x 1x 1x 5x 64x 64x 64x 8930x 8930x
import {Issue} from "../issue";
import {IRule, IRuleMetadata, RuleTag} from "./_irule";
import {IObject} from "../objects/_iobject";
import * as Objects from "../objects";
import {IRegistry} from "../_iregistry";
import {BasicRuleConfig} from "./_basic_rule_config";
import {XMLValidator} from "fast-xml-parser";
 
export class XMLConsistencyConf extends BasicRuleConfig {
}
 
export class XMLConsistency implements IRule {
 
  private conf = new XMLConsistencyConf();
 
  public getMetadata(): IRuleMetadata {
    return {
      key: "xml_consistency",
      title: "XML consistency",
      shortDescription: `Checks the consistency of main XML files, eg. naming for CLAS and INTF objects`,
      tags: [RuleTag.Naming, RuleTag.Syntax],
    };
  }
 
  public getConfig() {
    return this.conf;
  }
 
  public setConfig(conf: XMLConsistencyConf) {
    this.conf = conf;
  }
 
  public initialize(_reg: IRegistry) {
    return this;
  }
 
  public run(obj: IObject): Issue[] {
    const issues: Issue[] = [];
 
    const file = obj.getXMLFile();
    if (file === undefined) {
      return issues;
    }
 
    const xml = obj.getXML();
    if (xml) {
      const res = XMLValidator.validate(xml);
      if (res !== true) {
        issues.push(Issue.atRow(file, 1, "XML parser error: " + res.err.msg, this.getMetadata().key, this.conf.severity));
      }
    }
 
    // todo, have some XML validation in each object?
    if (obj instanceof Objects.Class) {
      const name = obj.getNameFromXML();
      if (name === undefined) {
        issues.push(Issue.atRow(file, 1, "Name undefined in XML", this.getMetadata().key, this.conf.severity));
      } else if (name !== obj.getName().toUpperCase()) {
        issues.push(Issue.atRow(file, 1, "Name in XML does not match object", this.getMetadata().key, this.conf.severity));
      } else if (obj.getMainABAPFile()?.getStructure() !== undefined && obj.getClassDefinition() === undefined) {
        issues.push(Issue.atRow(file, 1, "Class matching XML name not found in ABAP file", this.getMetadata().key, this.conf.severity));
      }
    }
 
    if (obj instanceof Objects.Interface) {
      const name = obj.getNameFromXML();
      if (name === undefined) {
        issues.push(Issue.atRow(file, 1, "Name undefined in XML", this.getMetadata().key, this.conf.severity));
      } else if (name !== obj.getName().toUpperCase()) {
        issues.push(Issue.atRow(file, 1, "Name in XML does not match object", this.getMetadata().key, this.conf.severity));
      } else if (obj.getDefinition() !== undefined && obj.getDefinition()?.getName().toUpperCase() !== name.toUpperCase()) {
        issues.push(Issue.atRow(file, 1, "Interface matching XML name not found in ABAP file", this.getMetadata().key, this.conf.severity));
      }
    }
 
    return issues;
  }
 
}