hubot 4.0.0 → 5.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/README.md +0 -1
- package/bin/hubot.js +30 -84
- package/docs/adapters/development.md +32 -5
- package/index.js +1 -0
- package/package.json +3 -4
- package/src/robot.js +32 -17
- package/test/adapter_test.js +0 -3
- package/test/es2015_test.js +6 -6
- package/test/fixtures/MockAdapter.coffee +10 -0
- package/test/fixtures/MockAdapter.mjs +43 -0
- package/test/fixtures/TestScript.coffee +9 -0
- package/test/fixtures/TestScript.js +13 -0
- package/test/middleware_test.js +4 -3
- package/test/robot_test.js +67 -24
- package/test/shell_test.js +3 -2
package/README.md
CHANGED
package/bin/hubot.js
CHANGED
|
@@ -8,7 +8,8 @@ const OptParse = require('optparse')
|
|
|
8
8
|
const Hubot = require('..')
|
|
9
9
|
|
|
10
10
|
const switches = [
|
|
11
|
-
['-a', '--adapter ADAPTER', 'The Adapter to use'],
|
|
11
|
+
['-a', '--adapter ADAPTER', 'The Adapter to use, e.g. "shell" (to load the default hubot shell adapter)'],
|
|
12
|
+
['-f', '--file PATH', 'Path to adapter file, e.g. "./adapters/CustomAdapter.mjs"'],
|
|
12
13
|
['-c', '--create PATH', 'Create a deployable hubot'],
|
|
13
14
|
['-d', '--disable-httpd', 'Disable the HTTP server'],
|
|
14
15
|
['-h', '--help', 'Display the help information'],
|
|
@@ -20,13 +21,13 @@ const switches = [
|
|
|
20
21
|
]
|
|
21
22
|
|
|
22
23
|
const options = {
|
|
23
|
-
adapter: process.env.HUBOT_ADAPTER
|
|
24
|
+
adapter: process.env.HUBOT_ADAPTER,
|
|
24
25
|
alias: process.env.HUBOT_ALIAS || false,
|
|
25
26
|
create: process.env.HUBOT_CREATE || false,
|
|
26
27
|
enableHttpd: process.env.HUBOT_HTTPD !== 'false',
|
|
27
28
|
scripts: process.env.HUBOT_SCRIPTS || [],
|
|
28
29
|
name: process.env.HUBOT_NAME || 'Hubot',
|
|
29
|
-
|
|
30
|
+
file: process.env.HUBOT_FILE,
|
|
30
31
|
configCheck: false
|
|
31
32
|
}
|
|
32
33
|
|
|
@@ -37,6 +38,10 @@ Parser.on('adapter', (opt, value) => {
|
|
|
37
38
|
options.adapter = value
|
|
38
39
|
})
|
|
39
40
|
|
|
41
|
+
Parser.on('file', (opt, value) => {
|
|
42
|
+
options.file = value
|
|
43
|
+
})
|
|
44
|
+
|
|
40
45
|
Parser.on('create', function (opt, value) {
|
|
41
46
|
options.path = value
|
|
42
47
|
options.create = true
|
|
@@ -89,32 +94,19 @@ if (options.create) {
|
|
|
89
94
|
console.error('See https://github.com/github/hubot/blob/master/docs/index.md for more details on getting started.')
|
|
90
95
|
process.exit(1)
|
|
91
96
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (options.version) {
|
|
96
|
-
console.log(robot.version)
|
|
97
|
-
process.exit(0)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (options.configCheck) {
|
|
101
|
-
loadScripts()
|
|
102
|
-
console.log('OK')
|
|
103
|
-
process.exit(0)
|
|
97
|
+
if (options.file) {
|
|
98
|
+
options.adapter = options.file.split('/').pop().split('.')[0]
|
|
104
99
|
}
|
|
105
|
-
|
|
106
|
-
robot.adapter.once('connected', loadScripts)
|
|
107
|
-
|
|
108
|
-
robot.run()
|
|
100
|
+
const robot = Hubot.loadBot(options.adapter, options.enableHttpd, options.name, options.alias)
|
|
109
101
|
|
|
110
102
|
function loadScripts () {
|
|
111
103
|
robot.load(pathResolve('.', 'scripts'))
|
|
112
104
|
robot.load(pathResolve('.', 'src', 'scripts'))
|
|
113
105
|
|
|
114
|
-
loadHubotScripts()
|
|
115
106
|
loadExternalScripts()
|
|
116
107
|
|
|
117
108
|
options.scripts.forEach((scriptPath) => {
|
|
109
|
+
console.log('loadding', scriptPath)
|
|
118
110
|
if (scriptPath[0] === '/') {
|
|
119
111
|
return robot.load(scriptPath)
|
|
120
112
|
}
|
|
@@ -123,70 +115,6 @@ function loadScripts () {
|
|
|
123
115
|
})
|
|
124
116
|
}
|
|
125
117
|
|
|
126
|
-
function loadHubotScripts () {
|
|
127
|
-
const hubotScripts = pathResolve('.', 'hubot-scripts.json')
|
|
128
|
-
let scripts
|
|
129
|
-
let scriptsPath
|
|
130
|
-
|
|
131
|
-
if (fs.existsSync(hubotScripts)) {
|
|
132
|
-
let hubotScriptsWarning
|
|
133
|
-
const data = fs.readFileSync(hubotScripts)
|
|
134
|
-
|
|
135
|
-
if (data.length === 0) {
|
|
136
|
-
return
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
try {
|
|
140
|
-
scripts = JSON.parse(data)
|
|
141
|
-
scriptsPath = pathResolve('node_modules', 'hubot-scripts', 'src', 'scripts')
|
|
142
|
-
robot.loadHubotScripts(scriptsPath, scripts)
|
|
143
|
-
} catch (error) {
|
|
144
|
-
const err = error
|
|
145
|
-
robot.logger.error(`Error parsing JSON data from hubot-scripts.json: ${err}`)
|
|
146
|
-
process.exit(1)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
hubotScriptsWarning = 'Loading scripts from hubot-scripts.json is deprecated and ' + 'will be removed in 3.0 (https://github.com/github/hubot-scripts/issues/1113) ' + 'in favor of packages for each script.\n\n'
|
|
150
|
-
|
|
151
|
-
if (scripts.length === 0) {
|
|
152
|
-
hubotScriptsWarning += 'Your hubot-scripts.json is empty, so you just need to remove it.'
|
|
153
|
-
return robot.logger.warning(hubotScriptsWarning)
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const hubotScriptsReplacements = pathResolve('node_modules', 'hubot-scripts', 'replacements.json')
|
|
157
|
-
const replacementsData = fs.readFileSync(hubotScriptsReplacements)
|
|
158
|
-
const replacements = JSON.parse(replacementsData)
|
|
159
|
-
const scriptsWithoutReplacements = []
|
|
160
|
-
|
|
161
|
-
if (!fs.existsSync(hubotScriptsReplacements)) {
|
|
162
|
-
hubotScriptsWarning += 'To get a list of recommended replacements, update your hubot-scripts: npm install --save hubot-scripts@latest'
|
|
163
|
-
return robot.logger.warning(hubotScriptsWarning)
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
hubotScriptsWarning += 'The following scripts have known replacements. Follow the link for installation instructions, then remove it from hubot-scripts.json:\n'
|
|
167
|
-
|
|
168
|
-
scripts.forEach((script) => {
|
|
169
|
-
const replacement = replacements[script]
|
|
170
|
-
|
|
171
|
-
if (replacement) {
|
|
172
|
-
hubotScriptsWarning += `* ${script}: ${replacement}\n`
|
|
173
|
-
} else {
|
|
174
|
-
scriptsWithoutReplacements.push(script)
|
|
175
|
-
}
|
|
176
|
-
})
|
|
177
|
-
|
|
178
|
-
hubotScriptsWarning += '\n'
|
|
179
|
-
|
|
180
|
-
if (scriptsWithoutReplacements.length > 0) {
|
|
181
|
-
hubotScriptsWarning += 'The following scripts don’t have (known) replacements. You can try searching https://www.npmjs.com/ or http://github.com/search or your favorite search engine. You can copy the script into your local scripts directory, or consider creating a new package to maintain yourself. If you find a replacement or create a package yourself, please post on https://github.com/github/hubot-scripts/issues/1641:\n'
|
|
182
|
-
hubotScriptsWarning += scriptsWithoutReplacements.map((script) => `* ${script}\n`).join('')
|
|
183
|
-
hubotScriptsWarning += '\nYou an also try updating hubot-scripts to get the latest list of replacements: npm install --save hubot-scripts@latest'
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
robot.logger.warning(hubotScriptsWarning)
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
118
|
function loadExternalScripts () {
|
|
191
119
|
const externalScripts = pathResolve('.', 'external-scripts.json')
|
|
192
120
|
|
|
@@ -207,3 +135,21 @@ function loadExternalScripts () {
|
|
|
207
135
|
}
|
|
208
136
|
})
|
|
209
137
|
}
|
|
138
|
+
|
|
139
|
+
(async () => {
|
|
140
|
+
await robot.loadAdapter(options.file)
|
|
141
|
+
if (options.version) {
|
|
142
|
+
console.log(robot.version)
|
|
143
|
+
process.exit(0)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (options.configCheck) {
|
|
147
|
+
loadScripts()
|
|
148
|
+
console.log('OK')
|
|
149
|
+
process.exit(0)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
robot.adapter.once('connected', loadScripts)
|
|
153
|
+
|
|
154
|
+
robot.run()
|
|
155
|
+
})()
|
|
@@ -33,7 +33,7 @@ class Sample extends Adapter {
|
|
|
33
33
|
}
|
|
34
34
|
run() {
|
|
35
35
|
this.robot.logger.info('Run')
|
|
36
|
-
this.emit('connected')
|
|
36
|
+
this.emit('connected') // The 'connected' event is required to trigger loading of Hubot scripts.
|
|
37
37
|
const user = new User(1001, 'Sample User')
|
|
38
38
|
const message = new TextMessage(user, 'Some Sample Message', 'MSG-001')
|
|
39
39
|
this.robot.receive(message)
|
|
@@ -42,23 +42,23 @@ class Sample extends Adapter {
|
|
|
42
42
|
exports.use = (robot) => new Sample(robot)
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
## Setting Up Your Development Environment
|
|
45
|
+
## Option 1. Setting Up Your Development Environment
|
|
46
46
|
|
|
47
47
|
1. Create a new folder for your adapter `hubot-sample`
|
|
48
48
|
- `mkdir hubot-sample`
|
|
49
49
|
2. Change your working directory to `hubot-sample`
|
|
50
50
|
- `cd hubot-sample`
|
|
51
51
|
3. Run `npm init` to create your package.json
|
|
52
|
-
- make sure the entry point is `src/sample.
|
|
52
|
+
- make sure the entry point is `src/sample.js`
|
|
53
53
|
4. Add your `.gitignore` to include `node_modules`
|
|
54
|
-
5. Edit the `src/sample.
|
|
54
|
+
5. Edit the `src/sample.js` file to include the above stub for your adapter
|
|
55
55
|
6. Edit the `package.json` to add a peer dependency on `hubot`
|
|
56
56
|
|
|
57
57
|
```json
|
|
58
58
|
"dependencies": {
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
|
-
"hubot": ">=
|
|
61
|
+
"hubot": ">=3.0"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"coffeescript": ">=1.2.0"
|
|
@@ -96,3 +96,30 @@ There is a an open issue in the node community around [npm linked peer dependenc
|
|
|
96
96
|
3. Now try running `hubot -a sample` again and see that the imports are properly loaded.
|
|
97
97
|
4. Once this is working properly, you can build out the functionality of your adapter as you see fit. Take a look at some of the other adapters to get some ideas for your implementation.
|
|
98
98
|
- Once packaged and deployed via `npm`, you won't need the dependency in `hubot` anymore since the peer dependency should work as an official module.
|
|
99
|
+
|
|
100
|
+
## Option 2. Setting Up Your Development Environment
|
|
101
|
+
|
|
102
|
+
Another option is to load the file from local disk.
|
|
103
|
+
|
|
104
|
+
1. Create a new folder for your adapter `hubot-sample`
|
|
105
|
+
- `mkdir hubot-sample`
|
|
106
|
+
2. Change your working directory to `hubot-sample`
|
|
107
|
+
- `cd hubot-sample`
|
|
108
|
+
3. Run `npm init` to create your package.json
|
|
109
|
+
- make sure the entry point is `src/sample.js`
|
|
110
|
+
4. Add your `.gitignore` to include `node_modules`
|
|
111
|
+
5. Edit the `src/sample.js` file to include the above stub for your adapter
|
|
112
|
+
6. Edit the `package.json` to add a peer dependency on `hubot`
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
"dependencies": {
|
|
116
|
+
},
|
|
117
|
+
"peerDependencies": {
|
|
118
|
+
"hubot": ">=4.2.0"
|
|
119
|
+
},
|
|
120
|
+
"devDependencies": {
|
|
121
|
+
"coffeescript": ">=1.2.0"
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
7. Run `npx hubot -p ./src -a sample.js`
|
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hubot",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"author": "hubot",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"github",
|
|
@@ -21,9 +21,8 @@
|
|
|
21
21
|
"connect-multiparty": "^2.2.0",
|
|
22
22
|
"express": "^4.18.2",
|
|
23
23
|
"express-basic-auth": "^1.2.1",
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"optparse": "^1.0.5"
|
|
24
|
+
"optparse": "^1.0.5",
|
|
25
|
+
"pino": "^8.11.0"
|
|
27
26
|
},
|
|
28
27
|
"devDependencies": {
|
|
29
28
|
"chai": "^4.3.7",
|
package/src/robot.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
-
require('log-node')()
|
|
3
|
-
|
|
4
2
|
const EventEmitter = require('events').EventEmitter
|
|
5
3
|
const fs = require('fs')
|
|
6
4
|
const path = require('path')
|
|
7
5
|
|
|
8
6
|
const async = require('async')
|
|
9
|
-
const
|
|
7
|
+
const pino = require('pino')
|
|
10
8
|
const HttpClient = require('./httpclient')
|
|
11
9
|
|
|
12
10
|
const Brain = require('./brain')
|
|
@@ -22,19 +20,17 @@ class Robot {
|
|
|
22
20
|
// Robots receive messages from a chat source (Campfire, irc, etc), and
|
|
23
21
|
// dispatch them to matching listeners.
|
|
24
22
|
//
|
|
25
|
-
// adapterPath - A String of the path to built-in adapters (defaults to src/adapters)
|
|
26
23
|
// adapter - A String of the adapter name.
|
|
27
24
|
// httpd - A Boolean whether to enable the HTTP daemon.
|
|
28
25
|
// name - A String of the robot name, defaults to Hubot.
|
|
29
26
|
// alias - A String of the alias of the robot name
|
|
30
|
-
constructor (
|
|
27
|
+
constructor (adapter, httpd, name, alias) {
|
|
31
28
|
if (name == null) {
|
|
32
29
|
name = 'Hubot'
|
|
33
30
|
}
|
|
34
31
|
if (alias == null) {
|
|
35
32
|
alias = false
|
|
36
33
|
}
|
|
37
|
-
this.adapterPath = path.join(__dirname, 'adapters')
|
|
38
34
|
|
|
39
35
|
this.name = name
|
|
40
36
|
this.events = new EventEmitter()
|
|
@@ -50,8 +46,15 @@ class Robot {
|
|
|
50
46
|
response: new Middleware(this),
|
|
51
47
|
receive: new Middleware(this)
|
|
52
48
|
}
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
this.logger = pino({
|
|
50
|
+
name,
|
|
51
|
+
level: process.env.HUBOT_LOG_LEVEL || 'info'
|
|
52
|
+
})
|
|
53
|
+
Reflect.defineProperty(this.logger, 'warning', {
|
|
54
|
+
value: this.logger.warn,
|
|
55
|
+
enumerable: true,
|
|
56
|
+
configurable: true
|
|
57
|
+
})
|
|
55
58
|
|
|
56
59
|
this.pingIntervalId = null
|
|
57
60
|
this.globalHttpOptions = {}
|
|
@@ -63,8 +66,6 @@ class Robot {
|
|
|
63
66
|
this.setupNullRouter()
|
|
64
67
|
}
|
|
65
68
|
|
|
66
|
-
this.loadAdapter(adapter)
|
|
67
|
-
|
|
68
69
|
this.adapterName = adapter
|
|
69
70
|
this.errorHandlers = []
|
|
70
71
|
|
|
@@ -502,19 +503,33 @@ class Robot {
|
|
|
502
503
|
// adapter - A String of the adapter name to use.
|
|
503
504
|
//
|
|
504
505
|
// Returns nothing.
|
|
505
|
-
loadAdapter (
|
|
506
|
-
this.logger.debug(`Loading adapter ${
|
|
507
|
-
|
|
506
|
+
async loadAdapter (adapterPath = null) {
|
|
507
|
+
this.logger.debug(`Loading adapter ${adapterPath ?? 'from npmjs:'} ${this.adapterName}`)
|
|
508
|
+
const ext = path.extname(adapterPath ?? '') ?? '.js'
|
|
508
509
|
try {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
510
|
+
if (Array.from(HUBOT_DEFAULT_ADAPTERS).indexOf(this.adapterName) > -1) {
|
|
511
|
+
this.adapter = this.requireAdapterFrom(path.resolve(path.join(__dirname, 'adapters', this.adapterName)))
|
|
512
|
+
} else if (['.js', '.cjs', '.coffee'].includes(ext)) {
|
|
513
|
+
this.adapter = this.requireAdapterFrom(path.resolve(adapterPath))
|
|
514
|
+
} else if (['.mjs'].includes(ext)) {
|
|
515
|
+
this.adapter = await this.importAdapterFrom(path.resolve(adapterPath))
|
|
516
|
+
} else {
|
|
517
|
+
this.adapter = this.requireAdapterFrom(`hubot-${this.adapterName}`)
|
|
518
|
+
}
|
|
512
519
|
} catch (err) {
|
|
513
|
-
this.logger.error(`Cannot load adapter ${
|
|
520
|
+
this.logger.error(`Cannot load adapter ${adapterPath ?? '[no path set]'} ${this.adapterName} - ${err}`)
|
|
514
521
|
process.exit(1)
|
|
515
522
|
}
|
|
516
523
|
}
|
|
517
524
|
|
|
525
|
+
requireAdapterFrom (adapaterPath) {
|
|
526
|
+
return require(adapaterPath).use(this)
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
async importAdapterFrom (adapterPath) {
|
|
530
|
+
return await (await import(adapterPath)).default.use(this)
|
|
531
|
+
}
|
|
532
|
+
|
|
518
533
|
// Public: Help Commands for Running Scripts.
|
|
519
534
|
//
|
|
520
535
|
// Returns an Array of help commands for running scripts.
|
package/test/adapter_test.js
CHANGED
|
@@ -15,9 +15,6 @@ describe('Adapter', function () {
|
|
|
15
15
|
this.robot = { receive: sinon.spy() }
|
|
16
16
|
})
|
|
17
17
|
|
|
18
|
-
// this one is hard, as it requires files
|
|
19
|
-
it('can load adapter by name')
|
|
20
|
-
|
|
21
18
|
describe('Public API', function () {
|
|
22
19
|
beforeEach(function () {
|
|
23
20
|
this.adapter = new Adapter(this.robot)
|
package/test/es2015_test.js
CHANGED
|
@@ -52,16 +52,16 @@ describe('hubot/es2015', function () {
|
|
|
52
52
|
expect(brain.get('foo')).to.equal('bar')
|
|
53
53
|
})
|
|
54
54
|
|
|
55
|
-
it('exports Robot class', function () {
|
|
55
|
+
it('exports Robot class', async function () {
|
|
56
56
|
mockery.enable({
|
|
57
57
|
warnOnReplace: false,
|
|
58
58
|
warnOnUnregistered: false
|
|
59
59
|
})
|
|
60
|
-
mockery.registerMock('hubot-mock-adapter', require('./fixtures/mock-adapter'))
|
|
60
|
+
mockery.registerMock('hubot-mock-adapter', require('./fixtures/mock-adapter.js'))
|
|
61
61
|
|
|
62
62
|
class MyRobot extends Robot {}
|
|
63
|
-
const robot = new MyRobot(
|
|
64
|
-
|
|
63
|
+
const robot = new MyRobot('mock-adapter', false, 'TestHubot')
|
|
64
|
+
await robot.loadAdapter()
|
|
65
65
|
expect(robot).to.be.an.instanceof(Robot)
|
|
66
66
|
expect(robot.name).to.equal('TestHubot')
|
|
67
67
|
|
|
@@ -193,7 +193,7 @@ describe('hubot/es2015', function () {
|
|
|
193
193
|
sinon.stub(Hubot, 'Robot')
|
|
194
194
|
|
|
195
195
|
expect(loadBot).to.be.a('function')
|
|
196
|
-
Hubot.loadBot(
|
|
197
|
-
expect(Hubot.Robot).to.be.called.calledWith(
|
|
196
|
+
Hubot.loadBot(null, 'adapter', 'enableHttpd', 'botName', 'botAlias')
|
|
197
|
+
expect(Hubot.Robot).to.be.called.calledWith(null, 'adapter', 'enableHttpd', 'botName', 'botAlias')
|
|
198
198
|
})
|
|
199
199
|
})
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { Adapter } from '../../es2015.js' // eslint-disable-line import/no-unresolved
|
|
4
|
+
|
|
5
|
+
class MockAdapter extends Adapter {
|
|
6
|
+
constructor (robot) {
|
|
7
|
+
super(robot)
|
|
8
|
+
this.name = 'MockAdapter'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
send (envelope, ...strings) {
|
|
12
|
+
this.emit('send', envelope, strings)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
reply (envelope, ...strings) {
|
|
16
|
+
this.emit('reply', envelope, strings)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
topic (envelope, ...strings) {
|
|
20
|
+
this.emit('topic', envelope, strings)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
play (envelope, ...strings) {
|
|
24
|
+
this.emit('play', envelope, strings)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
run () {
|
|
28
|
+
// This is required to get the scripts loaded
|
|
29
|
+
this.emit('connected')
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
close () {
|
|
33
|
+
this.emit('closed')
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
MockAdapter
|
|
38
|
+
}
|
|
39
|
+
export default {
|
|
40
|
+
use (robot) {
|
|
41
|
+
return new MockAdapter(robot)
|
|
42
|
+
}
|
|
43
|
+
}
|
package/test/middleware_test.js
CHANGED
|
@@ -345,14 +345,15 @@ describe('Middleware', function () {
|
|
|
345
345
|
// Any new fields that are exposed to middleware should be explicitly
|
|
346
346
|
// tested for.
|
|
347
347
|
describe('Public Middleware APIs', function () {
|
|
348
|
-
beforeEach(function () {
|
|
348
|
+
beforeEach(async function () {
|
|
349
349
|
mockery.enable({
|
|
350
350
|
warnOnReplace: false,
|
|
351
351
|
warnOnUnregistered: false
|
|
352
352
|
})
|
|
353
|
-
mockery.registerMock('hubot-mock-adapter', require('./fixtures/mock-adapter'))
|
|
353
|
+
mockery.registerMock('hubot-mock-adapter', require('./fixtures/mock-adapter.js'))
|
|
354
354
|
process.env.EXPRESS_PORT = 0
|
|
355
|
-
this.robot = new Robot(
|
|
355
|
+
this.robot = new Robot('mock-adapter', true, 'TestHubot')
|
|
356
|
+
await this.robot.loadAdapter()
|
|
356
357
|
this.robot.run
|
|
357
358
|
|
|
358
359
|
// Re-throw AssertionErrors for clearer test failures
|
package/test/robot_test.js
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
// Assertions and Stubbing
|
|
7
7
|
const chai = require('chai')
|
|
8
8
|
const sinon = require('sinon')
|
|
9
|
-
const emitter = require('log/lib/emitter')
|
|
10
9
|
chai.use(require('sinon-chai'))
|
|
11
10
|
|
|
12
11
|
const expect = chai.expect
|
|
@@ -24,15 +23,16 @@ const mockery = require('mockery')
|
|
|
24
23
|
const path = require('path')
|
|
25
24
|
|
|
26
25
|
describe('Robot', function () {
|
|
27
|
-
beforeEach(function () {
|
|
26
|
+
beforeEach(async function () {
|
|
28
27
|
mockery.enable({
|
|
29
28
|
warnOnReplace: false,
|
|
30
29
|
warnOnUnregistered: false
|
|
31
30
|
})
|
|
32
|
-
mockery.registerMock('hubot-mock-adapter', require('./fixtures/mock-adapter'))
|
|
31
|
+
mockery.registerMock('hubot-mock-adapter', require('./fixtures/mock-adapter.js'))
|
|
33
32
|
process.env.EXPRESS_PORT = 0
|
|
34
|
-
this.robot = new Robot(
|
|
33
|
+
this.robot = new Robot('mock-adapter', true, 'TestHubot')
|
|
35
34
|
this.robot.alias = 'Hubot'
|
|
35
|
+
await this.robot.loadAdapter()
|
|
36
36
|
this.robot.run()
|
|
37
37
|
|
|
38
38
|
// Re-throw AssertionErrors for clearer test failures
|
|
@@ -389,8 +389,8 @@ describe('Robot', function () {
|
|
|
389
389
|
this.sandbox.stub(module, '_load').returns(script)
|
|
390
390
|
this.sandbox.stub(this.robot, 'parseHelp')
|
|
391
391
|
|
|
392
|
-
this.robot.loadFile('./scripts', '
|
|
393
|
-
expect(module._load).to.have.been.calledWith(path.join('scripts', '
|
|
392
|
+
this.robot.loadFile('./scripts', 'TestScript.js')
|
|
393
|
+
expect(module._load).to.have.been.calledWith(path.join('scripts', 'TestScript'))
|
|
394
394
|
})
|
|
395
395
|
|
|
396
396
|
describe('proper script', function () {
|
|
@@ -403,13 +403,13 @@ describe('Robot', function () {
|
|
|
403
403
|
})
|
|
404
404
|
|
|
405
405
|
it('should call the script with the Robot', function () {
|
|
406
|
-
this.robot.loadFile('./scripts', '
|
|
406
|
+
this.robot.loadFile('./scripts', 'TestScript.js')
|
|
407
407
|
expect(this.script).to.have.been.calledWith(this.robot)
|
|
408
408
|
})
|
|
409
409
|
|
|
410
410
|
it('should parse the script documentation', function () {
|
|
411
|
-
this.robot.loadFile('./scripts', '
|
|
412
|
-
expect(this.robot.parseHelp).to.have.been.calledWith(path.join('scripts', '
|
|
411
|
+
this.robot.loadFile('./scripts', 'TestScript.js')
|
|
412
|
+
expect(this.robot.parseHelp).to.have.been.calledWith(path.join('scripts', 'TestScript.js'))
|
|
413
413
|
})
|
|
414
414
|
})
|
|
415
415
|
|
|
@@ -423,24 +423,15 @@ describe('Robot', function () {
|
|
|
423
423
|
})
|
|
424
424
|
|
|
425
425
|
it('logs a warning for a .js file', function () {
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
}
|
|
430
|
-
emitter.on('log', listener)
|
|
431
|
-
this.robot.loadFile('./scripts', 'test-script.js')
|
|
432
|
-
expect(wasCalled).to.be.true
|
|
433
|
-
emitter.off('log', listener)
|
|
426
|
+
sinon.stub(this.robot.logger, 'warning')
|
|
427
|
+
this.robot.loadFile('./scripts', 'TestScript.js')
|
|
428
|
+
expect(this.robot.logger.warning).to.have.been.called
|
|
434
429
|
})
|
|
435
430
|
|
|
436
431
|
it('logs a warning for a .mjs file', function () {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
}
|
|
441
|
-
emitter.on('log', listener)
|
|
442
|
-
this.robot.loadFile('./scripts', 'test-script.mjs')
|
|
443
|
-
expect(wasCalled).to.be.true
|
|
432
|
+
sinon.stub(this.robot.logger, 'warning')
|
|
433
|
+
this.robot.loadFile('./scripts', 'TestScript.mjs')
|
|
434
|
+
expect(this.robot.logger.warning).to.have.been.called
|
|
444
435
|
})
|
|
445
436
|
})
|
|
446
437
|
|
|
@@ -1091,3 +1082,55 @@ describe('Robot', function () {
|
|
|
1091
1082
|
})
|
|
1092
1083
|
})
|
|
1093
1084
|
})
|
|
1085
|
+
|
|
1086
|
+
describe('Robot ES6', () => {
|
|
1087
|
+
let robot = null
|
|
1088
|
+
beforeEach(async () => {
|
|
1089
|
+
process.env.EXPRESS_PORT = 0
|
|
1090
|
+
robot = new Robot('MockAdapter', true, 'TestHubot')
|
|
1091
|
+
robot.alias = 'Hubot'
|
|
1092
|
+
await robot.loadAdapter('./test/fixtures/MockAdapter.mjs')
|
|
1093
|
+
robot.loadFile(path.resolve('./test/fixtures/'), 'TestScript.js')
|
|
1094
|
+
robot.run()
|
|
1095
|
+
})
|
|
1096
|
+
afterEach(() => {
|
|
1097
|
+
robot.shutdown()
|
|
1098
|
+
})
|
|
1099
|
+
it('should load an ES6 module adapter from a file', async () => {
|
|
1100
|
+
const { MockAdapter } = await import('./fixtures/MockAdapter.mjs')
|
|
1101
|
+
expect(robot.adapter).to.be.an.instanceOf(MockAdapter)
|
|
1102
|
+
expect(robot.adapter.name).to.equal('MockAdapter')
|
|
1103
|
+
})
|
|
1104
|
+
it('should respond to a message', async () => {
|
|
1105
|
+
const sent = (envelop, strings) => {
|
|
1106
|
+
expect(strings).to.deep.equal(['test response'])
|
|
1107
|
+
}
|
|
1108
|
+
robot.adapter.on('send', sent)
|
|
1109
|
+
await robot.adapter.receive(new TextMessage('tester', 'hubot test'))
|
|
1110
|
+
})
|
|
1111
|
+
})
|
|
1112
|
+
|
|
1113
|
+
describe('Robot Coffeescript', () => {
|
|
1114
|
+
let robot = null
|
|
1115
|
+
beforeEach(async () => {
|
|
1116
|
+
process.env.EXPRESS_PORT = 0
|
|
1117
|
+
robot = new Robot('MockAdapter', true, 'TestHubot')
|
|
1118
|
+
robot.alias = 'Hubot'
|
|
1119
|
+
await robot.loadAdapter('./test/fixtures/MockAdapter.coffee')
|
|
1120
|
+
robot.loadFile(path.resolve('./test/fixtures/'), 'TestScript.coffee')
|
|
1121
|
+
robot.run()
|
|
1122
|
+
})
|
|
1123
|
+
afterEach(() => {
|
|
1124
|
+
robot.shutdown()
|
|
1125
|
+
})
|
|
1126
|
+
it('should load a CoffeeScript adapter from a file', async () => {
|
|
1127
|
+
expect(robot.adapter.name).to.equal('MockAdapter')
|
|
1128
|
+
})
|
|
1129
|
+
it('should load a coffeescript file and respond to a message', async () => {
|
|
1130
|
+
const sent = (envelop, strings) => {
|
|
1131
|
+
expect(strings).to.deep.equal(['test response from coffeescript'])
|
|
1132
|
+
}
|
|
1133
|
+
robot.adapter.on('send', sent)
|
|
1134
|
+
await robot.adapter.receive(new TextMessage('tester', 'hubot test'))
|
|
1135
|
+
})
|
|
1136
|
+
})
|
package/test/shell_test.js
CHANGED
|
@@ -11,8 +11,9 @@ const expect = chai.expect
|
|
|
11
11
|
const Robot = require('../src/robot')
|
|
12
12
|
|
|
13
13
|
describe('Shell Adapter', function () {
|
|
14
|
-
beforeEach(function () {
|
|
15
|
-
this.robot = new Robot(
|
|
14
|
+
beforeEach(async function () {
|
|
15
|
+
this.robot = new Robot('shell', false, 'TestHubot')
|
|
16
|
+
await this.robot.loadAdapter()
|
|
16
17
|
this.robot.run()
|
|
17
18
|
})
|
|
18
19
|
|