All files / lib/helpers/fields statistics-fields.js

96.96% Statements 32/33
80% Branches 20/25
100% Functions 12/12
96.87% Lines 31/32

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 991x 1x 1x           1x                       13x   13x                         5x 5x                 5x 5x   5x     7x 2x   2x       2x     5x 4x     1x     5x         5x 3x         5x 3x 3x   5x 3x         3x   3x 3x 3x       1x  
const { isDate } = require('../data-type-utils')
const { getEsriTypeFromDefinition } = require('./esri-type-utils')
const { ESRI_FIELD_TYPE_DATE } = require('./constants')
const {
  StatisticField,
  StatisticDateField,
  FieldFromFieldDefinition,
  FieldFromKeyValue
} = require('./field-classes')
 
class StatisticsFields {
  static normalizeOptions (inputOptions = {}) {
    const {
      statistics,
      metadata: {
        fields
      } = {},
      groupByFieldsForStatistics = [],
      attributeSample,
      ...options
    } = inputOptions
 
    return {
      statisticsSample: Array.isArray(statistics) ? statistics[0] : statistics,
      fieldDefinitions: options.fieldDefinitions || options.fields || fields,
      groupByFieldsForStatistics: Array.isArray(groupByFieldsForStatistics) ? groupByFieldsForStatistics : groupByFieldsForStatistics
        .replace(/\s*,\s*/g, ',')
        .replace(/^\s/, '')
        .replace(/\s*$/, '')
        .split(','),
      ...options
    }
  }
 
  static create (inputOptions) {
    const options = StatisticsFields.normalizeOptions(inputOptions)
    return new StatisticsFields(options)
  }
 
  constructor (options = {}) {
    const {
      statisticsSample,
      groupByFieldsForStatistics = [],
      fieldDefinitions = [],
      outStatistics
    } = options
    const dateFieldRegexs = getDateFieldRegexs(fieldDefinitions, outStatistics)
 
    this.fields = Object
      .entries(statisticsSample)
      .map(([key, value]) => {
        if (groupByFieldsForStatistics.includes(key)) {
          const fieldDefinition = fieldDefinitions.find(({ name }) => name === key)
 
          Iif (fieldDefinition) {
            return new FieldFromFieldDefinition(fieldDefinition)
          }
 
          return new FieldFromKeyValue(key, value)
        }
 
        if (isDateField(dateFieldRegexs, key, value)) {
          return new StatisticDateField(key)
        }
 
        return new StatisticField(key)
      })
 
    return this.fields
  }
}
 
function isDateField (regexs, fieldName, value) {
  return regexs.some(regex => {
    return regex.test(fieldName)
  }) || isDate(value)
}
 
function getDateFieldRegexs (fieldDefinitions = [], outStatistics = []) {
  const dateFields = fieldDefinitions.filter(({ type }) => {
    return getEsriTypeFromDefinition(type) === ESRI_FIELD_TYPE_DATE
  }).map(({ name }) => name)
 
  return outStatistics
    .filter(({ onStatisticField }) => dateFields.includes(onStatisticField))
    .map((statistic) => {
      const {
        onStatisticField,
        outStatisticFieldName
      } = statistic
 
      const name = outStatisticFieldName || onStatisticField
      const spaceEscapedName = name.replace(/\s/g, '_')
      return new RegExp(`${spaceEscapedName}$`)
    })
}
 
module.exports = StatisticsFields