hubot 3.4.0 → 4.0.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hubot",
3
- "version": "3.4.0",
3
+ "version": "4.0.0",
4
4
  "author": "hubot",
5
5
  "keywords": [
6
6
  "github",
@@ -15,26 +15,24 @@
15
15
  "url": "https://github.com/hubotio/hubot.git"
16
16
  },
17
17
  "dependencies": {
18
- "async": ">=0.1.0 <1.0.0",
19
- "chalk": "^1.0.0",
18
+ "async": "^3.2.4",
20
19
  "cline": "^0.8.2",
21
- "coffeescript": "1.6.3",
22
- "connect-multiparty": "^2.1.1",
23
- "express": "^4.16.3",
24
- "express-basic-auth": "1.1.7",
25
- "log": "1.4.0",
26
- "optparse": "1.0.4"
20
+ "coffeescript": "^2.7.0",
21
+ "connect-multiparty": "^2.2.0",
22
+ "express": "^4.18.2",
23
+ "express-basic-auth": "^1.2.1",
24
+ "log": "^6.3.1",
25
+ "log-node": "^8.0.3",
26
+ "optparse": "^1.0.5"
27
27
  },
28
28
  "devDependencies": {
29
- "chai": "~2.1.0",
30
- "coveralls": "^3.0.2",
29
+ "chai": "^4.3.7",
31
30
  "is-circular": "^1.0.2",
32
31
  "mocha": "^10.2.0",
33
- "mockery": "^1.4.0",
34
- "nyc": "^15.1.0",
32
+ "mockery": "^2.1.0",
35
33
  "semantic-release": "^21.0.1",
36
- "sinon": "~1.17.0",
37
- "sinon-chai": "^2.8.0",
34
+ "sinon": "^15.0.4",
35
+ "sinon-chai": "^3.7.0",
38
36
  "standard": "^17.0.0"
39
37
  },
40
38
  "engines": {
@@ -48,9 +46,13 @@
48
46
  "scripts": {
49
47
  "start": "bin/hubot",
50
48
  "pretest": "standard",
51
- "test": "nyc --reporter=html --reporter=text mocha",
52
- "coverage": "nyc report --reporter=text-lcov | coveralls",
53
- "test:smoke": "node src/**/*.js",
54
- "semantic-release": "semantic-release pre && npm publish && semantic-release post"
49
+ "test": "mocha --exit",
50
+ "test:smoke": "node src/**/*.js"
51
+ },
52
+ "release": {
53
+ "branches": [
54
+ "master"
55
+ ],
56
+ "dryRun": false
55
57
  }
56
58
  }
@@ -4,7 +4,6 @@ const fs = require('fs')
4
4
  const readline = require('readline')
5
5
  const Stream = require('stream')
6
6
  const cline = require('cline')
7
- const chalk = require('chalk')
8
7
 
9
8
  const Adapter = require('../adapter')
10
9
 
@@ -15,12 +14,13 @@ const TextMessage = _require.TextMessage
15
14
  const historySize = process.env.HUBOT_SHELL_HISTSIZE != null ? parseInt(process.env.HUBOT_SHELL_HISTSIZE) : 1024
16
15
 
17
16
  const historyPath = '.hubot_history'
17
+ const bold = str => `\x1b[1m${str}\x1b[22m`
18
18
 
19
19
  class Shell extends Adapter {
20
20
  send (envelope/* , ...strings */) {
21
21
  const strings = [].slice.call(arguments, 1)
22
22
 
23
- Array.from(strings).forEach(str => console.log(chalk.bold(`${str}`)))
23
+ Array.from(strings).forEach(str => console.log(bold(str)))
24
24
  }
25
25
 
26
26
  emote (envelope/* , ...strings */) {
@@ -36,15 +36,13 @@ class Shell extends Adapter {
36
36
 
37
37
  run () {
38
38
  this.buildCli()
39
-
40
39
  loadHistory((error, history) => {
41
40
  if (error) {
42
41
  console.log(error.message)
43
42
  }
44
-
45
43
  this.cli.history(history)
46
44
  this.cli.interact(`${this.robot.name}> `)
47
- return this.emit('connected')
45
+ return this.emit('connected', this)
48
46
  })
49
47
  }
50
48
 
@@ -97,14 +95,11 @@ class Shell extends Adapter {
97
95
  }
98
96
 
99
97
  const outstream = fs.createWriteStream(historyPath, fileOpts)
100
- outstream.on('finish', this.shutdown.bind(this))
101
-
98
+ outstream.on('end', this.shutdown.bind(this))
102
99
  for (i = 0, len = history.length; i < len; i++) {
103
100
  item = history[i]
104
101
  outstream.write(item + '\n')
105
102
  }
106
-
107
- outstream.end(this.shutdown.bind(this))
108
103
  })
109
104
  }
110
105
  }
package/src/robot.js CHANGED
@@ -1,11 +1,12 @@
1
1
  'use strict'
2
+ require('log-node')()
2
3
 
3
4
  const EventEmitter = require('events').EventEmitter
4
5
  const fs = require('fs')
5
6
  const path = require('path')
6
7
 
7
8
  const async = require('async')
8
- const Log = require('log')
9
+ const log = require('log')
9
10
  const HttpClient = require('./httpclient')
10
11
 
11
12
  const Brain = require('./brain')
@@ -49,7 +50,9 @@ class Robot {
49
50
  response: new Middleware(this),
50
51
  receive: new Middleware(this)
51
52
  }
52
- this.logger = new Log(process.env.HUBOT_LOG_LEVEL || 'info')
53
+ process.env.LOG_LEVEL = process.env.LOG_LEVEL || process.env.HUBOT_LOG_LEVEL || 'info'
54
+ this.logger = log.get('robot')
55
+
53
56
  this.pingIntervalId = null
54
57
  this.globalHttpOptions = {}
55
58
 
@@ -317,13 +320,13 @@ class Robot {
317
320
  // stack doesn't get too big
318
321
  process.nextTick(() =>
319
322
  // Stop processing when message.done == true
320
- done(context.response.message.done)
323
+ done(null, context.response.message.done)
321
324
  )
322
325
  })
323
326
  } catch (err) {
324
327
  this.emit('error', err, new this.Response(this, context.response.message, []))
325
328
  // Continue to next listener when there is an error
326
- done(false)
329
+ done(null, false)
327
330
  }
328
331
  },
329
332
  // Ignore the result ( == the listener that set message.done = true)
@@ -30,6 +30,10 @@ describe('Datastore', function () {
30
30
  this.robot.brain.userForId('2', { name: 'User Two' })
31
31
  })
32
32
 
33
+ this.afterEach(function () {
34
+ this.clock.restore()
35
+ })
36
+
33
37
  describe('global scope', function () {
34
38
  it('returns undefined for values not in the datastore', function () {
35
39
  return this.robot.datastore.get('blah').then(function (value) {
@@ -6,6 +6,7 @@
6
6
  // Assertions and Stubbing
7
7
  const chai = require('chai')
8
8
  const sinon = require('sinon')
9
+ const emitter = require('log/lib/emitter')
9
10
  chai.use(require('sinon-chai'))
10
11
 
11
12
  const expect = chai.expect
@@ -374,7 +375,7 @@ describe('Robot', function () {
374
375
 
375
376
  describe('#loadFile', function () {
376
377
  beforeEach(function () {
377
- this.sandbox = sinon.sandbox.create()
378
+ this.sandbox = sinon.createSandbox()
378
379
  })
379
380
 
380
381
  afterEach(function () {
@@ -422,15 +423,24 @@ describe('Robot', function () {
422
423
  })
423
424
 
424
425
  it('logs a warning for a .js file', function () {
425
- sinon.stub(this.robot.logger, 'warning')
426
+ let wasCalled = false
427
+ const listener = e => {
428
+ wasCalled = e.messageTokens.some(t => t.indexOf('Expected scripts/test-script') > -1)
429
+ }
430
+ emitter.on('log', listener)
426
431
  this.robot.loadFile('./scripts', 'test-script.js')
427
- expect(this.robot.logger.warning).to.have.been.called
432
+ expect(wasCalled).to.be.true
433
+ emitter.off('log', listener)
428
434
  })
429
435
 
430
436
  it('logs a warning for a .mjs file', function () {
431
- sinon.stub(this.robot.logger, 'warning')
437
+ let wasCalled = false
438
+ const listener = e => {
439
+ wasCalled = e.messageTokens.some(t => t.indexOf('Expected scripts/test-script') > -1)
440
+ }
441
+ emitter.on('log', listener)
432
442
  this.robot.loadFile('./scripts', 'test-script.mjs')
433
- expect(this.robot.logger.warning).to.have.been.called
443
+ expect(wasCalled).to.be.true
434
444
  })
435
445
  })
436
446
 
@@ -724,7 +734,7 @@ describe('Robot', function () {
724
734
  this.robot.catchAll(catchAllCallback)
725
735
 
726
736
  this.robot.receive(testMessage, function () {
727
- expect(listenerCallback).to.have.been.called.once
737
+ expect(listenerCallback).to.have.been.calledOnce
728
738
  expect(catchAllCallback).to.not.have.been.called
729
739
  done()
730
740
  })
@@ -0,0 +1,72 @@
1
+ 'use strict'
2
+
3
+ /* global describe, beforeEach, it */
4
+
5
+ const chai = require('chai')
6
+ const sinon = require('sinon')
7
+ chai.use(require('sinon-chai'))
8
+
9
+ const expect = chai.expect
10
+
11
+ const Robot = require('../src/robot')
12
+
13
+ describe('Shell Adapter', function () {
14
+ beforeEach(function () {
15
+ this.robot = new Robot(null, 'shell', false, 'TestHubot')
16
+ this.robot.run()
17
+ })
18
+
19
+ this.afterEach(function () {
20
+ this.robot.shutdown()
21
+ })
22
+
23
+ describe('Public API', function () {
24
+ beforeEach(function () {
25
+ this.adapter = this.robot.adapter
26
+ })
27
+
28
+ it('assigns robot', function () {
29
+ expect(this.adapter.robot).to.equal(this.robot)
30
+ })
31
+
32
+ it('sends a message', function () {
33
+ this.adapter.send = sinon.spy()
34
+ this.adapter.send({ room: 'general' }, 'hello')
35
+
36
+ expect(this.adapter.send).to.have.been.calledWith({ room: 'general' }, 'hello')
37
+ })
38
+
39
+ it('emotes a message', function () {
40
+ this.adapter.send = sinon.spy()
41
+ this.adapter.emote({ room: 'general' }, 'hello')
42
+
43
+ expect(this.adapter.send).to.have.been.calledWith({ room: 'general' }, '* hello')
44
+ })
45
+
46
+ it('replies to a message', function () {
47
+ this.adapter.send = sinon.spy()
48
+ this.adapter.reply({ room: 'general', user: { name: 'mocha' } }, 'hello')
49
+
50
+ expect(this.adapter.send).to.have.been.calledWith({ room: 'general', user: { name: 'mocha' } }, 'mocha: hello')
51
+ })
52
+
53
+ it('runs the adapter and emits connected', function (done) {
54
+ const connected = () => {
55
+ this.adapter.off('connected', connected)
56
+ done()
57
+ }
58
+ this.adapter.on('connected', connected)
59
+ this.adapter.run()
60
+ })
61
+ })
62
+
63
+ it('dispatches received messages to the robot', function () {
64
+ this.robot.receive = sinon.spy()
65
+ this.adapter = this.robot.adapter
66
+ this.message = sinon.spy()
67
+
68
+ this.adapter.receive(this.message)
69
+
70
+ expect(this.robot.receive).to.have.been.calledWith(this.message)
71
+ })
72
+ })
package/.env.example DELETED
@@ -1,2 +0,0 @@
1
- export NPM_TOKEN=npm_whatever
2
- export GITHUB_TOKEN=ghp_whatever
package/.envrc DELETED
@@ -1,5 +0,0 @@
1
- # TODO change to op://Personal/npmjs.org/NPM Publish
2
- export NPM_TOKEN=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
3
-
4
- # TODO change to op://Personal/te/NPM Publish
5
- export GITHUB_TOKEN=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
package/.travis.yml DELETED
@@ -1,27 +0,0 @@
1
- language: node_js
2
- node_js:
3
- - "10"
4
- - "8"
5
- - "6"
6
- notifications:
7
- email: false
8
- sudo: false
9
- addons:
10
- apt:
11
- packages:
12
- - expect
13
- before_install:
14
- - npm install -g npm@latest
15
- before_script:
16
- - npm prune
17
- - bin/e2e-test.sh
18
- after_success:
19
- - npm run coverage
20
- branches:
21
- except:
22
- - /^v\d+\.\d+\.\d+$/
23
- deploy:
24
- provider: script
25
- skip_cleanup: true
26
- script:
27
- - npx travis-deploy-once "npx semantic-release"