mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
tech: annotations refactor, add tests for regions processing (#9618)
* tech: annotations refactor, add tests for regions processing * tech: remove unused imports from annotations tests
This commit is contained in:
committed by
Torkel Ödegaard
parent
c3b90f2028
commit
2b78c47a5a
@@ -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
public/app/features/annotations/events_processing.ts
Normal file
80
public/app/features/annotations/events_processing.ts
Normal file
@@ -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';
|
||||
}
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user