diff --git a/package.json b/package.json index 2ac412e..3e306a4 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,8 @@ "pre-commit": "^1.2.2", "validate-commit-msg": "^2.14.0", "webpack": "^4.29.3", - "webpack-cli": "^3.2.3" + "webpack-cli": "^3.2.3", + "lodash": "^4.17.11" }, "config": { "commitizen": { diff --git a/src/class/host.js b/src/class/host.js index 95b4051..8944225 100644 --- a/src/class/host.js +++ b/src/class/host.js @@ -260,6 +260,8 @@ class Host { const theHost = this; let plgs = plugins; + if (!plgs) throw new Error('params is required'); + // compatibel array and object if (plgs && !Array.isArray(plgs)) plgs = [plugins]; diff --git a/test/interation/main.js b/test/interation/main.js index eb88f46..6efe54c 100644 --- a/test/interation/main.js +++ b/test/interation/main.js @@ -1,4 +1,5 @@ import test from 'ava'; +import _ from 'lodash'; export default function main({ BtApp, BtPage }) { test('[BtPlugin] options.relyOn', (t) => { @@ -199,24 +200,74 @@ export default function main({ BtApp, BtPage }) { }, beforeAttach({ theHost }) { const plugin = this; - return Promise - .resolve() - .then(() => new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, 100); - })) - .then(() => { - t.is(plugin.name, pluginContent.data.name); - t.is(theHost.name, appInfo.name); - t.end(); - }); + t.is(plugin.name, pluginContent.data.name); + t.is(theHost.name, appInfo.name); + + // theHost is still instanceof BtApp + t.truthy(theHost instanceof BtApp); + + // custom method not ready + t.is(theHost[plugin.name], undefined); + + // data, handlers not ready + t.is(_.get(theHost, `data.${plugin.name}`), undefined); + t.is(theHost.onClick, undefined); + + t.end(); + }, + customMethod: { + sayHello() { + return { msg: 'hello', context: this }; + }, + }, + handler: { + onClick() { + return 'clicked'; + }, + }, + }; + const pluginA = (pluginContent); + const app = new BtApp(appInfo); + + app.use(pluginA); + }); + + test.cb('[BtPlugin] attached', (t) => { + const appInfo = { + name: Symbol, + }; + const pluginContent = { + name: 'pluginA', + data: { + name: 'pluginA', + }, + attached({ theHost }) { + const plugin = this; + t.is(plugin.name, pluginContent.data.name); + t.is(theHost.name, appInfo.name); + + // theHost is still instanceof BtApp + t.truthy(theHost instanceof BtApp); + + // custom method not ready + t.is(theHost[plugin.name], undefined); + + // data, handlers was ready + t.deepEqual(_.get(theHost, `data.${plugin.name}`), pluginContent.data); + t.is(typeof theHost.onClick, 'function'); + + t.end(); }, customMethod: { sayHello() { return { msg: 'hello', context: this }; }, }, + handler: { + onClick() { + return 'clicked'; + }, + }, }; const pluginA = (pluginContent); const app = new BtApp(appInfo); @@ -224,6 +275,76 @@ export default function main({ BtApp, BtPage }) { app.use(pluginA); }); + test.cb('[BtPlugin] initialize', (t) => { + const appInfo = { + name: Symbol, + }; + const pluginContent = { + name: 'pluginA', + data: { + name: 'pluginA', + }, + initialize({ theHost }) { + const plugin = this; + t.is(plugin.name, pluginContent.data.name); + t.is(theHost.name, appInfo.name); + + // theHost is not instanceof BtApp anymore + t.falsy(theHost instanceof BtApp); + + // custom method should ready + t.is(typeof theHost[plugin.name].sayHello, 'function'); + + // data, handlers was ready + t.deepEqual(_.get(theHost, `data.${plugin.name}`), pluginContent.data); + t.is(typeof theHost.onClick, 'function'); + + t.end(); + }, + customMethod: { + sayHello() { + return { msg: 'hello', context: this }; + }, + }, + handler: { + onClick() { + return 'clicked'; + }, + }, + }; + const pluginA = (pluginContent); + const app = new BtApp(appInfo); + + app.use(pluginA); + + // mock App + class App { + constructor(btApp) { + Object.assign(this, btApp); + } + } + const mockNativeAppInstance = new App(app); + mockNativeAppInstance.onLaunch(); + }); + + test.cb('[BtPlugin] name is required', (t) => { + const error = t.throws(() => { + const app = new BtApp(); + app.use({}); + }); + t.is(error.message, '[BeautyWe:error] params of name are required when create a BtPlugin.'); + t.end(); + }); + + test.cb('[BtPlugin] use params is required', (t) => { + const error = t.throws(() => { + const app = new BtApp(); + app.use(); + }); + t.is(error.message, 'params is required'); + t.end(); + }); + test('[BtPlugin] should run funstacks in sequence', (t) => { const status = { timestamp: {