Selaa lähdekoodia

tech: annotations refactor, add tests for regions processing (#9618)

* tech: annotations refactor, add tests for regions processing

* tech: remove unused imports from annotations tests
Alexander Zobnin 8 vuotta sitten
vanhempi
commit
2b78c47a5a

+ 1 - 79
public/app/features/annotations/annotations_srv.ts

@@ -3,6 +3,7 @@ import './editor_ctrl';
 import angular from 'angular';
 import _ from 'lodash';
 import coreModule from 'app/core/core_module';
+import {makeRegions, dedupAnnotations} from './events_processing';
 
 export class AnnotationsSrv {
   globalAnnotationsPromise: any;
@@ -161,83 +162,4 @@ export class AnnotationsSrv {
   }
 }
 
-/**
- * This function converts annotation events into set
- * of single events and regions (event consist of two)
- * @param annotations
- * @param options
- */
-function makeRegions(annotations, options) {
-  let [regionEvents, singleEvents] = _.partition(annotations, 'regionId');
-  let regions = getRegions(regionEvents, options.range);
-  annotations = _.concat(regions, singleEvents);
-  return annotations;
-}
-
-function getRegions(events, range) {
-  let region_events = _.filter(events, event => {
-    return event.regionId;
-  });
-  let regions = _.groupBy(region_events, 'regionId');
-  regions = _.compact(
-    _.map(regions, region_events => {
-      let region_obj = _.head(region_events);
-      if (region_events && region_events.length > 1) {
-        region_obj.timeEnd = region_events[1].time;
-        region_obj.isRegion = true;
-        return region_obj;
-      } else {
-        if (region_events && region_events.length) {
-          // Don't change proper region object
-          if (!region_obj.time || !region_obj.timeEnd) {
-            // This is cut region
-            if (isStartOfRegion(region_obj)) {
-              region_obj.timeEnd = range.to.valueOf() - 1;
-            } else {
-              // Start time = null
-              region_obj.timeEnd = region_obj.time;
-              region_obj.time = range.from.valueOf() + 1;
-            }
-            region_obj.isRegion = true;
-          }
-
-          return region_obj;
-        }
-      }
-    }),
-  );
-
-  return regions;
-}
-
-function isStartOfRegion(event): boolean {
-  return event.id && event.id === event.regionId;
-}
-
-function dedupAnnotations(annotations) {
-  let dedup = [];
-
-  // Split events by annotationId property existance
-  let events = _.partition(annotations, 'id');
-
-  let eventsById = _.groupBy(events[0], 'id');
-  dedup = _.map(eventsById, eventGroup => {
-    if (eventGroup.length > 1 && !_.every(eventGroup, isPanelAlert)) {
-      // Get first non-panel alert
-      return _.find(eventGroup, event => {
-        return event.eventType !== 'panel-alert';
-      });
-    } else {
-      return _.head(eventGroup);
-    }
-  });
-
-  dedup = _.concat(dedup, events[1]);
-  return dedup;
-}
-
-function isPanelAlert(event) {
-  return event.eventType === 'panel-alert';
-}
-
 coreModule.service('annotationsSrv', AnnotationsSrv);

+ 80 - 0
public/app/features/annotations/events_processing.ts

@@ -0,0 +1,80 @@
+import _ from 'lodash';
+
+/**
+ * This function converts annotation events into set
+ * of single events and regions (event consist of two)
+ * @param annotations
+ * @param options
+ */
+export function makeRegions(annotations, options) {
+  let [regionEvents, singleEvents] = _.partition(annotations, 'regionId');
+  let regions = getRegions(regionEvents, options.range);
+  annotations = _.concat(regions, singleEvents);
+  return annotations;
+}
+
+function getRegions(events, range) {
+  let region_events = _.filter(events, event => {
+    return event.regionId;
+  });
+  let regions = _.groupBy(region_events, 'regionId');
+  regions = _.compact(
+    _.map(regions, region_events => {
+      let region_obj = _.head(region_events);
+      if (region_events && region_events.length > 1) {
+        region_obj.timeEnd = region_events[1].time;
+        region_obj.isRegion = true;
+        return region_obj;
+      } else {
+        if (region_events && region_events.length) {
+          // Don't change proper region object
+          if (!region_obj.time || !region_obj.timeEnd) {
+            // This is cut region
+            if (isStartOfRegion(region_obj)) {
+              region_obj.timeEnd = range.to.valueOf() - 1;
+            } else {
+              // Start time = null
+              region_obj.timeEnd = region_obj.time;
+              region_obj.time = range.from.valueOf() + 1;
+            }
+            region_obj.isRegion = true;
+          }
+
+          return region_obj;
+        }
+      }
+    }),
+  );
+
+  return regions;
+}
+
+function isStartOfRegion(event): boolean {
+  return event.id && event.id === event.regionId;
+}
+
+export function dedupAnnotations(annotations) {
+  let dedup = [];
+
+  // Split events by annotationId property existance
+  let events = _.partition(annotations, 'id');
+
+  let eventsById = _.groupBy(events[0], 'id');
+  dedup = _.map(eventsById, eventGroup => {
+    if (eventGroup.length > 1 && !_.every(eventGroup, isPanelAlert)) {
+      // Get first non-panel alert
+      return _.find(eventGroup, event => {
+        return event.eventType !== 'panel-alert';
+      });
+    } else {
+      return _.head(eventGroup);
+    }
+  });
+
+  dedup = _.concat(dedup, events[1]);
+  return dedup;
+}
+
+function isPanelAlert(event) {
+  return event.eventType === 'panel-alert';
+}

+ 83 - 0
public/app/features/annotations/specs/annotations_srv_specs.jest.ts

@@ -0,0 +1,83 @@
+import {makeRegions, dedupAnnotations} from '../events_processing';
+
+describe('Annotations', () => {
+
+  describe('Annotations regions', () => {
+    let testAnnotations: any[];
+
+    beforeEach(() => {
+      testAnnotations = [
+        {id: 1, time: 1},
+        {id: 2, time: 2},
+        {id: 3, time: 3, regionId: 3},
+        {id: 4, time: 5, regionId: 3},
+        {id: 5, time: 4, regionId: 5},
+        {id: 6, time: 8, regionId: 5}
+      ];
+    });
+
+    it('should convert single region events to regions', () => {
+      const range = {from: 0, to: 10};
+      const expectedAnnotations = [
+        {id: 3, regionId: 3, isRegion: true, time: 3, timeEnd: 5},
+        {id: 5, regionId: 5, isRegion: true, time: 4, timeEnd: 8},
+        {id: 1, time: 1},
+        {id: 2, time: 2}
+      ];
+
+      let regions = makeRegions(testAnnotations, {range: range});
+      expect(regions).toEqual(expectedAnnotations);
+    });
+
+    it('should cut regions to current time range', () => {
+      const range = {from: 0, to: 8};
+      testAnnotations = [
+        {id: 5, time: 4, regionId: 5}
+      ];
+      const expectedAnnotations = [
+        {id: 5, regionId: 5, isRegion: true, time: 4, timeEnd: 7}
+      ];
+
+      let regions = makeRegions(testAnnotations, {range: range});
+      expect(regions).toEqual(expectedAnnotations);
+    });
+  });
+
+  describe('Annotations deduplication', () => {
+    it('should remove duplicated annotations', () => {
+      const testAnnotations = [
+        {id: 1, time: 1},
+        {id: 2, time: 2},
+        {id: 2, time: 2},
+        {id: 5, time: 5},
+        {id: 5, time: 5}
+      ];
+      const expectedAnnotations = [
+        {id: 1, time: 1},
+        {id: 2, time: 2},
+        {id: 5, time: 5}
+      ];
+
+      let deduplicated = dedupAnnotations(testAnnotations);
+      expect(deduplicated).toEqual(expectedAnnotations);
+    });
+
+    it('should leave non "panel-alert" event if present', () => {
+      const testAnnotations = [
+        {id: 1, time: 1},
+        {id: 2, time: 2},
+        {id: 2, time: 2, eventType: 'panel-alert'},
+        {id: 5, time: 5},
+        {id: 5, time: 5}
+      ];
+      const expectedAnnotations = [
+        {id: 1, time: 1},
+        {id: 2, time: 2},
+        {id: 5, time: 5}
+      ];
+
+      let deduplicated = dedupAnnotations(testAnnotations);
+      expect(deduplicated).toEqual(expectedAnnotations);
+    });
+  });
+});