egg/test/lib/core/loader/load_plugin.test.js
Maledong 0d6798d22d docs (Controller.md): Add new feat description (#3066)
Due to https://github.com/eggjs/egg-multipart/pull/19, we have to
add this new feature into Egg's main doc in controller.md to notify
clients.
2018-09-30 19:42:11 +08:00

337 lines
8.9 KiB
JavaScript

'use strict';
const path = require('path');
const fs = require('fs');
const mm = require('egg-mock');
const assert = require('assert');
const AppWorkerLoader = require('../../../../').AppWorkerLoader;
const AgentWorkerLoader = require('../../../../').AgentWorkerLoader;
const utils = require('../../../utils');
const EGG_BASE = path.join(__dirname, '../../../../');
describe('test/lib/core/loader/load_plugin.test.js', () => {
let app;
const logger = console;
before(() => {
app = utils.app('apps/empty');
return app.ready();
});
after(() => app.close());
afterEach(mm.restore);
it('should loadConfig all plugins', () => {
const baseDir = utils.getFilepath('apps/loader-plugin');
const appLoader = new AppWorkerLoader({
baseDir,
app,
logger,
});
appLoader.loadConfig();
assert.deepEqual(appLoader.plugins.b, {
enable: true,
name: 'b',
dependencies: [],
optionalDependencies: [],
env: [],
path: path.join(baseDir, 'node_modules/b'),
from: path.join(baseDir, 'config/plugin.js'),
});
assert.deepEqual(appLoader.plugins.c, {
enable: true,
name: 'c',
dependencies: [],
optionalDependencies: [],
env: [],
path: path.join(baseDir, 'node_modules/c'),
from: path.join(baseDir, 'config/plugin.js'),
});
assert.deepEqual(appLoader.plugins.e, {
enable: true,
name: 'e',
dependencies: [ 'f' ],
optionalDependencies: [],
env: [],
path: path.join(baseDir, 'plugins/e'),
from: path.join(baseDir, 'config/plugin.js'),
});
assert(
appLoader.plugins.onerror.path === fs.realpathSync(path.join(EGG_BASE, 'node_modules/egg-onerror'))
);
assert(appLoader.plugins.onerror.package === 'egg-onerror');
assert(/\d+\.\d+\.\d+/.test(appLoader.plugins.onerror.version));
assert(Array.isArray(appLoader.orderPlugins));
});
it('should same name plugin level follow: app > framework > egg', () => {
const baseDir = utils.getFilepath('apps/loader-plugin');
const appLoader = new AppWorkerLoader({
baseDir,
app,
logger,
});
appLoader.loadConfig();
assert.deepEqual(appLoader.plugins.rds, {
enable: true,
name: 'rds',
dependencies: [ 'session' ],
optionalDependencies: [],
env: [],
package: 'rds',
path: path.join(baseDir, 'node_modules/rds'),
from: path.join(baseDir, 'config/plugin.js'),
});
});
it('should plguin support alias name', () => {
const baseDir = utils.getFilepath('apps/loader-plugin');
const appLoader = new AppWorkerLoader({
baseDir,
app,
logger,
});
appLoader.loadConfig();
assert.deepEqual(appLoader.plugins.d1, {
enable: true,
name: 'd1',
package: 'd',
dependencies: [],
optionalDependencies: [],
env: [],
path: path.join(baseDir, 'node_modules/d'),
from: path.join(baseDir, 'config/plugin.js'),
});
assert(!appLoader.plugins.d);
});
it('should support package.json config', () => {
const baseDir = utils.getFilepath('apps/loader-plugin');
const appLoader = new AppWorkerLoader({
baseDir,
app,
logger,
});
appLoader.loadConfig();
assert.deepEqual(appLoader.plugins.g, {
enable: true,
name: 'g',
dependencies: [ 'f' ],
optionalDependencies: [],
env: [],
path: path.join(baseDir, 'plugins/g'),
from: path.join(baseDir, 'config/plugin.js'),
});
});
it('should show warning message when plugin name wrong', () => {
let message;
mm(console, 'warn', m => {
if (!m.startsWith('[egg:loader] pkg.eggPlugin is missing') && !message) {
message = m;
}
});
const baseDir = utils.getFilepath('apps/loader-plugin');
const appLoader = new AppWorkerLoader({
baseDir,
app,
logger,
});
appLoader.loadConfig();
assert(
message === '[egg:loader] pluginName(e) is different from pluginConfigName(wrong-name)'
);
});
it('should loadConfig plugins with custom plugins config', () => {
const baseDir = utils.getFilepath('apps/loader-plugin');
const plugins = {
foo: {
enable: true,
path: path.join(baseDir, 'node_modules/d'),
},
d1: {
env: [ 'unittest' ],
},
};
const appLoader = new AppWorkerLoader({
baseDir,
plugins,
app,
logger,
});
appLoader.loadConfig();
assert.deepEqual(appLoader.plugins.d1, {
enable: true,
name: 'd1',
package: 'd',
dependencies: [],
optionalDependencies: [],
env: [ 'unittest' ],
path: path.join(baseDir, 'node_modules/d'),
from: path.join(baseDir, 'config/plugin.js'),
});
assert.deepEqual(appLoader.plugins.foo, {
enable: true,
name: 'foo',
dependencies: [],
optionalDependencies: [],
env: [],
path: path.join(baseDir, 'node_modules/d'),
});
assert(!appLoader.plugins.d);
});
it('should throw error when plugin not exists', () => {
assert.throws(function() {
const baseDir = utils.getFilepath('apps/loader-plugin-noexist');
const appLoader = new AppWorkerLoader({
baseDir,
app,
logger,
});
appLoader.loadConfig();
}, /Can not find plugin noexist in /);
});
it('should throw error when app baseDir not exists', () => {
assert.throws(function() {
const baseDir = utils.getFilepath('apps/notexist-app');
const appLoader = new AppWorkerLoader({
baseDir,
app,
logger,
});
appLoader.loadConfig();
}, /notexist-app not exists/);
});
it('should keep plugin list sorted', () => {
mm(process.env, 'NODE_ENV', 'development');
const baseDir = utils.getFilepath('apps/loader-plugin-dep');
const appLoader = new AppWorkerLoader({
baseDir,
app,
logger,
});
appLoader.loadConfig();
assert.deepEqual(appLoader.orderPlugins.map(plugin => {
return plugin.name;
}), [
'session',
'security',
'jsonp',
'onerror',
'i18n',
'watcher',
'schedule',
'multipart',
'development',
'logrotator',
'static',
'view',
'b',
'c1',
'f',
'a',
'd',
'e',
]);
});
it('should throw recursive deps error', () => {
assert.throws(function() {
const baseDir = utils.getFilepath('apps/loader-plugin-dep-recursive');
const appLoader = new AppWorkerLoader({
baseDir,
app,
logger,
});
appLoader.loadConfig();
}, /sequencify plugins has problem, missing: \[\], recursive: \[a,b,c,a\]/);
});
it('should throw error when plugin dep not exists', function() {
assert.throws(function() {
const baseDir = utils.getFilepath('apps/loader-plugin-dep-missing');
const appLoader = new AppWorkerLoader({
baseDir,
app,
logger,
});
appLoader.loadConfig();
}, /sequencify plugins has problem, missing: \[a1\], recursive: \[\]\s+>> Plugin \[a1\] is disabled or missed, but is required by \[c\]/);
});
it('should auto fill plugin infos', () => {
mm(process.env, 'NODE_ENV', 'test');
const baseDir = utils.getFilepath('apps/loader-plugin');
const appLoader1 = new AppWorkerLoader({
baseDir,
app,
logger,
});
appLoader1.loadConfig();
// unittest disable
const keys1 = appLoader1.orderPlugins.map(plugin => {
return plugin.name;
}).join(',');
assert(keys1.includes('b,c,d1,f,e'));
assert(!appLoader1.plugins.a1);
mm(process.env, 'NODE_ENV', 'development');
const appLoader2 = new AppWorkerLoader({
baseDir,
app,
logger,
});
appLoader2.loadConfig();
const keys2 = appLoader2.orderPlugins.map(plugin => {
return plugin.name;
}).join(',');
assert(keys2.includes('d1,a1,b,c,f,e'));
assert.deepEqual(appLoader2.plugins.a1, {
enable: true,
name: 'a1',
dependencies: [ 'd1' ],
optionalDependencies: [],
env: [ 'local', 'prod' ],
path: path.join(baseDir, 'node_modules/a1'),
from: path.join(baseDir, 'config/plugin.js'),
});
});
it('should customize loadPlugin', () => {
const baseDir = utils.getFilepath('apps/loader-plugin');
class CustomAppLoader extends AppWorkerLoader {
loadPlugin() {
this.hasAppLoadPlugin = true;
super.loadPlugin();
}
}
const appLoader = new CustomAppLoader({
baseDir,
app,
logger,
});
appLoader.loadConfig();
assert(appLoader.hasAppLoadPlugin === true);
class CustomAgentLoader extends AgentWorkerLoader {
loadPlugin() {
this.hasAgentLoadPlugin = true;
super.loadPlugin();
}
}
const agentLoader = new CustomAgentLoader({
baseDir,
app,
logger,
});
agentLoader.loadConfig();
assert(agentLoader.hasAgentLoadPlugin === true);
});
});