Skip to content

Commit 0bcf2e8

Browse files
committed
add MovingWindow tests
1 parent d8807e8 commit 0bcf2e8

File tree

2 files changed

+147
-2
lines changed

2 files changed

+147
-2
lines changed

src/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,8 +1348,8 @@ export async function fileIsAccessible(fileName: string, mode?: number) {
13481348
export class MovingWindow {
13491349
/** Index of the next slot to be overwritten */
13501350
private writeIndex: number;
1351-
private length: number;
1352-
private samples: Float64Array;
1351+
length: number;
1352+
samples: Float64Array;
13531353

13541354
constructor(windowSize = 10) {
13551355
this.samples = new Float64Array(windowSize);

test/unit/utils.test.ts

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
MongoDBCollectionNamespace,
1515
MongoDBNamespace,
1616
MongoRuntimeError,
17+
MovingWindow,
1718
ObjectId,
1819
shuffle,
1920
TimeoutController
@@ -1045,4 +1046,148 @@ describe('driver utils', function () {
10451046
});
10461047
});
10471048
});
1049+
1050+
describe('class MovingWindow', () => {
1051+
describe('constructor', () => {
1052+
it('Constructs a Float64 array of length windowSize', () => {
1053+
const window = new MovingWindow(10);
1054+
expect(window.samples).to.have.length(10);
1055+
});
1056+
});
1057+
1058+
describe('addSample', () => {
1059+
context('when length < windowSize', () => {
1060+
it('increments the length', () => {
1061+
const window = new MovingWindow(10);
1062+
expect(window.length).to.equal(0);
1063+
1064+
window.addSample(1);
1065+
1066+
expect(window.length).to.equal(1);
1067+
});
1068+
});
1069+
context('when length === windowSize', () => {
1070+
let window: MovingWindow;
1071+
const size = 10;
1072+
1073+
beforeEach(() => {
1074+
window = new MovingWindow(size);
1075+
for (let i = 1; i <= size; i++) {
1076+
window.addSample(i);
1077+
}
1078+
});
1079+
1080+
it('does not increment the length', () => {
1081+
window.addSample(size + 1);
1082+
expect(window.length).to.equal(size);
1083+
});
1084+
1085+
it('overwrites the oldest element', () => {
1086+
window.addSample(size + 1);
1087+
for (const el of window.samples) {
1088+
if (el === 1) expect.fail('Did not overwrite oldest element');
1089+
}
1090+
});
1091+
1092+
it('appends the new element to the end of the window', () => {
1093+
window.addSample(size + 1);
1094+
expect(window.last).to.equal(size + 1);
1095+
});
1096+
});
1097+
});
1098+
1099+
describe('min()', () => {
1100+
context('when length < 2', () => {
1101+
it('returns 0', () => {
1102+
const window = new MovingWindow(10);
1103+
// length 0
1104+
expect(window.min()).to.equal(0);
1105+
1106+
window.addSample(1);
1107+
// length 1
1108+
expect(window.min()).to.equal(0);
1109+
});
1110+
});
1111+
1112+
context('when 2 <= length < windowSize', () => {
1113+
let window: MovingWindow;
1114+
beforeEach(() => {
1115+
window = new MovingWindow(10);
1116+
for (let i = 1; i <= 3; i++) {
1117+
window.addSample(i);
1118+
}
1119+
});
1120+
1121+
it('correctly computes the minimum', () => {
1122+
expect(window.min()).to.equal(1);
1123+
});
1124+
});
1125+
1126+
context('when length == windowSize', () => {
1127+
let window: MovingWindow;
1128+
const size = 10;
1129+
1130+
beforeEach(() => {
1131+
window = new MovingWindow(size);
1132+
for (let i = 1; i <= size * 2; i++) {
1133+
window.addSample(i);
1134+
}
1135+
});
1136+
1137+
it('correctly computes the minimum', () => {
1138+
expect(window.min()).to.equal(size + 1);
1139+
});
1140+
});
1141+
});
1142+
1143+
describe('average()', () => {
1144+
it('correctly computes the mean', () => {
1145+
const window = new MovingWindow(10);
1146+
let sum = 0;
1147+
1148+
for (let i = 1; i <= 10; i++) {
1149+
sum += i;
1150+
window.addSample(i);
1151+
}
1152+
1153+
expect(window.average()).to.equal(sum / 10);
1154+
});
1155+
});
1156+
1157+
describe('last', () => {
1158+
context('when length == 0', () => {
1159+
it('returns null', () => {
1160+
const window = new MovingWindow(10);
1161+
expect(window.last).to.be.null;
1162+
});
1163+
});
1164+
1165+
context('when length > 0', () => {
1166+
it('returns the most recently inserted element', () => {
1167+
const window = new MovingWindow(10);
1168+
for (let i = 0; i < 11; i++) {
1169+
window.addSample(i);
1170+
}
1171+
expect(window.last).to.equal(10);
1172+
});
1173+
});
1174+
});
1175+
1176+
describe('clear', () => {
1177+
let window: MovingWindow;
1178+
1179+
beforeEach(() => {
1180+
window = new MovingWindow(10);
1181+
for (let i = 0; i < 20; i++) {
1182+
window.addSample(i);
1183+
}
1184+
expect(window.length).to.equal(10);
1185+
});
1186+
1187+
it('sets length to 0', () => {
1188+
window.clear();
1189+
expect(window.length).to.equal(0);
1190+
});
1191+
});
1192+
});
10481193
});

0 commit comments

Comments
 (0)