From e7c5d78a92814e7fc3c085e3266db1bbd824833c Mon Sep 17 00:00:00 2001 From: "TZU-YEN, CHANG" Date: Mon, 4 May 2020 02:54:07 +0800 Subject: [PATCH] feat(bin): add the full feature and some e2e test --- example/manual.ts | 4 +- packages/bin/e2e/route.js | 9 +++ packages/bin/e2e/route.ts | 8 +++ packages/bin/e2e/routes.js | 27 ++++++++ packages/bin/e2e/routes.ts | 24 +++++++ packages/bin/e2e/single.js | 5 ++ packages/bin/e2e/single.ts | 4 ++ packages/bin/package.json | 4 +- packages/bin/src/index.spec.ts | 122 +++++++++++++++++++++++++++++++++ packages/bin/src/index.ts | 31 ++++++--- packages/ton/src/index.ts | 2 +- yarn.lock | 22 ++++-- 12 files changed, 243 insertions(+), 19 deletions(-) create mode 100644 packages/bin/e2e/route.js create mode 100644 packages/bin/e2e/route.ts create mode 100644 packages/bin/e2e/routes.js create mode 100644 packages/bin/e2e/routes.ts create mode 100644 packages/bin/e2e/single.js create mode 100644 packages/bin/e2e/single.ts create mode 100644 packages/bin/src/index.spec.ts diff --git a/example/manual.ts b/example/manual.ts index 05a7b89..24b2063 100644 --- a/example/manual.ts +++ b/example/manual.ts @@ -1,4 +1,3 @@ -/* eslint-disable no-console */ import { send, redirect, @@ -7,6 +6,7 @@ import { registerGracefulShutdown, route } from '../packages/ton/src' +import * as logger from '../packages/logger' const host = '0.0.0.0' const port = 3000 @@ -19,7 +19,7 @@ async function main() { ) const token = await listen(app, host, port) registerGracefulShutdown(token) - console.info(`\nyou raise me up, to listen on http://${host}:${port}\n`) + logger.info(`\nyou raise me up, to listen on http://${host}:${port}\n`) } main() diff --git a/packages/bin/e2e/route.js b/packages/bin/e2e/route.js new file mode 100644 index 0000000..91c0d73 --- /dev/null +++ b/packages/bin/e2e/route.js @@ -0,0 +1,9 @@ +/** + * @type {import('@tonjs/ton').TonRoute} + */ +const route = { + methods: 'get', + pattern: '/', + handler: () => 'Hi There!' +} +module.exports = route diff --git a/packages/bin/e2e/route.ts b/packages/bin/e2e/route.ts new file mode 100644 index 0000000..ced83d0 --- /dev/null +++ b/packages/bin/e2e/route.ts @@ -0,0 +1,8 @@ +import { TonRoute } from '@tonjs/ton' + +const route: TonRoute = { + methods: 'get', + pattern: '/', + handler: () => 'Hi There!' +} +export default route diff --git a/packages/bin/e2e/routes.js b/packages/bin/e2e/routes.js new file mode 100644 index 0000000..ef76973 --- /dev/null +++ b/packages/bin/e2e/routes.js @@ -0,0 +1,27 @@ +const { sendText, sendEmpty } = require('@tonjs/ton') + +/** + * @type {import('@tonjs/ton').TonRoutes} + */ +const routes = [ + { + methods: 'get', + pattern: '/', + handler: (req, res) => sendText(res, 200, 'TonJS') + }, + { + methods: 'get', + pattern: '/empty', + handler: (req, res) => sendEmpty(res) + }, + { + methods: 'any', + pattern: '/ping', + handler: function pong() { + return { + result: 'pong' + } + } + } +] +module.exports = routes diff --git a/packages/bin/e2e/routes.ts b/packages/bin/e2e/routes.ts new file mode 100644 index 0000000..82cb1aa --- /dev/null +++ b/packages/bin/e2e/routes.ts @@ -0,0 +1,24 @@ +import { TonRoutes, sendEmpty, sendText } from '@tonjs/ton' + +const routes: TonRoutes = [ + { + methods: 'get', + pattern: '/', + handler: (req, res) => sendText(res, 200, 'TonJS') + }, + { + methods: 'get', + pattern: '/empty', + handler: (req, res) => sendEmpty(res) + }, + { + methods: 'any', + pattern: '/ping', + handler: function pong() { + return { + result: 'pong' + } + } + } +] +export default routes diff --git a/packages/bin/e2e/single.js b/packages/bin/e2e/single.js new file mode 100644 index 0000000..453dd23 --- /dev/null +++ b/packages/bin/e2e/single.js @@ -0,0 +1,5 @@ +/** + * @type {import('@tonjs/ton').TonHandler} + */ +const handler = () => 'Hi There!' +module.exports = handler diff --git a/packages/bin/e2e/single.ts b/packages/bin/e2e/single.ts new file mode 100644 index 0000000..3883956 --- /dev/null +++ b/packages/bin/e2e/single.ts @@ -0,0 +1,4 @@ +import { TonHandler } from '@tonjs/ton' + +const single: TonHandler = () => 'Hi There!' +export default single diff --git a/packages/bin/package.json b/packages/bin/package.json index 27fdfc9..7895ccc 100644 --- a/packages/bin/package.json +++ b/packages/bin/package.json @@ -37,10 +37,12 @@ "build": "tsc" }, "dependencies": { + "@tonjs/logger": "0.0.0", "@tonjs/ton": "0.0.0", "yargs": "^15.3.1" }, "devDependencies": { - "@types/yargs": "^15.0.4" + "@types/yargs": "^15.0.4", + "axios": "^0.19.2" } } diff --git a/packages/bin/src/index.spec.ts b/packages/bin/src/index.spec.ts new file mode 100644 index 0000000..9a5dbca --- /dev/null +++ b/packages/bin/src/index.spec.ts @@ -0,0 +1,122 @@ +// eslint-disable-next-line import/no-extraneous-dependencies +import axios from 'axios' +import path from 'path' +import { TonApp, TonListenSocket, close } from '@tonjs/ton' +import bin from './index' + +let logLevel = process.env.LOG_LEVEL +let instance: { app: TonApp; token: TonListenSocket } + +beforeAll(() => { + logLevel = process.env.LOG_LEVEL + process.env.LOG_LEVEL = 'silent' +}) + +afterAll(() => { + if (logLevel) { + process.env.LOG_LEVEL = logLevel + } +}) + +afterEach(() => { + close(instance.token) +}) + +describe('e2e', () => { + it('should import TonHandler TS', async () => { + instance = await bin({ + host: '0.0.0.0', + port: 4000, + _: ['packages/bin/e2e/single.ts'] + }) + expect(instance.token).not.toBe(undefined) + const { data, status } = await axios.get('http://0.0.0.0:4000') + expect(status).toBe(200) + expect(data).toBe('Hi There!') + }) + + it('should import TonHandler JS', async () => { + instance = await bin({ + host: '0.0.0.0', + port: 4000, + _: ['packages/bin/e2e/single.js'] + }) + expect(instance.token).not.toBe(undefined) + const { data, status } = await axios.get('http://0.0.0.0:4000') + expect(status).toBe(200) + expect(data).toBe('Hi There!') + }) + + it('should import TonRoute TS', async () => { + instance = await bin({ + host: '0.0.0.0', + port: 4000, + _: ['packages/bin/e2e/route.ts'] + }) + expect(instance.token).not.toBe(undefined) + const { data, status } = await axios.get('http://0.0.0.0:4000') + expect(status).toBe(200) + expect(data).toBe('Hi There!') + }) + + it('should import TonRoute JS', async () => { + instance = await bin({ + host: '0.0.0.0', + port: 4000, + _: ['packages/bin/e2e/route.js'] + }) + expect(instance.token).not.toBe(undefined) + const { data, status } = await axios.get('http://0.0.0.0:4000') + expect(status).toBe(200) + expect(data).toBe('Hi There!') + }) + + it('should import TonRoutes TS', async () => { + instance = await bin({ + host: '0.0.0.0', + port: 4000, + _: ['packages/bin/e2e/routes.ts'] + }) + expect(instance.token).not.toBe(undefined) + + const resRoot = await axios.get('http://0.0.0.0:4000') + expect(resRoot.status).toBe(200) + expect(resRoot.data).toBe('TonJS') + + const resEmpty = await axios.get('http://0.0.0.0:4000/empty') + expect(resEmpty.status).toBe(204) + + const resPing = await axios.get('http://0.0.0.0:4000/ping') + expect(resPing.status).toBe(200) + expect(resPing.data).toEqual({ result: 'pong' }) + }) + + it('should import TonRoutes JS', async () => { + instance = await bin({ + host: '0.0.0.0', + port: 4000, + _: ['packages/bin/e2e/routes.js'] + }) + expect(instance.token).not.toBe(undefined) + + const resRoot = await axios.get('http://0.0.0.0:4000') + expect(resRoot.status).toBe(200) + expect(resRoot.data).toBe('TonJS') + + const resEmpty = await axios.get('http://0.0.0.0:4000/empty') + expect(resEmpty.status).toBe(204) + + const resPing = await axios.get('http://0.0.0.0:4000/ping') + expect(resPing.status).toBe(200) + expect(resPing.data).toEqual({ result: 'pong' }) + }) + + it('should use index.js as default entry', async () => { + try { + await bin({ host: '0.0.0.0', port: 4000, _: [] }) + } catch (err) { + // eslint-disable-next-line jest/no-try-expect + expect(err.moduleName).toBe(path.resolve(process.cwd(), 'index.js')) + } + }) +}) diff --git a/packages/bin/src/index.ts b/packages/bin/src/index.ts index 5152378..af49042 100644 --- a/packages/bin/src/index.ts +++ b/packages/bin/src/index.ts @@ -1,4 +1,3 @@ -/* eslint-disable no-console */ import path from 'path' import { TonHandler, @@ -8,12 +7,14 @@ import { createApp, listen, routes, - registerGracefulShutdown + registerGracefulShutdown, + TonApp } from '@tonjs/ton' +import * as logger from '@tonjs/logger' import yargs = require('yargs') -const { argv } = yargs +export const parser = yargs .scriptName('ton') .usage('Usage: $0 ') .help() @@ -63,23 +64,31 @@ const { argv } = yargs } }) -async function main() { +export default async function main( + argv: any +): Promise<{ app: TonApp; token: TonListenSocket }> { try { + logger.info('[Try Love TonJS]') const [entry = 'index.js'] = argv._ - const app = createApp(argv) const endpoint: TonHandler | TonRoute | TonRoutes = ( await import(path.resolve(process.cwd(), entry)) ).default - routes(app, endpoint) + const app = createApp(argv) + routes(app, endpoint, { logger }) const token: TonListenSocket = await listen(app, argv.host, argv.port) registerGracefulShutdown(token) - console.info( - `\nyou raise me up, to listen on http://${argv.host}:${argv.port}\n` + logger.info( + `you raise me up, to listen on http://${argv.host}:${argv.port}` ) + return { app, token } } catch (err) { - console.info(`\nfailed to listen on ${argv.host}:${argv.port}\n`) - console.error(err) + logger.info(`failed to listen on ${argv.host}:${argv.port}`) + logger.error(err) + throw err } } -main() +/* istanbul ignore next */ +if (process.env.NODE_ENV !== 'test') { + main(parser.argv) +} diff --git a/packages/ton/src/index.ts b/packages/ton/src/index.ts index 1a87cf0..5e8af9a 100644 --- a/packages/ton/src/index.ts +++ b/packages/ton/src/index.ts @@ -435,7 +435,7 @@ export function routes( /* istanbul ignore next */ { logger = tonLogger }: { logger?: TonLogger } = {} ) { - logger.debug('\nroutes:') + logger.debug('routes:') if (Array.isArray(endpoints)) { endpoints.forEach(item => { diff --git a/yarn.lock b/yarn.lock index 5aeda90..001d118 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2016,6 +2016,13 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== +axios@^0.19.2: + version "0.19.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" + integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== + dependencies: + follow-redirects "1.5.10" + babel-jest@^25.5.1: version "25.5.1" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-25.5.1.tgz#bc2e6101f849d6f6aec09720ffc7bc5332e62853" @@ -2864,7 +2871,7 @@ dateformat@^3.0.0: resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== -debug@3.1.0: +debug@3.1.0, debug@=3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== @@ -3650,6 +3657,13 @@ flush-write-stream@^1.0.0: inherits "^2.0.3" readable-stream "^2.3.6" +follow-redirects@1.5.10: + version "1.5.10" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + dependencies: + debug "=3.1.0" + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -7793,9 +7807,9 @@ ts-jest@^25.4.0: yargs-parser "18.x" ts-node@^8.6.2: - version "8.9.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.9.1.tgz#2f857f46c47e91dcd28a14e052482eb14cfd65a5" - integrity sha512-yrq6ODsxEFTLz0R3BX2myf0WBCSQh9A+py8PBo1dCzWIOcvisbyH6akNKqDHMgXePF2kir5mm5JXJTH3OUJYOQ== + version "8.10.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.10.1.tgz#77da0366ff8afbe733596361d2df9a60fc9c9bd3" + integrity sha512-bdNz1L4ekHiJul6SHtZWs1ujEKERJnHs4HxN7rjTyyVOFf3HaJ6sLqe6aPG62XTzAB/63pKRh5jTSWL0D7bsvw== dependencies: arg "^4.1.0" diff "^4.0.1"