All files / FeatureServer/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                       27x   27x                         19x 19x                 19x 19x   19x     29x 4x   4x       4x     25x 8x     17x     19x         25x 5x         19x 6x 6x   19x 19x         5x   5x 5x 5x       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