check-report.js 2.45 KB
const schemeDatas = require('../schemes');
const _ = require('lodash');
const assertType = require('./assert-type');

const equalsValidate = scheme => {
  return log => {
    const equals = scheme.equals;
    const conditions = Object.keys(equals);

    return _.every(conditions, key => {
      const value = _.get(log.param, key);

      if (equals[key] instanceof RegExp) {
        return value && equals[key].test(value);
      }
      return value && value === equals[key]
    });
  };
}
const typesValidate = scheme => {
  return log => {
    const types = scheme.types;
    const conditions = Object.keys(types);

    return _.every(conditions, key => {
      const value = _.get(log.param, key);

      return value && assertType(value, types[key])
    });
  };
}
const validate = scheme => {
  return log => {
    return scheme.validate(log);
  };
}

const convertSchemes = (schemes) => {
  _.each(schemes, scheme => {
    scheme._validates = [];
    if (scheme.equals) {
      if (!scheme.priority) {
        scheme.priority = 1;
      }
      scheme._validates.push(equalsValidate(scheme));
    }
    if (scheme.types) {
      if (!scheme.priority) {
        scheme.priority = 1;
      }
      scheme._validates.push(typesValidate(scheme));
    }
    if (scheme.validate) {
      if (!scheme.priority) {
        scheme.priority = 1;
      }
      scheme._validates.push(validate(scheme));
    }
    if (scheme.single) {
      if (!scheme.priority) {
        scheme.priority = 1;
      }
    }
    if (!scheme.priority) {
      scheme.priority = 0;
    }
  })

  return _.orderBy(schemes, 'priority', 'desc');
}
const matchIndex = (scheme, logs) => {
  return _.findIndex(logs, log =>
    log.op === scheme.op && _.every(scheme._validates, vali => vali(log)));
}

const validateSchemes = (schemes, logs) => {
  const notValidates = _.filter(schemes, scheme => {
    const index = matchIndex(scheme, logs);

    if (index >= 0) {
      logs.splice(index, 1);
      if (scheme.single) {
        const repeatIndex = matchIndex(scheme, logs);

        if (repeatIndex >= 0) {
          return true;
        }
      }
      return false;
    }
    return true;
  });
  const overLogs = logs;

  return {
    notValidates,
    overLogs
  }
}

module.exports = function checkScene(scene, sceneData = {}) {
  if (!schemeDatas[scene]) {
    throw `未找到${scene}对应的scheme`;
  }
  const matchScheme = convertSchemes(schemeDatas[scene])

  return validateSchemes(matchScheme, sceneData[scene])
}