it("should update series without exceeding limit", () => { options.layoutConfig.view.limit = 3; options.series.high = { highwater: true }; const baseGraph = new BaseLineGraph(options); baseGraph.update({ a: 27, high: 27 }); expect(baseGraph).to.have.nested.property("series.a.y").that.deep.equals([0, 0, 27]); expect(baseGraph).to.have.nested.property("series.high.y").that.deep.equals([27, 27, 27]); });
describe("_createGraph", () => { it("should create a blessed-contrib line graph", () => { sandbox.spy(testContainer, "append"); options.layoutConfig.view.limit = 8; sandbox.stub(BaseLineGraph.prototype, "_createGraph"); const baseGraph = new BaseLineGraph(options); BaseLineGraph.prototype._createGraph.restore(); expect(baseGraph).to.not.have.property("node"); baseGraph._createGraph(options); expect(baseGraph).to.have.property("node").that.is.an.instanceof(contrib.line); expect(baseGraph.node).to.have.nested.property("options.label", " graph A "); expect(baseGraph.node).to.have.nested.property("options.maxY", undefined); expect(baseGraph.node).to.have.property("position") .that.deep.equals(options.layoutConfig.getPosition(options.parent)); expect(testContainer.append).to.have.been.calledOnce.and.calledWithExactly(baseGraph.node); }); });
describe("constructor", () => { beforeEach(() => { sandbox.stub(BaseLineGraph.prototype, "_createGraph"); }); it("should use limit from layoutConfig", () => { const limit = 7; options.layoutConfig.view.limit = limit; const baseGraph = new BaseLineGraph(options); expect(baseGraph).to.have.property("limit", limit); expect(baseGraph).to.have.nested.property("series.a.y") .that.deep.equals(_.times(limit, _.constant(0))); }); it("should create graph and set up event listener", () => { const baseGraph = new BaseLineGraph(options); expect(baseGraph).to.be.an.instanceof(BaseView); expect(baseGraph._createGraph).to.have.been.calledOnce; expect(testContainer.screen.on).to.have.been.calledWithExactly("metrics", sinon.match.func); }); });
describe("onEvent", () => { it("should call update for each gauge", () => { const memory = new MemoryGaugeView(options); expect(memory).to.have.property("heapGauge").that.is.an.instanceof(contrib.gauge); expect(memory).to.have.property("rssGauge").that.is.an.instanceof(contrib.gauge); sandbox.stub(memory, "update"); const mem = { heapUsed: 23, heapTotal: 39, rss: 290, systemTotal: 80010 }; memory.onEvent({ mem }); expect(memory.update).to.have.been.calledTwice .and.to.have.been.calledWithExactly(memory.heapGauge, mem.heapUsed, mem.heapTotal) .and.to.have.been.calledWithExactly(memory.rssGauge, mem.rss, mem.systemTotal); }); });
it("should create fullscreen view", () => { const layouts = createPanel([{ views: [ { type: "memory" } ] }]); expect(layouts.views[0]).to.have.property("getPosition").that.is.a("function"); expect(layouts.views[0].getPosition(parent)).to.be.deep.equal({ left: 0, top: 0, width: parent.width, height: parent.height }); });
describe("HelpView", () => { let sandbox; let testContainer; before(() => { sandbox = sinon.createSandbox(); }); beforeEach(() => { utils.stubWidgets(sandbox); testContainer = utils.getTestContainer(sandbox); }); afterEach(() => { sandbox.restore(); }); it("should create a box with text describing keybindings", () => { const help = new HelpView({ parent: testContainer }); expect(help).to.have.property("node").that.is.an.instanceof(blessed.box); expect(help.node).to.have.nested.property("options.content").that.contains("keybindings"); expect(help.node).to.have.property("hidden", true); }); });
/* eslint-disable no-magic-numbers */ it("should update series and label", () => { options.layoutConfig.view.limit = 4; options.layoutConfig.view.title = "cpu"; options.unit = "%"; const baseGraph = new BaseLineGraph(options); expect(baseGraph).to.have.nested.property("series.a.y").that.deep.equals([0, 0, 0, 0]); baseGraph.update({ a: 29 }); expect(baseGraph).to.have.nested.property("series.a.y").that.deep.equals([0, 0, 0, 29]); expect(baseGraph.node.setLabel).to.have.been.calledWith(" cpu (29%) "); baseGraph.update({ a: 8 }); expect(baseGraph).to.have.nested.property("series.a.y").that.deep.equals([0, 0, 29, 8]); expect(baseGraph.node.setLabel).to.have.been.calledWith(" cpu (8%) "); });
describe("constructor", () => { it("should require logProvider", () => { options.logProvider = undefined; expect(() => { new StreamView(options); // eslint-disable-line no-new }).to.throw("StreamView requires logProvider"); }); it("should create a log node and listen for given events", () => { const streamView = new StreamView(options); expect(streamView).to.have.property("node").that.is.an.instanceof(blessed.log); expect(streamView.node).to.have.nested.property("options.label", " stdout / stderr "); expect(testContainer.screen.on).to.have.been .calledWithExactly("stdout", sinon.match.func) .and.calledWithExactly("stderr", sinon.match.func); }); });
describe("resetGraphs", () => { it("resets zoom level and scroll offsets", () => { sandbox.stub(metricsProvider, "setZoomLevel").callsFake((zoom) => { expect(zoom) .to.be.a("number") .that.equals(0); }); _.each(AGGREGATE_TIME_LEVELS, (level) => { expect(metricsProvider) .to.be.an("object") .with.property("_aggregation") .which.is.an("object") .with.property(level) .which.is.an("object") .with.property("scrollOffset") .which.is.a("number") .that.equals(0); }); metricsProvider.resetGraphs(); }); });
it("creates missing average even if first", () => { const timeKey = AGGREGATE_TIME_LEVELS[0]; const timeLength = Number(timeKey); // Fill 2 time slots skiping the first // 2 slots are needed to cause average calculation const mockMetrics = fill(2, timeLength); expect(metricsProvider._aggregation[timeKey].data) .to.be.an("array") .that.eql([ { metricA: { valueA: 0 }, metricB: { valueA: 0, valueB: 0 } }, mapToAverage(mockMetrics[0]) ]); });
describe("constructor", () => { it("should create a box with two gauges and listen for metrics event", () => { const append = sandbox.spy(blessed.node.prototype, "append"); const memory = new MemoryGaugeView(options); expect(memory).to.have.property("node").that.is.an.instanceof(blessed.box); expect(memory.node).to.have.nested.property("options.label", " memory "); expect(append.thirdCall).to.have.been.calledOn(testContainer) .and.calledWithExactly(memory.node); expect(testContainer.screen.on).to.have.been.calledWithExactly("metrics", sinon.match.func); expect(memory).to.have.property("heapGauge").that.is.an.instanceof(contrib.gauge); expect(memory.heapGauge).to.have.nested.property("options.label", "heap"); expect(append.firstCall).to.have.been.calledOn(memory.node) .and.calledWithExactly(memory.heapGauge); expect(memory).to.have.property("rssGauge").that.is.an.instanceof(contrib.gauge); expect(memory.rssGauge).to.have.nested.property("options.label", "resident"); expect(append.secondCall).to.have.been.calledOn(memory.node) .and.calledWithExactly(memory.rssGauge); }); });
it("should update highwater series", () => { options.layoutConfig.view.limit = 3; options.series.high = { highwater: true }; const baseGraph = new BaseLineGraph(options); expect(baseGraph).to.have.nested.property("series.a.y").that.deep.equals([0, 0, 0]); expect(baseGraph).to.have.nested.property("series.high").that.deep.equals({ x: [":02", ":01", ":00"], y: [0, 0, 0], style: { line: "red" } }); baseGraph.update({ a: 2, high: 4 }); expect(baseGraph).to.have.nested.property("series.a.y").that.deep.equals([0, 0, 2]); expect(baseGraph).to.have.nested.property("series.high").that.deep.equals({ x: [":02", ":01", ":00"], y: [4, 4, 4], style: { line: "red" } }); expect(baseGraph.node.setLabel).to.have.been.calledWith(" graph A (2), high (4) "); });
describe("startGraphs", () => { it("offsets at the end or the beginning of the data set", () => { // load some data fill(100, 500); sandbox.stub(metricsProvider, "adjustScrollOffset").callsFake((direction) => { let length = metricsProvider._aggregation[AGGREGATE_TIME_LEVELS[0]].data.length; length = direction < 0 ? -length : Number(length); expect(direction) .to.be.a("number") .that.equals(length); }); metricsProvider.startGraphs(-1); metricsProvider.startGraphs(+1); }); });
// receiving metrics now would cause an emit sandbox.stub(metricsProvider, "emit").callsFake((key, data, discardEvent) => { if (discardEvent) { return; } expect(key) .to.be.a("string") .that.equals("metrics"); expect(data) .to.be.an("object") .that.deep.equals( _.last(metricsProvider._aggregation[metricsProvider.zoomLevelKey].data) ); });