All files / if-run/util aggregation-helper.ts

100% Statements 29/29
100% Branches 12/12
100% Functions 2/2
100% Lines 28/28

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 658x     8x       8x   8x 8x 8x           8x         15x   15x 29x 85x 1x       84x 56x 28x     28x   28x   28x 2x     26x 2x 2x     24x 24x     24x 12x 1x           28x      
import {ERRORS} from '@grnsft/if-core/utils';
import {PluginParams} from '@grnsft/if-core/types';
 
import {CONFIG, STRINGS} from '../config';
 
import {AggregationResult} from '../types/aggregation';
 
import {getAggregationInfoFor} from '../lib/aggregate';
 
const {MissingAggregationParamError} = ERRORS;
const {METRIC_MISSING} = STRINGS;
const {AGGREGATION_TIME_METRICS} = CONFIG;
 
/**
 * Aggregates child node level metrics. Appends aggregation additional params to metrics.
 * Otherwise iterates over outputs by aggregating per given `metrics`.
 */
export const aggregateOutputsIntoOne = (
  outputs: PluginParams[],
  metrics: string[],
  isTemporal?: boolean
) => {
  const metricsWithTime = metrics.concat(AGGREGATION_TIME_METRICS);
 
  return outputs.reduce((acc, output, index) => {
    for (const metric of metricsWithTime) {
      if (!(metric in output)) {
        throw new MissingAggregationParamError(METRIC_MISSING(metric, index));
      }
 
      /** Checks if metric is timestamp or duration, then adds to aggregated value. */
      if (AGGREGATION_TIME_METRICS.includes(metric)) {
        if (isTemporal) {
          acc[metric] = output[metric];
        }
      } else {
        const aggregationParams = getAggregationInfoFor(metric);
        /** Checks either its a temporal aggregation (vertical), then chooses `component`, otherwise `time`.  */
        const aggregationType = isTemporal ? 'component' : 'time';
 
        if (aggregationParams[aggregationType] === 'none') {
          continue;
        }
 
        if (aggregationParams[aggregationType] === 'copy') {
          acc[metric] = output[metric];
          continue;
        }
 
        acc[metric] = acc[metric] ?? 0;
        acc[metric] += parseFloat(output[metric]);
 
        /** Checks for the last iteration. */
        if (index === outputs.length - 1) {
          if (aggregationParams[aggregationType] === 'avg') {
            acc[metric] /= outputs.length;
          }
        }
      }
    }
 
    return acc;
  }, {} as AggregationResult);
};