@mattduffy/banner 1.1.1 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.cjs CHANGED
@@ -1,3 +1,5 @@
1
+ const restrictedGlobals = require('eslint-restricted-globals')
2
+
1
3
  module.exports = {
2
4
  globals: {
3
5
  window: true,
@@ -15,9 +17,9 @@ module.exports = {
15
17
  extends: 'airbnb-base',
16
18
  overrides: [
17
19
  {
18
- files: ["public/j/worker.js"],
20
+ files: ['public/j/worker.js'],
19
21
  rules: {
20
- 'no-restricted-globals': ['error', 'isFinite', 'isNaN'].concat(restrictedGlobals),
22
+ 'no-restricted-globals': ['error', 'isFinite', 'isNaN'].concat(restrictedGlobals),
21
23
  },
22
24
  },
23
25
  ],
@@ -31,7 +33,7 @@ module.exports = {
31
33
  'no-underscore-dangle': 'off',
32
34
  'import/extensions': 'off',
33
35
  'import/prefer-default-export': 'off',
34
- 'max-len': ['error', {"code": 100}],
36
+ 'max-len': ['error', { code: 100 }],
35
37
  'new-cap': 'off',
36
38
  },
37
39
  }
package/Readme.md CHANGED
@@ -3,11 +3,76 @@ This package exports a middleware function for Koajs app servers that displays u
3
3
  information.
4
4
 
5
5
  ```javascript
6
- import banner from '@mattduffy/banner'
6
+ import Banner from '@mattduffy/banner'
7
7
 
8
8
  // to emit a startup banner in your app logs
9
+ const banner = new Banner({
10
+ name: <your_app_name>,
11
+ local: <your_local_dev_host>,
12
+ localPort: <your_local_dev_port>, // optional
13
+ public: <your_public_domain_name>,
14
+ })
9
15
  banner.print()
10
-
16
+ /*
17
+ Emits to stdout (or where ever your logging goes).
18
+ #####################################################
19
+ # #
20
+ # Starting up: <your_app_name> #
21
+ # local: http://192.168.1.252:9876 #
22
+ # public: https://example.com #
23
+ # process: node v20.19.4 (Iron) #
24
+ # arch: x64 linux #
25
+ # #
26
+ #####################################################
27
+ */
11
28
  // To emit a banner at the start of each request
12
29
  app.use(banner.use())
30
+ /*
31
+ Emits at the beginning of each client request.
32
+ #################################################################
33
+ # GET: https://dev.example.com/map/getToken?debug=verbose
34
+ # Referer: https://dev.example.com/?debug=verbose
35
+ # From IP: 192.168.1.254
36
+ #################################################################
37
+ */
38
+ ```
39
+
40
+ The request banner uses a different ASCII text character depending on the value of
41
+ the ```ctx.request.method``` property. The supported request methods are ```GET```, ```PUT```,
42
+ ```POST```, and ```DELETE```.
43
+
44
+ ```
45
+ // GET
46
+ ######################################################################
47
+ # GET: https://banner.test/a/really/long/url/to/a/special/page
48
+ # Referer: https://googoogle.com
49
+ # From IP: 192.168.1.250
50
+ ######################################################################
51
+ ```
52
+
53
+ ```
54
+ // PUT
55
+ &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
56
+ & PUT: https://banner.test/a/really/long/url/to/a/special/page
57
+ & Referer: https://googoogle.com
58
+ & From IP: 192.168.1.250
59
+ &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
60
+ ```
61
+
62
+ ```
63
+ // POST
64
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
65
+ @ POST: https://banner.test/a/really/long/url/to/a/special/page
66
+ @ Referer: https://googoogle.com
67
+ @ From IP: 192.168.1.250
68
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
69
+ ```
70
+
71
+ ```
72
+ // DELETE
73
+ **********************************************************************
74
+ * DELETE: https://banner.test/a/really/long/url/to/a/special/page
75
+ * Referer: https://googoogle.com
76
+ * From IP: 192.168.1.250
77
+ **********************************************************************
13
78
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mattduffy/banner",
3
- "version": "1.1.1",
3
+ "version": "1.2.1",
4
4
  "description": "Displays server start-up information.",
5
5
  "author": "Matthew Duffy",
6
6
  "license": "ISC",
@@ -28,6 +28,7 @@
28
28
  },
29
29
  "keywords": [],
30
30
  "dependencies": {
31
- "debug": "4.4.1"
31
+ "debug": "4.4.1",
32
+ "eslint-restricted-globals": "0.2.0"
32
33
  }
33
34
  }
package/src/index.js CHANGED
@@ -7,8 +7,8 @@
7
7
  import Debug from 'debug'
8
8
 
9
9
  Debug.log = console.log.bind(console)
10
- const log = Debug('banner')
11
- const error = log.extend('ERROR')
10
+ // const log = Debug('banner')
11
+ // const error = log.extend('ERROR')
12
12
 
13
13
  /**
14
14
  * A class to create and emit a start-up banner of Koajs based apps.
@@ -18,33 +18,54 @@ const error = log.extend('ERROR')
18
18
  */
19
19
  export class Banner {
20
20
  #appName
21
+
21
22
  #arch
23
+
22
24
  #bannerText
25
+
23
26
  #borderGlyphGET = '#'
27
+
24
28
  #borderGlyphPUT = '&'
29
+
25
30
  #borderGlyphPOST = '@'
31
+
26
32
  #borderGlyphDELETE = '*'
33
+
34
+ #ipAddress
35
+
27
36
  #lineStarts = []
37
+
28
38
  #lines = []
39
+
29
40
  #local
41
+
30
42
  #localPort
43
+
31
44
  #nodejs
45
+
32
46
  #nodeLts
47
+
33
48
  #nodeName
49
+
34
50
  #nodeVersion
51
+
35
52
  #platform
53
+
36
54
  #public
55
+
37
56
  #startingup
57
+
38
58
  /**
39
59
  * Create an instance of the Banner class.
40
60
  * @param { object } [strings] - An object literal of strings to display in the banner.
41
- * @param { string } strings.name - The name of the app starting up.
42
- * @param { string } strings.public - The public web address the app is accesssible at.
61
+ * @param { string } [strings.ip] - The ip address of the request.
43
62
  * @param { string } strings.local - The local address the app is accessible at.
44
63
  * @param { Number } [strings.localPort] - The local address port, if provided.
64
+ * @param { string } strings.name - The name of the app starting up.
65
+ * @param { string } strings.public - The public web address the app is accesssible at.
45
66
  * @returns { Banner}
46
67
  */
47
- constructor(strings=null) {
68
+ constructor(strings = null) {
48
69
  this.#arch = process.arch
49
70
  this.#nodeLts = process.release?.lts ?? null
50
71
  this.#nodeName = process.release.name
@@ -61,7 +82,8 @@ export class Banner {
61
82
  this.#appName = strings.name
62
83
  this.#borderGlyphGET = strings?.borderGlyph ?? this.#borderGlyphGET
63
84
  this.#localPort = strings?.localPort ?? null
64
- this.#local = `${strings.local}${(this.#localPort) ? ':' + this.#localPort : ''}`
85
+ this.#ipAddress = strings?.ip ?? null
86
+ this.#local = `${strings.local}${(this.#localPort) ? `: ${this.#localPort}` : ''}`
65
87
  this.#public = strings.public
66
88
  this.#startingup = strings.name
67
89
  }
@@ -76,63 +98,62 @@ export class Banner {
76
98
  * @throws { Error } - Throws an exception if name, public, local values are missing.
77
99
  * @return { void }
78
100
  */
79
- #compose () {
101
+ #compose() {
80
102
  if (!this.#appName || !this.#local || !this.#public) {
81
103
  throw new Error('Missing required inputs.')
82
104
  }
83
105
  this.startingupLine = `${this.startingupLabel}: ${this.#startingup}`
84
106
  this.#lineStarts.push(this.startingupLine)
85
107
  this.localLine = `${this.localLabel}: `
86
- + `${/^https?:\/\//.test(this.#local) ? this.#local : 'http://' + this.#local}`
108
+ + `${/^https?:\/\//.test(this.#local) ? `${this.#local}` : `http://${this.#local}`}`
87
109
  this.#lineStarts.push(this.localLine)
88
110
  this.publicLine = `${this.publicLabel}: `
89
- + `${/^https?:\/\//.test(this.#public) ? this.#public : 'https://' + this.#public}`
111
+ + `${/^https?:\/\//.test(this.#public) ? `${this.#public}` : `https://${this.#public}`}`
90
112
  this.#lineStarts.push(this.publicLine)
91
113
  this.archLine = `${this.archLabel}: ${this.#arch} ${this.#platform}`
92
114
  this.#lineStarts.push(this.archLine)
93
115
  this.nodejsLine = `${this.nodejsLabel}: ${this.#nodeName} ${this.#nodeVersion} `
94
- + `${(this.#nodeLts) ? '(' + this.#nodeLts + ')' : ''}`
116
+ + `${(this.#nodeLts) ? `(${this.#nodeLts})` : ''}`
95
117
  this.#lineStarts.push(this.nodejsLine)
96
118
 
97
- this.startingupLine = this.startingupLine.padStart(
98
- (this.longestLabel - this.startingupLine.indexOf(':'))
99
- + this.startingupLine.length, ' ')
119
+ this.startingupLine = this.startingupLine
120
+ .padStart((this.longestLabel - this.startingupLine.indexOf(':'))
121
+ + this.startingupLine.length, ' ')
100
122
  this.#lines[0] = this.startingupLine
101
123
 
102
- this.localLine = this.localLine.padStart(
103
- (this.longestLabel - this.localLine.indexOf(':'))
104
- + this.localLine.length, ' ')
124
+ this.localLine = this.localLine
125
+ .padStart((this.longestLabel - this.localLine.indexOf(':'))
126
+ + this.localLine.length, ' ')
105
127
  this.#lines[1] = this.localLine
106
128
 
107
- this.publicLine = this.publicLine.padStart(
108
- (this.longestLabel - this.publicLine.indexOf(':'))
109
- + this.publicLine.length, ' ')
129
+ this.publicLine = this.publicLine
130
+ .padStart((this.longestLabel - this.publicLine.indexOf(':'))
131
+ + this.publicLine.length, ' ')
110
132
  this.#lines[2] = this.publicLine
111
133
 
112
- this.nodejsLine = this.nodejsLine.padStart(
113
- (this.longestLabel - this.nodejsLine.indexOf(':'))
114
- + this.nodejsLine.length, ' ')
134
+ this.nodejsLine = this.nodejsLine
135
+ .padStart((this.longestLabel - this.nodejsLine.indexOf(':'))
136
+ + this.nodejsLine.length, ' ')
115
137
  this.#lines[3] = this.nodejsLine
116
138
 
117
- this.archLine = this.archLine.padStart(
118
- (this.longestLabel - this.archLine.indexOf(':'))
119
- + this.archLine.length, ' ')
139
+ this.archLine = this.archLine
140
+ .padStart((this.longestLabel - this.archLine.indexOf(':'))
141
+ + this.archLine.length, ' ')
120
142
  this.#lines[4] = this.archLine
121
143
 
122
144
  const g = this.#borderGlyphGET
123
- this.#bannerText =
124
- `${g}${g.padEnd(this.longestLine + 5, g)}${g}\n`
145
+ this.#bannerText = `${g}${g.padEnd(this.longestLine + 5, g)}${g}\n`
125
146
  + `${g} ${' '.padEnd(this.longestLine + 2, ' ')} ${g}\n`
126
- + `${g} ${this.startingupLine}${' '.padEnd(
127
- (this.longestLine - this.startingupLine.length) + 3, ' ')} ${g}\n`
128
- + `${g} ${this.localLine}${' '.padEnd(
129
- (this.longestLine - this.localLine.length) + 3, ' ')} ${g}\n`
130
- + `${g} ${this.publicLine}${' '.padEnd(
131
- (this.longestLine - this.publicLine.length) + 3, ' ')} ${g}\n`
132
- + `${g} ${this.nodejsLine}${' '.padEnd(
133
- (this.longestLine - this.nodejsLine.length) + 3, ' ')} ${g}\n`
134
- + `${g} ${this.archLine}${' '.padEnd(
135
- (this.longestLine - this.archLine.length) + 3, ' ')} ${g}\n`
147
+ + `${g} ${this.startingupLine}${' '
148
+ .padEnd((this.longestLine - this.startingupLine.length) + 3, ' ')} ${g}\n`
149
+ + `${g} ${this.localLine}${' '
150
+ .padEnd((this.longestLine - this.localLine.length) + 3, ' ')} ${g}\n`
151
+ + `${g} ${this.publicLine}${' '
152
+ .padEnd((this.longestLine - this.publicLine.length) + 3, ' ')} ${g}\n`
153
+ + `${g} ${this.nodejsLine}${' '
154
+ .padEnd((this.longestLine - this.nodejsLine.length) + 3, ' ')} ${g}\n`
155
+ + `${g} ${this.archLine}${' '
156
+ .padEnd((this.longestLine - this.archLine.length) + 3, ' ')} ${g}\n`
136
157
  + `${g} ${' '.padEnd(this.longestLine + 2, ' ')} ${g}\n`
137
158
  + `${g}${g.padEnd(this.longestLine + 5, g)}${g}\n`
138
159
  }
@@ -163,13 +184,13 @@ export class Banner {
163
184
  }
164
185
  }
165
186
 
166
- /**
187
+ /**
167
188
  * Set the local address displayed in the banner.
168
189
  * @type { string }
169
190
  * @param { string } local - The local address displayed in the banner.
170
191
  */
171
192
  set local(local) {
172
- this.#local = `${local}${(this.#localPort) ? ':' + this.#localPort : ''}`
193
+ this.#local = `${local}${(this.#localPort) ? `:${this.#localPort}` : ''}`
173
194
  if (this.#appName && this.#public) {
174
195
  this.#compose()
175
196
  }
@@ -251,24 +272,24 @@ export class Banner {
251
272
 
252
273
  /**
253
274
  * Create a middleware method that generates a banner for each request.
254
- * @param { function } [log] - an optional reference to the app level logging function.
255
- * @param { function } [error] - an optional reference to the app level error logging function.
275
+ * @param { function } [Log] - an optional reference to the app level logging function.
276
+ * @param { function } [Error] - an optional reference to the app level error logging function.
256
277
  * @returns { (ctx:object, next:function) => mixed } - Koa middleware function.
257
278
  */
258
- use(log=null, error=null) {
259
- const _log = log ?? console.log
260
- const _error = error ?? console.error
279
+ use(Log = null, Error = null) {
280
+ const _log = Log ?? console.log
281
+ // const _error = Error ?? console.error
261
282
  _log('adding request banner to the app.')
262
283
  const gGET = this.#borderGlyphGET
263
284
  const gPUT = this.#borderGlyphPUT
264
285
  const gPOST = this.#borderGlyphPOST
265
286
  const gDEL = this.#borderGlyphDELETE
266
- const n = this.#appName
267
- return async function banner(ctx, next){
287
+ // const n = this.#appName
288
+ return async function banner(ctx, next = null) {
289
+ let _requestBanner
268
290
  try {
269
- // const _g = (/post/i.test(ctx.request.method)) ? '@' : g
270
291
  let _g
271
- switch(ctx.request.method.toLowerCase()) {
292
+ switch (ctx.request.method.toLowerCase()) {
272
293
  case 'get':
273
294
  _g = gGET
274
295
  break
@@ -284,43 +305,65 @@ export class Banner {
284
305
  default:
285
306
  _g = gGET
286
307
  }
287
- _log('ctx.request.header.host', ctx.request.header.host)
288
- const _urlLabel = `${ctx.request.method}:`
308
+ if (!ctx) {
309
+ throw new Error('Missing required ctx object.')
310
+ }
311
+ if (!ctx.request.header.host) {
312
+ throw new Error('Missing required request header.host value.')
313
+ }
314
+ if (!ctx.request.method) {
315
+ throw new Error('Missing required request method value.')
316
+ }
317
+ if (!ctx.request.url) {
318
+ throw new Error('Missing required request url value.')
319
+ }
320
+ const _urlLabel = `${ctx.request.method}:`
289
321
  const _url = `${ctx.request.protocol}://${ctx.request.header.host}${ctx.request.url}`
290
322
  let _urlLine = `${_urlLabel} ${_url}`
291
323
  const _refLabel = 'Referer:'
292
324
  const _ref = ctx.request.header.referer ?? '<emtpy header field>'
293
325
  let _refLine = `${_refLabel} ${_ref}`
294
- const _longestLabel = [_urlLabel, _refLabel].reduce((a, c) => {
326
+ const _ipLabel = 'From IP:'
327
+ const _ip = ctx.request.ip
328
+ let _ipLine = `${_ipLabel} ${_ip}`
329
+ const _longestLabel = [_urlLabel, _refLabel, _ipLabel].reduce((a, c) => {
295
330
  if (a.length > (c.indexOf(':') + 1)) {
296
331
  return a
297
332
  }
298
333
  return (c.indexOf(':') + 1)
299
334
  }, '')
300
335
  _refLine = _refLine.padStart(
301
- (_longestLabel - _refLine.indexOf(':')) + _refLine.length, ' '
336
+ (_longestLabel - _refLine.indexOf(':')) + _refLine.length,
337
+ ' ',
302
338
  )
303
339
  _urlLine = _urlLine.padStart(
304
- (_longestLabel - _urlLine.indexOf(':')) + _urlLine.length, ' '
340
+ (_longestLabel - _urlLine.indexOf(':')) + _urlLine.length,
341
+ ' ',
305
342
  )
306
- const _longestLine = [_urlLine, _refLine].reduce((a, c) => {
343
+ _ipLine = _ipLine.padStart(
344
+ (_longestLabel - _ipLine.indexOf(':')) + _ipLine.length,
345
+ ' ',
346
+ )
347
+ const _longestLine = [_urlLine, _refLine, _ipLine].reduce((a, c) => {
307
348
  if (a > c.length) return a
308
349
  return c.length
309
350
  }, '')
310
351
  // _log('request banner _longestLine', _longestLine)
311
- const _requestBanner =
312
- `${_g.padEnd(_longestLine + 5, _g)}\n`
352
+ _requestBanner = `${_g.padEnd(_longestLine + 5, _g)}\n`
313
353
  + `${_g} ${_urlLine}\n`
314
354
  + `${_g} ${_refLine}\n`
355
+ + `${_g} ${_ipLine}\n`
315
356
  + `${_g.padEnd(_longestLine + 5, _g)}`
316
357
  _log(_requestBanner)
317
- await next()
318
- return true
358
+ if (next) {
359
+ await next(ctx.request.method)
360
+ }
319
361
  } catch (e) {
320
- _error('Failed after adding start-up banner.')
321
- _error(e)
322
- ctx.throw(500, 'Error after adding start-up banner.', e)
362
+ // _error('Failed after adding the request banner.')
363
+ // _error(e)
364
+ ctx.throw(500, e)
323
365
  }
324
- }
325
- }
366
+ return _requestBanner
367
+ } // end async closure function, Banner.use.banner()
368
+ } // end Banner.use()
326
369
  }
package/test/test.js CHANGED
@@ -8,8 +8,10 @@ import {
8
8
  } from 'node:test'
9
9
  import assert from 'node:assert/strict'
10
10
  import fs from 'node:fs/promises'
11
+ import os from 'node:os'
11
12
  import { Banner } from '../src/index.js'
12
13
  const skip = { skip: true }
14
+ console.log(skip)
13
15
  let cfg
14
16
  let ctx
15
17
  let ctx_POST
@@ -17,11 +19,30 @@ let ctx_GET
17
19
  let ctx_PUT
18
20
  let ctx_DEL
19
21
  let next
20
- console.log(skip)
21
22
  describe('First test suite for banner package', async () => {
22
23
  before(() => {
24
+ function getLocalIpAddress() {
25
+ const networkInterfaces = os.networkInterfaces();
26
+ let localIpAddress = null;
27
+
28
+ for (const interfaceName in networkInterfaces) {
29
+ const networkInterface = networkInterfaces[interfaceName];
30
+ for (const details of networkInterface) {
31
+ // Check for IPv4, not internal (loopback), and a valid address
32
+ if (details.family === 'IPv4' && !details.internal) {
33
+ localIpAddress = details.address;
34
+ break; // Found a suitable IPv4 address, exit inner loop
35
+ }
36
+ }
37
+ if (localIpAddress) {
38
+ break; // Found a suitable IPv4 address, exit outer loop
39
+ }
40
+ }
41
+ return localIpAddress;
42
+ }
23
43
  ctx = {
24
44
  request: {
45
+ ip: getLocalIpAddress(),
25
46
  protocol: 'https',
26
47
  method: '',
27
48
  url: '/a/really/long/url/to/a/special/page',
@@ -30,17 +51,10 @@ describe('First test suite for banner package', async () => {
30
51
  referer: 'https://googoogle.com',
31
52
  },
32
53
  },
33
- throw: (code, msg) => {
34
- throw new Error(`Error code ${code}: ${msg}`)
35
- }
36
54
  }
37
- ctx_DEL = { ...ctx }
38
- ctx_PUT = { ...ctx }
39
- ctx_POST = { ...ctx }
40
- ctx_GET = { ...ctx }
41
- next = async () => {
55
+ next = async (m) => {
42
56
  setTimeout(() => {
43
- console.log('the next() function')
57
+ console.log(`the next(${m}) function`)
44
58
  }, 1000)
45
59
  }
46
60
  cfg = {
@@ -68,44 +82,64 @@ describe('First test suite for banner package', async () => {
68
82
  })
69
83
 
70
84
  it('Should work as a koajs middleware function - POST method.', async () => {
71
- ctx_POST = Object.assign(ctx_POST, ctx)
85
+ ctx_POST = Object.assign({}, ctx)
72
86
  ctx_POST.request.method = 'POST'
87
+ ctx_POST.throw = (code, err, {} = null) => {
88
+ throw new Error(`${code}, ${msg}`)
89
+ }
73
90
  console.log(ctx_POST)
74
91
  const post = new Banner(ctx_POST)
75
- assert(await post.use()(ctx, next))
92
+ assert(await post.use()(ctx_POST, next))
76
93
  })
77
94
 
78
95
  it('Should work as a koajs middleware function - GET method.', async () => {
79
- ctx_GET = Object.assign(ctx_GET, ctx)
96
+ ctx_GET = Object.assign({}, ctx)
80
97
  ctx_GET.request.method = 'GET'
98
+ ctx_GET.throw = (code, err, {} = null) => {
99
+ throw new Error(`${code}, ${msg}`)
100
+ }
81
101
  console.log(ctx_GET)
82
102
  const get = new Banner(ctx_GET)
83
- assert(await get.use()(ctx, next))
103
+ assert(await get.use()(ctx_GET, next))
84
104
  })
85
105
 
86
106
  it('Should work as a koajs middleware function - PUT method.', async () => {
87
- ctx_PUT = Object.assign(ctx_PUT, ctx)
107
+ ctx_PUT = Object.assign({}, ctx)
88
108
  ctx_PUT.request.method = 'PUT'
109
+ ctx_PUT.throw = (code, err, {} = null) => {
110
+ throw new Error(`${code}, ${msg}`)
111
+ }
89
112
  console.log(ctx_PUT)
90
113
  const put = new Banner(ctx_PUT)
91
- assert(await put.use()(ctx, next))
114
+ assert(await put.use()(ctx_PUT, next))
92
115
  })
93
116
 
94
117
  it('Should work as a koajs middleware function - DELETE method.', async () => {
95
- ctx_DEL = Object.assign(ctx_DEL, ctx)
118
+ ctx_DEL = Object.assign({}, ctx)
96
119
  ctx_DEL.request.method = 'DELETE'
120
+ ctx_DEL.throw = (code, err, {} = null) => {
121
+ throw new Error(`${code}, ${msg}`)
122
+ }
97
123
  console.log(ctx_DEL)
98
124
  const del = new Banner(ctx_DEL)
99
- assert(await del.use()(ctx, next))
125
+ assert(await del.use()(ctx_DEL, next))
100
126
  })
101
127
 
102
128
  it('Should fail as a koajs middleware function, missing input parameters.', async () => {
103
- ctx.url= ''
104
- ctx.request.header.host = undefined
105
- ctx.request.url = undefined
129
+ ctx.request.header.host = null
130
+ ctx.request.url = null
131
+ ctx.throw = (code, err) => {
132
+ // console.log(err.message)
133
+ throw err
134
+ }
106
135
  console.log(ctx)
107
- const post = new Banner()
108
- await post.use()(ctx, next)
109
- // assert.throws(await post.use()(ctx, next))
136
+ const req = new Banner()
137
+ const use = await req.use()
138
+ assert.rejects(
139
+ async () => {
140
+ await use(ctx)
141
+ },
142
+ Error,
143
+ )
110
144
  })
111
145
  })