@netdata/charts
Version:
Netdata frontend SDK and chart utilities
287 lines (285 loc) • 8.79 kB
JavaScript
"use strict";
var _calculations = require("./calculations");
describe("calculations", function () {
describe("calculateStats", function () {
it("calculates correct statistics from data", function () {
var payload = {
data: [[1, 10, 20], [2, 30, 40], [3, 50, 60]],
dimensions: ["cpu", "memory"],
viewUpdateEvery: 2
};
var result = (0, _calculations.calculateStats)(payload);
expect(result).toEqual({
min: 30,
avg: 70,
max: 110,
points: 3,
dimensions: 2,
cv: 46.656947481584346,
median: 70,
stddev: 32.65986323710904,
p25: 50,
p75: 90,
p95: 106,
range: 80,
count: 3,
volume: 420
});
});
it("filters data by highlight range", function () {
var payload = {
data: [[1000000, 10, 20],
// 1000 seconds in ms
[2000000, 30, 40],
// 2000 seconds in ms
[3000000, 50, 60],
// 3000 seconds in ms
[4000000, 70, 80] // 4000 seconds in ms
],
dimensions: ["cpu", "memory"],
viewUpdateEvery: 2
};
// Highlight range in seconds (1500-3500), will be converted to ms internally
var result = (0, _calculations.calculateStats)(payload, [1500, 3500]);
expect(result).toEqual({
min: 70,
avg: 90,
max: 110,
points: 2,
dimensions: 2,
cv: 22.22222222222222,
median: 90,
stddev: 20,
p25: 80,
p75: 100,
p95: 108,
range: 40,
count: 2,
volume: 360
});
});
it("returns null when highlight range excludes all data", function () {
var payload = {
data: [[1000, 10, 20], [2000, 30, 40]],
dimensions: ["cpu", "memory"]
};
var result = (0, _calculations.calculateStats)(payload, [5000, 6000]);
expect(result).toBeNull();
});
it("handles null and invalid values", function () {
var payload = {
data: [[1, null, 20], [2, NaN, 40], [3, Infinity, 60]],
dimensions: ["cpu"],
viewUpdateEvery: 1
};
var result = (0, _calculations.calculateStats)(payload);
expect(result).toEqual({
min: 20,
avg: 40,
max: 60,
points: 3,
dimensions: 2,
cv: 40.8248290463863,
median: 40,
stddev: 16.32993161855452,
p25: 30,
p75: 50,
p95: 58,
range: 40,
count: 3,
volume: 120
});
});
it("uses absolute values for dimension aggregation", function () {
var payload = {
data: [[1, -500, 100], [2, -300, 200], [3, -100, 50]],
dimensions: ["received", "sent"],
viewUpdateEvery: 1
};
var result = (0, _calculations.calculateStats)(payload);
expect(result.min).toBe(150);
expect(result.avg).toBeCloseTo(416.67, 1);
expect(result.max).toBe(600);
expect(result.median).toBe(500);
expect(result.volume).toBeCloseTo(1250, 0);
expect(result.range).toBe(450);
});
it("returns null for empty or invalid payload", function () {
expect((0, _calculations.calculateStats)(null)).toBeNull();
expect((0, _calculations.calculateStats)({})).toBeNull();
expect((0, _calculations.calculateStats)({
data: []
})).toBeNull();
expect((0, _calculations.calculateStats)({
data: [[1]]
})).toBeNull();
});
});
describe("calculatePercentageChange", function () {
it("calculates positive percentage change", function () {
var result = (0, _calculations.calculatePercentageChange)(120, 100);
expect(result).toEqual({
value: 20,
direction: "up",
formatted: "20.0%"
});
});
it("calculates negative percentage change", function () {
var result = (0, _calculations.calculatePercentageChange)(80, 100);
expect(result).toEqual({
value: 20,
direction: "down",
formatted: "20.0%"
});
});
it("handles edge cases", function () {
expect((0, _calculations.calculatePercentageChange)(0, 100)).toEqual({
value: 100,
direction: "down",
formatted: "100.0%"
});
expect((0, _calculations.calculatePercentageChange)(100, 0)).toEqual({
value: 0,
direction: "neutral",
formatted: "0.0%"
});
expect((0, _calculations.calculatePercentageChange)(0, 0)).toEqual({
value: 0,
direction: "neutral",
formatted: "0.0%"
});
expect((0, _calculations.calculatePercentageChange)(null, 100)).toBeNull();
expect((0, _calculations.calculatePercentageChange)(100, null)).toBeNull();
});
});
describe("calculateComparisons", function () {
var mockPeriods = [{
id: "selected",
isBase: true,
stats: {
min: 10,
avg: 30,
max: 50,
points: 100,
dimensions: 2
}
}, {
id: "24h",
stats: {
min: 8,
avg: 36,
max: 60,
points: 90,
dimensions: 2
}
}, {
id: "7d",
stats: {
min: 12,
avg: 24,
max: 40,
points: 110,
dimensions: 2
}
}];
it("calculates comparisons correctly", function () {
var result = (0, _calculations.calculateComparisons)(mockPeriods);
expect(result[0]).toEqual(mockPeriods[0]);
expect(result[1].changes.min).toEqual({
value: 20,
direction: "down",
formatted: "20.0%"
});
expect(result[1].changes.avg).toEqual({
value: 20,
direction: "up",
formatted: "20.0%"
});
});
it("handles missing base period", function () {
var periodsWithoutBase = [{
id: "24h",
stats: {
min: 10,
avg: 20,
max: 30
}
}];
var result = (0, _calculations.calculateComparisons)(periodsWithoutBase);
expect(result).toEqual(periodsWithoutBase);
});
});
describe("extractDimensionValues", function () {
it("returns null when payload is null or undefined", function () {
expect((0, _calculations.extractDimensionValues)(null)).toBeNull();
expect((0, _calculations.extractDimensionValues)(undefined)).toBeNull();
});
it("returns null when payload.data is empty", function () {
expect((0, _calculations.extractDimensionValues)({
data: [],
labels: ["time", "in", "ANOMALY_RATE", "ANNOTATIONS"]
})).toBeNull();
});
it("returns null when payload.labels is missing or not an array", function () {
expect((0, _calculations.extractDimensionValues)({
data: [[1, 10]]
})).toBeNull();
expect((0, _calculations.extractDimensionValues)({
data: [[1, 10]],
labels: "nope"
})).toBeNull();
});
it("returns a label -> value bag for a bare camelized payload", function () {
var payload = {
labels: ["time", "in", "out", "ANOMALY_RATE", "ANNOTATIONS"],
data: [[1000, 100, 200, null, null]]
};
expect((0, _calculations.extractDimensionValues)(payload)).toEqual({
"in": 100,
out: 200
});
});
it("skips synthetic ANOMALY_RATE and ANNOTATIONS labels", function () {
var payload = {
labels: ["time", "in", "ANOMALY_RATE", "out", "ANNOTATIONS"],
data: [[1000, 100, 0.5, 200, "x"]]
};
expect((0, _calculations.extractDimensionValues)(payload)).toEqual({
"in": 100,
out: 200
});
});
it("picks the requested row when rowIndex is provided", function () {
var payload = {
labels: ["time", "in", "out", "ANOMALY_RATE", "ANNOTATIONS"],
data: [[1000, 10, 20, null, null], [2000, 30, 40, null, null], [3000, 50, 60, null, null]]
};
expect((0, _calculations.extractDimensionValues)(payload, 0)).toEqual({
"in": 10,
out: 20
});
expect((0, _calculations.extractDimensionValues)(payload, 1)).toEqual({
"in": 30,
out: 40
});
});
it("counts from end for negative rowIndex", function () {
var payload = {
labels: ["time", "in", "out", "ANOMALY_RATE", "ANNOTATIONS"],
data: [[1000, 10, 20, null, null], [2000, 30, 40, null, null], [3000, 50, 60, null, null]]
};
expect((0, _calculations.extractDimensionValues)(payload)).toEqual({
"in": 50,
out: 60
});
expect((0, _calculations.extractDimensionValues)(payload, -1)).toEqual({
"in": 50,
out: 60
});
expect((0, _calculations.extractDimensionValues)(payload, -2)).toEqual({
"in": 30,
out: 40
});
});
});
});