All files / lib/model/oasis/annotations ExpressionBuilder.js

100% Statements 30/30
100% Branches 8/8
100% Functions 11/11
100% Lines 30/30

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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107    1x 1x 1x 1x 1x   1x                             1x               1523x 36x 69x           1355x     1355x 1355x 1x                         17x       51x       2x       3x       1x       85x 1355x     84x     84x   84x     84x     84x   1344x     84x 1x             1x  
"use strict";
 
const _ = require("lodash");
const Annotation = require("./Annotation");
const Collection = require("./Collection");
const PropertyValue = require("./PropertyValue");
const Record = require("./Record");
 
const constantExpressions = [
  "Binary",
  "Bool",
  "Date",
  "DateTimeOffset",
  "Decimal",
  "Duration",
  "EnumMember",
  "Float",
  "Guid",
  "Int",
  "String",
  "TimeOfDay",
];
 
const scalarExpressions = constantExpressions.concat([
  "AnnotationPath",
  "NavigationPropertyPath",
  "Path",
  "PropertyPath",
]);
 
function defineSingleValueProperty(element, propertyName, values) {
  if (values.length === 1) {
    Object.defineProperty(element, propertyName, {
      get: () => values[0],
    });
  }
}
 
function parseConstantExpression(element, propertyName, elementId) {
  let values = [element.raw.$ ? element.raw.$[propertyName] : undefined]
    .concat(element.raw[propertyName])
    .filter(Boolean);
  defineSingleValueProperty(element, _.lowerFirst(propertyName), values);
  if (values.length > 1) {
    throw new Error(
      `Multiple '${propertyName}' values defined for ${elementId}`
    );
  }
}
 
/**
 * Class for construction annotation values.
 *
 * @class ExpressionBuilder
 */
class ExpressionBuilder {
  static get scalarExpressions() {
    return scalarExpressions;
  }
 
  static buildAnnotation(annotationMetadata) {
    return new Annotation(annotationMetadata, ExpressionBuilder);
  }
 
  static buildCollection(collectionMetadata) {
    return new Collection(collectionMetadata, ExpressionBuilder);
  }
 
  static buildRecord(recordMetadata) {
    return new Record(recordMetadata, ExpressionBuilder);
  }
 
  static buildPropertyValue(propertyValueMetadata) {
    return new PropertyValue(propertyValueMetadata, ExpressionBuilder);
  }
 
  static assignElementValue(element, elementId) {
    scalarExpressions.forEach((p) =>
      parseConstantExpression(element, p, elementId)
    );
 
    let collections = _.get(element.raw, "Collection", []).map(
      ExpressionBuilder.buildCollection
    );
    defineSingleValueProperty(element, "collection", collections);
 
    let records = _.get(element.raw, "Record", []).map(
      ExpressionBuilder.buildRecord
    );
    defineSingleValueProperty(element, "record", records);
 
    let expressionCount =
      collections.length +
      records.length +
      scalarExpressions.filter((e) => element[_.lowerFirst(e)] !== undefined)
        .length;
 
    if (expressionCount > 1) {
      throw new Error(
        `${elementId} has multiple (${expressionCount}) value expressions.`
      );
    }
  }
}
 
module.exports = ExpressionBuilder;