webpack-dashboard/test/plugin/index.spec.js
Ryan Roemer 0a11e7e6ae
Chore: Various plugin refactoring and simplification. (#332)
Refactors the plugin internal logic to be a lot simpler. 

- Chore: Refactor internal stats consumption to perform `inspectpack` analysis in the main thread, without using `main` streams. Originally, the `inspectpack` engine did some really heavy CPU stuff (gzipping lots of files), but now the actions are super fast, so I've removed `most` async observables and just switched to straight promises.
- Chore: Refactor internal handler in plugin to always be a wrapped function so that we can't accidentally have asynchronous code call the handler function after it is removed / nulled.
- Bugfix: Add message counting delayed cleanup in plugin to allow messages to drain in Dashboard. The issue seems to be that we hit socket IO disconnect in the plugin before the dashboard actually processes the messages. Fixes #294.
2021-07-12 12:27:50 -07:00

165 lines
4.2 KiB
JavaScript

"use strict";
const inspectpackActions = require("inspectpack/lib/actions");
const base = require("../base.spec");
const Plugin = require("../../plugin");
const errorSerializer = require("../../utils/error-serialization");
describe("plugin", () => {
const options = {
port: 3000,
host: "111.0.2.3"
};
it("can create a new no option plugin", () => {
const plugin = new Plugin();
expect(plugin).to.be.ok;
expect(plugin.host).to.equal("127.0.0.1");
// eslint-disable-next-line no-magic-numbers
expect(plugin.port).to.equal(9838);
expect(plugin._handler).to.be.null;
expect(plugin.watching).to.be.false;
});
it("can create a new with options dashboard", () => {
const pluginWithOptions = new Plugin(options);
expect(pluginWithOptions.host).to.equal("111.0.2.3");
// eslint-disable-next-line no-magic-numbers
expect(pluginWithOptions.port).to.equal(3000);
});
describe("plugin methods", () => {
let stats;
let toJson;
let compilation;
let compiler;
let plugin;
beforeEach(() => {
stats = {
modules: [],
assets: []
};
toJson = base.sandbox.stub().callsFake(() => stats);
compilation = {
errors: [],
warnings: [],
getStats: () => ({ toJson }),
tap: base.sandbox.stub(),
tapAsync: base.sandbox.stub() // this is us in webpack-dashboard
};
compiler = {
// mock out webpack4 compiler, since that's what we have in devDeps
hooks: {
compilation,
emit: {
intercept: base.sandbox.stub()
},
watchRun: {
tapAsync: base.sandbox.stub()
},
run: {
tapAsync: base.sandbox.stub()
},
compile: {
tap: base.sandbox.stub()
},
failed: {
tap: base.sandbox.stub()
},
invalid: {
tap: base.sandbox.stub()
},
done: {
tap: base.sandbox.stub()
}
}
};
plugin = new Plugin();
});
it("can do a basic compilation", () => {
expect(() => plugin.apply(compiler)).to.not.throw;
// after instantiation, test that we can hit getMetrics
expect(() => plugin.getMetrics({ toJson })).to.not.throw;
});
it("can do a basic getMetrics", () => {
const actions = base.sandbox.spy(inspectpackActions, "actions");
return (
plugin
.getMetrics({ toJson })
// eslint-disable-next-line promise/always-return
.then(() => {
expect(actions).to.have.been.calledThrice;
})
);
});
it("filters assets for includeAssets", () => {
const actions = base.sandbox.spy(inspectpackActions, "actions");
stats = {
assets: [
{
name: "one.js",
modules: []
},
{
name: "two.js",
modules: []
},
{
name: "three.js",
modules: []
}
]
};
plugin = new Plugin({
includeAssets: [
"one", // string prefix
/tw/ // regex match
]
});
return (
plugin
.getMetrics({ toJson })
// eslint-disable-next-line promise/always-return
.then(() => {
expect(actions).to.have.been.calledWith("sizes", {
stats: {
assets: [
{ modules: [], name: "one.js" },
{ modules: [], name: "two.js" }
]
}
});
})
);
});
it("should serialize errors when encountered", () => {
const actions = base.sandbox.stub(inspectpackActions, "actions").rejects();
const serializeError = base.sandbox.spy(errorSerializer, "serializeError");
return (
plugin
.getMetrics({ toJson })
// eslint-disable-next-line promise/always-return
.then(() => {
// All three actions called.
expect(actions).to.have.been.calledThrice;
// ... but since two are in Promise.all only get one rejection.
expect(serializeError).to.have.been.calledTwice;
})
);
});
});
});