Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: homework #118

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Karma configuration
// Generated on Fri Aug 11 2017 22:02:05 GMT+0800 (CST)
process.env.CHROME_BIN = require('puppeteer').executablePath()
module.exports = function(config) {
config.set({

Expand Down
46 changes: 39 additions & 7 deletions lib/db.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,45 @@
const Tapable = require('tapable')
const {
SyncWaterfallHook,
AsyncSeriesWaterfallHook
} = require('tapable');

class DB extends Tapable {
constructor() {
// TODO


class DB {
constructor(options) {
this.options = options || {};
this.hooks = {
endpoint: new AsyncSeriesWaterfallHook(['options']),
options: new SyncWaterfallHook(['options']),
judge: new SyncWaterfallHook(['res'])
}
}

useExtendOptions(options) {
const pluginOptions = this.hooks.options.call(this.options);
Object.keys(pluginOptions).forEach(item => {
if (pluginOptions.hasOwnProperty(item)) {
options[item] = pluginOptions[item];
}
});
return options;
}

request() {
// TODO
request(options) {
const extendsOptions = this.useExtendOptions(options);
return this.hooks.endpoint.promise(extendsOptions)
.then(
res => {
if (!this.hooks.judge.call(res)) {
return Promise.reject(res);
}
return res;
}
)
.catch(err => {
return Promise.reject(err);
});
}
}

module.exports = DB
module.exports = DB;
15 changes: 4 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "test",
"main": "index.js",
"scripts": {
"test": "karma start"
"test": "jest"
},
"repository": {
"type": "git",
Expand All @@ -20,14 +20,7 @@
},
"homepage": "https://github.com/FE-star/homework2#readme",
"devDependencies": {
"karma": "^6.3.16",
"karma-chrome-launcher": "^2.2.0",
"karma-mocha": "^1.3.0",
"karma-webpack": "^2.0.4",
"mocha": "^3.5.0",
"webpack": "^3.5.3"
},
"dependencies": {
"puppeteer": "^16.2.0"
"jest": "^28.1.3",
"tapable": "^1.1.3"
}
}
}
244 changes: 94 additions & 150 deletions test/test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
let DB = require('../lib/db')
let DB = require('../lib/db');
// just for the real answer, please ignore
// if (!DB.prototype.request) {
// DB = require('../lib/.db')
// }
const assert = require('assert')
const assert = require('assert');

describe('DB', function () {
it('可以设置options', function () {
Expand All @@ -13,21 +13,14 @@ describe('DB', function () {
})

it('可以设置endpoint插件,使得该请求用制定的方式处理', function (done) {
class XX extends DB {
constructor(options) {
super(options)

this.plugin('endpoint', function () {
return new Promise((resolve) => {
setTimeout(() => {
resolve({ retcode: 0, res: { msg: 'hello world' } })
}, 0)
})
})
}
}

const xx = new XX()
const xx = new DB();
xx.hooks.endpoint.tapPromise('endpointPlugin1', () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve({ retcode: 0, res: { msg: 'hello world' } });
}, 0);
})
});
xx.request()
.then((res) => {
assert.equal(res.res.msg, 'hello world')
Expand All @@ -36,31 +29,19 @@ describe('DB', function () {
})

it('可以根据不同的options,使用不同的endpoint', function (done) {
class AA extends DB {
constructor(options) {
super(options)
this.plugin('endpoint', function (options) {
if (options.type === 1) {
return new Promise((resolve) => {
setTimeout(() => {
resolve({ retcode: 1, msg: 'logout' })
}, 0)
})
}
})
this.plugin('endpoint', function (options) {
if (options.type === 0) {
return new Promise((resolve) => {
setTimeout(() => {
resolve({ retcode: 0, res: { msg: 'hello world' } })
}, 0)
})
}
})
}
}

const aa = new AA
const aa = new DB();
aa.hooks.endpoint.tapPromise('endpointPlugin2', (options) => {
return new Promise((resolve) => {
if (options.type === 1) {
setTimeout(() => {
resolve({ retcode: 1 });
}, 0);
}
if (options.type === 0) {
resolve({ retcode: 0 });
}
});
});
// 如果 options.type === 1,则返回第一个答案
aa.request({ type: 1 })
.then(res => {
Expand All @@ -74,136 +55,99 @@ describe('DB', function () {
})

it('可以设置options插件来处理options', function (done) {
class YY extends DB {
constructor(options) {
super(options)
this.plugin('options', (options) => {
// modify options
options.flag = true
return options
})
this.plugin('endpoint', (options) => {
// init
assert.equal(options.init, true)
// merge
assert.equal(options.url, 'my://hello')
// options plugin modify
assert.equal(options.flag, true)

return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ retcode: 0, res: { msg: 'hello world' } })
}, 0)
})
})
}
}

const yy = new YY({ init: true })
const yy = new DB({ init: true });
yy.hooks.options.tap('optionsPlugin1', (options) => {
options.flag = true;
return options;
});
yy.hooks.endpoint.tapPromise('endpointPlugin3', (options) => {
assert.equal(options.init, true);
assert.equal(options.url, 'my://hello');
assert.equal(options.flag, true);
return new Promise((resolve) => {
setTimeout(() => {
resolve({ retcode: 0, res: { msg: 'hello world' } })
}, 0)
});
})
yy.request({ url: 'my://hello' })
.then((res) => {
assert.equal(res.res.msg, 'hello world');
done()
})
});
})

it('可以设置多个options插件', function (done) {
class BB extends DB {
constructor(options) {
super(options)
this.plugin('options', (options) => {
// modify options
options.flag = true
return options
})
this.plugin('options', (options) => {
// modify options,后面的覆盖前面的
options.flag = false
return options
})
this.plugin('options', (options) => {
options.url = 'you://hello'
return options
})
this.plugin('endpoint', (options) => {
// init
assert.equal(options.init, true)
// merge
assert.equal(options.url, 'you://hello')
// options plugin modify
assert.equal(options.flag, false)

return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ retcode: 0, res: { msg: 'hello world' } })
}, 0)
})
})
}
}

const bb = new BB({ init: true })
const bb = new DB({ init: true });
bb.hooks.options.tap('optionsPlugin2', (options) => {
options.flag = true;
return options;
});
bb.hooks.options.tap('optionsPlugin3', (options) => {
options.flag = false;
return options;
});
bb.hooks.options.tap('optionsPlugin4', (options) => {
options.url = 'you://hello';
return options;
});
bb.hooks.endpoint.tapPromise('endpointPlugin4', (options) => {
assert.equal(options.init, true);
assert.equal(options.url, 'you://hello');
assert.equal(options.flag, false);
return new Promise((resolve) => {
setTimeout(() => {
resolve({ retcode: 0, res: { msg: 'hello world' } });
}, 0);
})
})
bb.request({ url: 'my://hello' })
.then((res) => {
done()
})
})

it('可以通过judge插件判断返回是否正确', function (done) {
class CC extends DB {
constructor(options) {
super(options)
this.plugin('endpoint', function (options) {
if (options.type === 1) {
return new Promise((resolve) => {
setTimeout(() => {
resolve({ retcode: 1, msg: 'logout' })
}, 0)
})
}
})
this.plugin('endpoint', function (options) {
if (options.type === 0) {
return new Promise((resolve) => {
setTimeout(() => {
resolve({ retcode: 0, res: { msg: 'hello world' } })
}, 0)
})
}
})

this.plugin('judge', function (res) {
if (res.retcode !== 0) return true
})
const cc = new DB();
cc.hooks.endpoint.tapPromise('endpoingPlugin5', (options) => {
if (options.type === 0) {
return new Promise((resolve) => {
setTimeout(() => {
resolve({ retcode: 0, res: { msg: 'hello world' } })
}, 0);
});
}
}

const cc = new CC
if (options.type === 1) {
return new Promise((resolve) => {
setTimeout(() => {
resolve({ retcode: 1, msg: 'logout' })
}, 0);
});
}
});
cc.hooks.judge.tap('judgePlugin1', (res) => {
return res.retcode === 0;
});
cc.request({ type: 0 })
.then((res) => {
assert.equal(res.res.msg, 'hello world')
return cc.request({ type: 1 })
assert.equal(res.res.msg, 'hello world');
return cc.request({ type: 1 });
}).then((res) => {
done(new Error('不应该进入正确回调,应当进入失败回调,因为retcode为1'))
done(new Error('不应该进入正确回调,应当进入失败回调,因为retcode为1'));
}, (res) => {
assert.equal(res.retcode, 1)
assert.equal(res.msg, 'logout')
done()
assert.equal(res.retcode, 1);
assert.equal(res.msg, 'logout');
done();
})
})

it('可以reject数据', function (done) {
class ZZ extends DB {
constructor(options) {
super(options)
this.plugin('endpoint', function () {
return new Promise((resolve, reject) => {
reject()
})
})
}
}

const zz = new ZZ
const zz = new DB();
zz.hooks.endpoint.tapPromise('endpointPlugin6', () => {
return new Promise((resolve, reject) => {
reject();
});
});

zz.request()
.then(() => {
Expand Down