Browse Source

Tests for detection-spans (#747)

pull/1/head
rozetko 5 years ago committed by GitHub
parent
commit
4a764cb4d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 75
      server/spec/models/detection_model.jest.ts
  2. 28
      server/spec/utils_for_tests/detection_spans.ts
  3. 11
      server/src/models/detection_model.ts
  4. 1
      server/src/utils/spans.ts

75
server/spec/models/detection_model.jest.ts

@ -0,0 +1,75 @@
import { TEST_ANALYTIC_UNIT_ID } from '../utils_for_tests/analytic_units';
import { buildSpans, insertSpans, clearSpansDB, convertSpansToOptions } from '../utils_for_tests/detection_spans';
import * as Detection from '../../src/models/detection_model';
import * as _ from 'lodash';
const INITIAL_SPANS_CONFIGS = [
{ from: 1, to: 3, status: Detection.DetectionStatus.READY },
{ from: 4, to: 5, status: Detection.DetectionStatus.RUNNING }
];
beforeEach(async () => {
await insertSpans(INITIAL_SPANS_CONFIGS);
});
afterEach(clearSpansDB);
describe('insertSpan', () => {
it('should merge spans with the same status', async () => {
await insertSpans([
{ from: 3, to: 5, status: Detection.DetectionStatus.READY }
]);
const expectedSpans = [
{ from: 1, to: 5, status: Detection.DetectionStatus.READY }
];
const spansInDB = await Detection.findMany(TEST_ANALYTIC_UNIT_ID, { });
const spansOptions = convertSpansToOptions(spansInDB);
expect(spansOptions).toEqual(expectedSpans);
});
it('should merge spans if existing span is inside the one being inserted', async () => {
await insertSpans([
{ from: 1, to: 6, status: Detection.DetectionStatus.RUNNING }
]);
const expectedSpans = [
{ from: 1, to: 6, status: Detection.DetectionStatus.RUNNING }
];
const spansInDB = await Detection.findMany(TEST_ANALYTIC_UNIT_ID, {});
const spansOptions = convertSpansToOptions(spansInDB);
expect(spansOptions).toEqual(expectedSpans);
});
});
describe('getIntersectedSpans', () => {
it('should find all intersections with the inserted span', async () => {
const testCases = [
{
from: 1, to: 5,
expected: [
{ from: 1, to: 3, status: Detection.DetectionStatus.READY },
{ from: 3, to: 4, status: Detection.DetectionStatus.RUNNING }
]
},
{ from: 4, to: 5, expected: [{ from: 3, to: 4, status: Detection.DetectionStatus.RUNNING }] },
{ from: 6, to: 7, expected: [] }
]
for(let testCase of testCases) {
const intersectedSpans = await Detection.getIntersectedSpans(TEST_ANALYTIC_UNIT_ID, testCase.from, testCase.to);
const intersectedSpansOptions = convertSpansToOptions(intersectedSpans);
expect(intersectedSpansOptions).toEqual(testCase.expected);
}
});
});
describe('getSpanBorders', () => {
it('should sort and find span borders', () => {
const borders = Detection.getSpanBorders(buildSpans(INITIAL_SPANS_CONFIGS));
expect(borders).toEqual([1, 3, 3, 4]);
});
});

28
server/spec/utils_for_tests/detection_spans.ts

@ -0,0 +1,28 @@
import { TEST_ANALYTIC_UNIT_ID } from './analytic_units';
import * as Detection from '../../src/models/detection_model';
import * as _ from 'lodash';
export type DetectionSpanOptions = { from: number, to: number, status: Detection.DetectionStatus };
export function buildSpans(options: DetectionSpanOptions[]): Detection.DetectionSpan[] {
return options.map(option => {
return new Detection.DetectionSpan(TEST_ANALYTIC_UNIT_ID, option.from, option.to, option.status);
});
}
export async function insertSpans(options: DetectionSpanOptions[]): Promise<void> {
const spansToInsert = buildSpans(options);
const insertPromises = spansToInsert.map(async span => Detection.insertSpan(span));
await Promise.all(insertPromises);
}
export function convertSpansToOptions(spans: Detection.DetectionSpan[]): DetectionSpanOptions[] {
const spansOptions = spans.map(span => ({ from: span.from, to: span.to, status: span.status }));
return _.sortBy(spansOptions, spanOptions => spanOptions.from);
}
export async function clearSpansDB(): Promise<void> {
await Detection.clearSpans(TEST_ANALYTIC_UNIT_ID);
}

11
server/src/models/detection_model.ts

@ -2,6 +2,7 @@ import { AnalyticUnitId } from './analytic_units';
import { Collection, makeDBQ } from '../services/data_service'; import { Collection, makeDBQ } from '../services/data_service';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { getNonIntersectedSpans } from '../utils/spans';
let db = makeDBQ(Collection.DETECTION_SPANS); let db = makeDBQ(Collection.DETECTION_SPANS);
@ -13,6 +14,12 @@ export enum DetectionStatus {
export type DetectionId = string; export type DetectionId = string;
/**
* Detection-span represents the state of dataset segment:
* - READY: detection is done
* - RUNNING: detection is running
* - FAILED: detection failed
*/
export class DetectionSpan { export class DetectionSpan {
constructor( constructor(
public analyticUnitId: AnalyticUnitId, public analyticUnitId: AnalyticUnitId,
@ -130,6 +137,10 @@ export async function insertSpan(span: DetectionSpan) {
return db.insertOne(spanToInsert); return db.insertOne(spanToInsert);
} }
/**
* Sorts spans by `from` field and @returns an array of their borders
*/
// TODO: remove after getNonIntersectedSpans refactoring
export function getSpanBorders(spans: DetectionSpan[]): number[] { export function getSpanBorders(spans: DetectionSpan[]): number[] {
let spanBorders: number[] = []; let spanBorders: number[] = [];

1
server/src/utils/spans.ts

@ -7,6 +7,7 @@ export declare type Span = {
to: number to: number
} }
// TODO: move from utils and refactor
export function getNonIntersectedSpans(from: number, to: number, spanBorders: number[]): Span[] { export function getNonIntersectedSpans(from: number, to: number, spanBorders: number[]): Span[] {
// spanBorders array must be sorted ascending // spanBorders array must be sorted ascending
let isFromProcessed = false; let isFromProcessed = false;

Loading…
Cancel
Save