boty 0.1.0 → 0.1.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +18 -1
- data/README.md +39 -3
- data/Rakefile +1 -1
- data/boty.gemspec +9 -5
- data/lib/boty.rb +2 -1
- data/lib/boty/action.rb +26 -35
- data/lib/boty/action_description.rb +24 -0
- data/lib/boty/bot.rb +36 -25
- data/lib/boty/dsl.rb +3 -3
- data/lib/boty/eventable.rb +4 -3
- data/lib/boty/http.rb +3 -4
- data/lib/boty/locale.rb +12 -13
- data/lib/boty/logger.rb +14 -3
- data/lib/boty/rspec.rb +15 -16
- data/lib/boty/session.rb +7 -8
- data/lib/boty/slack.rb +11 -3
- data/lib/boty/slack/channel.rb +2 -1
- data/lib/boty/slack/chat.rb +5 -1
- data/lib/boty/slack/rtm.rb +1 -1
- data/lib/boty/slack/url.rb +10 -5
- data/lib/boty/slack/user.rb +2 -1
- data/lib/boty/slack/users.rb +1 -1
- data/lib/boty/version.rb +1 -1
- data/script/knows.rb +10 -9
- data/script/pug.rb +5 -1
- data/spec/boty/bot_spec.rb +89 -72
- data/spec/boty/cli_spec.rb +5 -5
- data/spec/boty/dsl_spec.rb +12 -13
- data/spec/boty/rspec_spec.rb +2 -1
- data/spec/boty/script_loader_spec.rb +8 -6
- data/spec/boty/session_spec.rb +2 -2
- data/spec/boty/slack/chat_spec.rb +18 -18
- data/spec/boty/slack/im_spec.rb +4 -4
- data/spec/boty/slack/message_spec.rb +11 -9
- data/spec/boty/slack/rtm_spec.rb +3 -3
- data/spec/boty/slack/url_spec.rb +5 -5
- data/spec/boty/slack/users_spec.rb +23 -23
- data/spec/happy_path_spec.rb +19 -18
- data/spec/script/i18n_spec.rb +18 -10
- data/spec/script/knows_spec.rb +8 -7
- data/spec/script/pug_spec.rb +27 -10
- data/spec/script/remember_spec.rb +27 -21
- data/spec/spec_helper.rb +4 -3
- data/spec/support/em_support.rb +1 -3
- data/spec/support/faraday_support.rb +0 -1
- data/spec/support/faye_support.rb +9 -6
- data/spec/support/file_system_matchers.rb +4 -4
- data/spec/support/logger_support.rb +9 -12
- data/spec/support/session_support.rb +26 -15
- data/spec/support/slack_support.rb +9 -6
- data/spec/support/template_project_support.rb +24 -23
- data/spec/support/thor_support.rb +3 -3
- data/template/project/%bot_name%.rb +4 -1
- data/template/project/spec/spec_helper.rb +4 -2
- metadata +21 -4
data/lib/boty/eventable.rb
CHANGED
@@ -6,7 +6,8 @@ module Boty
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def event(data)
|
9
|
-
|
9
|
+
type = event_type data
|
10
|
+
return unless type
|
10
11
|
|
11
12
|
events[type].each do |action|
|
12
13
|
action.call data
|
@@ -30,9 +31,9 @@ module Boty
|
|
30
31
|
|
31
32
|
def event_type(data)
|
32
33
|
type = data["type"].to_sym
|
33
|
-
logger.debug
|
34
|
+
logger.debug do "event[#{type}] arrived: #{data}" end
|
34
35
|
unless events[type]
|
35
|
-
logger.debug "no action binded to #{type}"
|
36
|
+
logger.debug do "no action binded to #{type}" end
|
36
37
|
return
|
37
38
|
end
|
38
39
|
type
|
data/lib/boty/http.rb
CHANGED
@@ -13,17 +13,16 @@ module Boty
|
|
13
13
|
|
14
14
|
def connection(verb, url, params)
|
15
15
|
uri = URI url
|
16
|
-
Faraday.new(url: "#{uri.scheme}://#{uri.host}") { |builder|
|
16
|
+
faraday = Faraday.new(url: "#{uri.scheme}://#{uri.host}") { |builder|
|
17
17
|
builder.adapter(*Faraday.default_adapter)
|
18
|
-
}.public_send(verb) { |req|
|
19
|
-
req.url uri.path, params
|
20
18
|
}
|
19
|
+
faraday.public_send(verb) { |req| req.url uri.path, params }
|
21
20
|
end
|
22
21
|
|
23
22
|
def handle_response
|
24
23
|
# TODO: use a response parser accordingly to the
|
25
24
|
body = response.body
|
26
|
-
if /
|
25
|
+
if %r{application/json}.match response.headers["Content-Type"]
|
27
26
|
JSON.parse body
|
28
27
|
else
|
29
28
|
body
|
data/lib/boty/locale.rb
CHANGED
@@ -1,24 +1,23 @@
|
|
1
1
|
module Boty
|
2
2
|
class Locale
|
3
|
-
def self.reload(
|
4
|
-
|
5
|
-
I18n.load_path =
|
3
|
+
def self.reload(language = nil)
|
4
|
+
locale = new
|
5
|
+
I18n.load_path = locale.locales_paths.uniq
|
6
6
|
I18n.available_locales = I18n::Backend::Simple.new.available_locales
|
7
|
-
|
7
|
+
locale.locale = language if language
|
8
8
|
end
|
9
9
|
|
10
10
|
def locales_paths
|
11
|
-
|
12
|
-
(
|
13
|
-
|
11
|
+
locale_yaml_files_path = "../../../locale/**/*.yml"
|
12
|
+
default_locales_path = File.expand_path(locale_yaml_files_path, __FILE__)
|
13
|
+
(Dir["locale/**/*.yml"] + Dir[default_locales_path])
|
14
|
+
.map { |file| File.expand_path file }
|
14
15
|
end
|
15
16
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
I18n.locale = :en
|
21
|
-
end
|
17
|
+
def locale=(language)
|
18
|
+
I18n.locale = language
|
19
|
+
rescue I18n::InvalidLocale
|
20
|
+
I18n.locale = :en
|
22
21
|
end
|
23
22
|
end
|
24
23
|
end
|
data/lib/boty/logger.rb
CHANGED
@@ -17,6 +17,16 @@ module Boty
|
|
17
17
|
Logger.adapter
|
18
18
|
end
|
19
19
|
|
20
|
+
def log_error(error, message)
|
21
|
+
logger.error do
|
22
|
+
"#{message}\n#{error.message}"
|
23
|
+
end
|
24
|
+
|
25
|
+
logger.debug do
|
26
|
+
error.backtrace.reduce("") { |a, e| a << "#{e}\n" }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
20
30
|
class Multi < ::Logger
|
21
31
|
def initialize(adapters)
|
22
32
|
@adapters = adapters
|
@@ -38,7 +48,7 @@ module Boty
|
|
38
48
|
class Memory < ::Logger
|
39
49
|
attr_reader :logs
|
40
50
|
|
41
|
-
def initialize(*
|
51
|
+
def initialize(*)
|
42
52
|
@logs = []
|
43
53
|
end
|
44
54
|
|
@@ -52,8 +62,9 @@ module Boty
|
|
52
62
|
end
|
53
63
|
|
54
64
|
class Null < ::Logger
|
55
|
-
def initialize(*
|
56
|
-
|
65
|
+
def initialize(*); end
|
66
|
+
|
67
|
+
def add(*, &block); end
|
57
68
|
end
|
58
69
|
end
|
59
70
|
end
|
data/lib/boty/rspec.rb
CHANGED
@@ -8,23 +8,22 @@ module Boty
|
|
8
8
|
include SlackSupport::Users
|
9
9
|
|
10
10
|
before do
|
11
|
-
@_bot = Boty::Bot.new(
|
12
|
-
|
13
|
-
)
|
14
|
-
|
15
|
-
class << Boty::Slack.chat
|
16
|
-
attr_accessor :messages
|
17
|
-
|
18
|
-
def post_message(message, options)
|
19
|
-
@messages ||= []
|
20
|
-
@messages << { message: message, options: options }
|
21
|
-
end
|
22
|
-
end
|
11
|
+
@_bot = Boty::Bot.new("id" => "1234", "name" => "bot")
|
12
|
+
mock_post_message
|
23
13
|
end
|
24
14
|
|
25
|
-
let(:bot) {
|
26
|
-
|
27
|
-
|
15
|
+
let(:bot) { Boty::DSL.new @_bot }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def mock_post_message
|
20
|
+
class << Boty::Slack.chat
|
21
|
+
attr_accessor :messages
|
22
|
+
|
23
|
+
def post_message(message, options)
|
24
|
+
@messages ||= []
|
25
|
+
@messages << { message: message, options: options }
|
26
|
+
end
|
28
27
|
end
|
29
28
|
end
|
30
29
|
|
@@ -39,7 +38,7 @@ module Boty
|
|
39
38
|
|
40
39
|
::RSpec::Matchers.define :have_responded do |expected|
|
41
40
|
# TODO: add proper messages for failures.
|
42
|
-
match do
|
41
|
+
match do
|
43
42
|
last_message = Slack.chat.messages.last
|
44
43
|
expected == last_message[:message]
|
45
44
|
end
|
data/lib/boty/session.rb
CHANGED
@@ -22,38 +22,37 @@ module Boty
|
|
22
22
|
begin
|
23
23
|
on_message event, @bot
|
24
24
|
rescue StandardError => e
|
25
|
-
|
26
|
-
logger.debug e.backtrace.reduce("") { |msg, line| msg << "#{line}\n" }
|
25
|
+
log_error e, "Message #{event} could not be processed."
|
27
26
|
end
|
28
27
|
end
|
29
28
|
end
|
30
29
|
|
31
30
|
def login
|
32
|
-
logger.debug
|
31
|
+
logger.debug do "Logging in against slack right now" end
|
33
32
|
@slack_info = Slack.rtm.start
|
34
|
-
logger.debug
|
33
|
+
logger.debug do "yep! logged in!" end
|
35
34
|
@session_url = @slack_info["url"]
|
36
35
|
end
|
37
36
|
|
38
37
|
def initialize_bot(&block)
|
39
38
|
Bot.new(@slack_info["self"]).tap { |bot|
|
40
39
|
DSL.new(bot).instance_eval(&block) if block_given?
|
41
|
-
logger.debug
|
40
|
+
logger.debug do "Bot is configured and ready to go!" end
|
42
41
|
}
|
43
42
|
end
|
44
43
|
|
45
44
|
def on_message(event, bot)
|
46
|
-
logger.debug
|
45
|
+
logger.debug do "Message arrived. Creating bot event" end
|
47
46
|
bot.event JSON.parse(event.data)
|
48
47
|
end
|
49
48
|
|
50
49
|
def on_close
|
51
50
|
logger.debug { "bye bye" }
|
52
|
-
#
|
51
|
+
# TODO: try to reconnect (stablish_connection) unless is an em interrupt
|
53
52
|
end
|
54
53
|
|
55
54
|
def stablish_connection
|
56
|
-
logger.debug
|
55
|
+
logger.debug do "Starting to listen on #{@session_url}" end
|
57
56
|
ws = Faye::WebSocket::Client.new @session_url
|
58
57
|
ws.on :close do on_close end
|
59
58
|
on_connect ws
|
data/lib/boty/slack.rb
CHANGED
@@ -10,9 +10,17 @@ require "boty/slack/message"
|
|
10
10
|
module Boty
|
11
11
|
module Slack
|
12
12
|
class << self
|
13
|
-
def chat
|
14
|
-
|
15
|
-
|
13
|
+
def chat
|
14
|
+
@chat ||= Chat.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def rtm
|
18
|
+
@rtm ||= RTM.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def users
|
22
|
+
@users ||= Users.new
|
23
|
+
end
|
16
24
|
end
|
17
25
|
|
18
26
|
def User(user_id)
|
data/lib/boty/slack/channel.rb
CHANGED
data/lib/boty/slack/chat.rb
CHANGED
data/lib/boty/slack/rtm.rb
CHANGED
data/lib/boty/slack/url.rb
CHANGED
@@ -2,9 +2,14 @@ module Boty
|
|
2
2
|
module Slack
|
3
3
|
module URL
|
4
4
|
def self.included(base)
|
5
|
+
class << base
|
6
|
+
attr_reader :_url
|
7
|
+
end
|
8
|
+
|
5
9
|
base.instance_eval do
|
6
|
-
def url(url)
|
7
|
-
|
10
|
+
def url(url)
|
11
|
+
@_url = url
|
12
|
+
end
|
8
13
|
end
|
9
14
|
end
|
10
15
|
|
@@ -16,11 +21,11 @@ module Boty
|
|
16
21
|
|
17
22
|
def parameterize(user_parameters, path: nil)
|
18
23
|
url = path ? self.class._url + path : self.class._url
|
19
|
-
parameters = {token: ENV["SLACK_BOT_API_TOKEN"]}.merge user_parameters
|
20
|
-
parameters.reduce(url + "?") { |
|
24
|
+
parameters = { token: ENV["SLACK_BOT_API_TOKEN"] }.merge user_parameters
|
25
|
+
parameters.reduce(url + "?") { |final_url, param|
|
21
26
|
parameter = param[0]
|
22
27
|
value = URI.encode param[1].to_s
|
23
|
-
"#{
|
28
|
+
"#{final_url}#{parameter}=#{value}&"
|
24
29
|
}.gsub(/&$/, "")
|
25
30
|
end
|
26
31
|
end
|
data/lib/boty/slack/user.rb
CHANGED
data/lib/boty/slack/users.rb
CHANGED
data/lib/boty/version.rb
CHANGED
data/script/knows.rb
CHANGED
@@ -6,25 +6,26 @@ end
|
|
6
6
|
class KnownFormmater
|
7
7
|
def initialize(actions)
|
8
8
|
@actions = actions
|
9
|
-
@
|
9
|
+
@descriptions = @actions.map(&:desc)
|
10
|
+
@max_size = @descriptions.map(&:command).map(&:length).max
|
10
11
|
end
|
11
12
|
|
12
13
|
def format
|
13
|
-
@
|
14
|
-
|
14
|
+
@descriptions.inject("```\n") { |message, description|
|
15
|
+
message << format_description(description) + "\n"
|
15
16
|
} + "```"
|
16
17
|
end
|
17
18
|
|
18
19
|
private
|
19
20
|
|
20
|
-
def name(
|
21
|
-
pad = @max_size -
|
22
|
-
(" " * pad) +
|
21
|
+
def name(trigger)
|
22
|
+
pad = @max_size - trigger.length
|
23
|
+
(" " * pad) + trigger
|
23
24
|
end
|
24
25
|
|
25
|
-
def
|
26
|
-
message = name command
|
27
|
-
message << ": #{
|
26
|
+
def format_description(description)
|
27
|
+
message = name description.command
|
28
|
+
message << ": #{description.description}" if description.description
|
28
29
|
message
|
29
30
|
end
|
30
31
|
end
|
data/script/pug.rb
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
desc "pug me", I18n.t("scripts.pug_me")
|
2
2
|
command(/pug me/i) do
|
3
3
|
response = http.get "http://pugme.herokuapp.com/random"
|
4
|
-
say "<#{response[
|
4
|
+
say "<#{response['pug']}>"
|
5
5
|
end
|
6
6
|
|
7
7
|
desc "pug bomb X", I18n.t("scripts.pug_bomb")
|
8
8
|
command(/pug bomb( \d+)?/i) do |count|
|
9
9
|
count = (count || "5").strip
|
10
|
+
if count.to_i > 5
|
11
|
+
count = "5"
|
12
|
+
say "wow! so many pugs! sendind 5 instead."
|
13
|
+
end
|
10
14
|
response = http.get "http://pugme.herokuapp.com/bomb", count: count
|
11
15
|
response["pugs"].each do |pug| say "<#{pug}>" end
|
12
16
|
end
|
data/spec/boty/bot_spec.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
module Boty
|
2
2
|
RSpec.describe Bot do
|
3
|
+
include Boty
|
3
4
|
subject(:bot) { described_class.new bot_info }
|
4
5
|
|
5
|
-
let(:bot_info)
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
let(:bot_info) do
|
7
|
+
{
|
8
|
+
"id" => "666",
|
9
|
+
"name" => "jabber"
|
10
|
+
}
|
11
|
+
end
|
9
12
|
|
10
13
|
describe "#on" do
|
11
14
|
it "binds an event `'type'` to a block" do
|
@@ -22,18 +25,20 @@ module Boty
|
|
22
25
|
end
|
23
26
|
|
24
27
|
describe "#off" do
|
25
|
-
let(:data)
|
26
|
-
|
27
|
-
|
28
|
-
|
28
|
+
let(:data) do
|
29
|
+
{
|
30
|
+
"type" => "bbq",
|
31
|
+
"text" => "omg. wtf."
|
32
|
+
}
|
33
|
+
end
|
29
34
|
|
30
35
|
it "unbounds an event by type AND block, just if the block is the same" do
|
31
36
|
@permanent_executed = false
|
32
|
-
permanent_block = ->(_)
|
37
|
+
permanent_block = ->(_) do @permanent_executed = true end
|
33
38
|
bot.on :bbq, &permanent_block
|
34
39
|
|
35
40
|
@ephemeral_executed = false
|
36
|
-
ephemeral_block = ->(_)
|
41
|
+
ephemeral_block = ->(_) do @ephemeral_executed = true end
|
37
42
|
bot.on :bbq, &ephemeral_block
|
38
43
|
bot.off :bbq, &ephemeral_block
|
39
44
|
|
@@ -45,9 +50,9 @@ module Boty
|
|
45
50
|
|
46
51
|
it "unbounds all events by type" do
|
47
52
|
@first_block = @second_block = @third_block = false
|
48
|
-
bot.on(:bbq)
|
49
|
-
bot.on(:bbq)
|
50
|
-
bot.on(:bbq)
|
53
|
+
bot.on(:bbq) do |_| @first_block = true end
|
54
|
+
bot.on(:bbq) do |_| @second_block = true end
|
55
|
+
bot.on(:bbq) do |_| @third_block = true end
|
51
56
|
bot.off(:bbq)
|
52
57
|
|
53
58
|
bot.event data
|
@@ -59,21 +64,23 @@ module Boty
|
|
59
64
|
end
|
60
65
|
|
61
66
|
describe "#match", :users do
|
62
|
-
let(:data)
|
63
|
-
|
64
|
-
|
65
|
-
|
67
|
+
let(:data) do
|
68
|
+
{
|
69
|
+
"type" => "message",
|
70
|
+
"text" => "bbq omg lol"
|
71
|
+
}
|
72
|
+
end
|
66
73
|
|
67
74
|
it "binds a regex to events of `type => message`" do
|
68
|
-
|
75
|
+
message = nil
|
69
76
|
bot.match(/omg/i) do
|
70
|
-
|
77
|
+
message = self.message
|
71
78
|
end
|
72
79
|
bot.event data
|
73
80
|
|
74
|
-
expect(
|
75
|
-
expect(
|
76
|
-
expect(
|
81
|
+
expect(message).to be_a Boty::Slack::Message
|
82
|
+
expect(message.text).to eq "bbq omg lol"
|
83
|
+
expect(message.match[0]).to eq "omg"
|
77
84
|
end
|
78
85
|
|
79
86
|
it "binds various actions to events of type message" do
|
@@ -82,23 +89,22 @@ module Boty
|
|
82
89
|
bot.match(/omg/i) do iterations << "second" end
|
83
90
|
bot.event data
|
84
91
|
|
85
|
-
expect(iterations).to eq
|
92
|
+
expect(iterations).to eq %w(first second)
|
86
93
|
end
|
87
94
|
|
88
95
|
it "passes the matched strings as parameters to block action" do
|
89
|
-
|
96
|
+
rspec = self
|
90
97
|
bot.match(/(bbq) omg (lol)/i) do |bbq, lol|
|
91
|
-
|
98
|
+
rspec.expect(bbq).to rspec.eq "bbq"
|
99
|
+
rspec.expect(lol).to rspec.eq "lol"
|
92
100
|
end
|
93
|
-
bot.event data
|
94
101
|
|
95
|
-
|
96
|
-
expect(_bbq).to eq "bbq"
|
102
|
+
bot.event data
|
97
103
|
end
|
98
104
|
|
99
105
|
it "evals the block in the context of the bot" do
|
100
106
|
dsl = nil
|
101
|
-
bot.match(/omg/)
|
107
|
+
bot.match(/omg/) do dsl = self end
|
102
108
|
bot.event data
|
103
109
|
|
104
110
|
expect(dsl.bot).to eq bot
|
@@ -106,10 +112,12 @@ module Boty
|
|
106
112
|
end
|
107
113
|
|
108
114
|
describe "#respond", :users do
|
109
|
-
let(:data)
|
110
|
-
|
111
|
-
|
112
|
-
|
115
|
+
let(:data) do
|
116
|
+
{
|
117
|
+
"type" => "message",
|
118
|
+
"text" => "hey <@jabber>, omg me"
|
119
|
+
}
|
120
|
+
end
|
113
121
|
|
114
122
|
it "binds actions for messages only when there is a mention (@bot)" do
|
115
123
|
expect { |b|
|
@@ -146,7 +154,7 @@ module Boty
|
|
146
154
|
|
147
155
|
it "evals the block in the context of the bot" do
|
148
156
|
dsl = nil
|
149
|
-
bot.respond(/omg me/)
|
157
|
+
bot.respond(/omg me/) do dsl = self end
|
150
158
|
bot.event data
|
151
159
|
|
152
160
|
expect(dsl.bot).to eq bot
|
@@ -159,10 +167,12 @@ module Boty
|
|
159
167
|
end
|
160
168
|
|
161
169
|
describe "#no_match" do
|
162
|
-
let(:data)
|
163
|
-
|
164
|
-
|
165
|
-
|
170
|
+
let(:data) do
|
171
|
+
{
|
172
|
+
"type" => "message",
|
173
|
+
"text" => "bbq omg lol"
|
174
|
+
}
|
175
|
+
end
|
166
176
|
|
167
177
|
it "removes a message based on the regex AND the block" do
|
168
178
|
permanent_executed = false
|
@@ -182,8 +192,8 @@ module Boty
|
|
182
192
|
|
183
193
|
it "removes all binds for a specific regex" do
|
184
194
|
first = second = false
|
185
|
-
bot.match(/omg/i)
|
186
|
-
bot.match(/omg/i)
|
195
|
+
bot.match(/omg/i) do first = true end
|
196
|
+
bot.match(/omg/i) do second = true end
|
187
197
|
bot.no_match(/omg/i)
|
188
198
|
|
189
199
|
bot.event data
|
@@ -194,10 +204,12 @@ module Boty
|
|
194
204
|
end
|
195
205
|
|
196
206
|
describe "#no_respond" do
|
197
|
-
let(:data)
|
198
|
-
|
199
|
-
|
200
|
-
|
207
|
+
let(:data) do
|
208
|
+
{
|
209
|
+
"type" => "message",
|
210
|
+
"text" => "hey <@#{bot.name}>, omg me"
|
211
|
+
}
|
212
|
+
end
|
201
213
|
|
202
214
|
it "removes a message based on the regex AND the block" do
|
203
215
|
permanent_executed = false
|
@@ -217,8 +229,8 @@ module Boty
|
|
217
229
|
|
218
230
|
it "removes all binds for a specific regex" do
|
219
231
|
first = second = false
|
220
|
-
bot.respond(/omg/i)
|
221
|
-
bot.respond(/omg/i)
|
232
|
+
bot.respond(/omg/i) do first = true end
|
233
|
+
bot.respond(/omg/i) do second = true end
|
222
234
|
bot.no_respond(/omg/i)
|
223
235
|
|
224
236
|
dsl.bot.event data
|
@@ -231,22 +243,22 @@ module Boty
|
|
231
243
|
|
232
244
|
describe "#say" do
|
233
245
|
it "sends a string using the slack api to general (default) channel" do
|
234
|
-
expect(Slack.chat).to receive(:post_message)
|
235
|
-
with "something", channel: "#general"
|
246
|
+
expect(Slack.chat).to receive(:post_message)
|
247
|
+
.with "something", channel: "#general"
|
236
248
|
|
237
249
|
bot.say "something"
|
238
250
|
end
|
239
251
|
|
240
252
|
it "sends a message to the channel specified by parameter" do
|
241
|
-
expect(Slack.chat).to receive(:post_message)
|
242
|
-
with "omg pugs!", channel: "#omg"
|
253
|
+
expect(Slack.chat).to receive(:post_message)
|
254
|
+
.with "omg pugs!", channel: "#omg"
|
243
255
|
|
244
256
|
bot.say "omg pugs!", channel: "#omg"
|
245
257
|
end
|
246
258
|
|
247
259
|
it "accepts extra parameters and send them to the slack api" do
|
248
|
-
expect(Slack.chat).to receive(:post_message)
|
249
|
-
with "omg pugs!", channel: "#omg", omg: "lol"
|
260
|
+
expect(Slack.chat).to receive(:post_message)
|
261
|
+
.with "omg pugs!", channel: "#omg", omg: "lol"
|
250
262
|
|
251
263
|
bot.say "omg pugs!", channel: "#omg", omg: "lol"
|
252
264
|
end
|
@@ -262,9 +274,9 @@ module Boty
|
|
262
274
|
|
263
275
|
describe "#im" do
|
264
276
|
before do
|
265
|
-
|
266
|
-
|
267
|
-
and_return
|
277
|
+
user = Boty::Slack::User.new "id" => "U123", "name" => "julian"
|
278
|
+
allow(Slack.users).to receive(:by_name).with("julian")
|
279
|
+
.and_return user
|
268
280
|
end
|
269
281
|
|
270
282
|
it "sends a message in the back channel (particular, im...)" do
|
@@ -287,9 +299,8 @@ module Boty
|
|
287
299
|
end
|
288
300
|
|
289
301
|
it "logs when fails on discover the destiny", :logger do
|
290
|
-
allow(Slack.users).to receive(:by_name)
|
291
|
-
with("omg_doesnt_exists").
|
292
|
-
and_return nil
|
302
|
+
allow(Slack.users).to receive(:by_name)
|
303
|
+
.with("omg_doesnt_exists").and_return nil
|
293
304
|
bot.im "lol", destiny: "omg_doesnt_exists"
|
294
305
|
|
295
306
|
expect(logger.logs.last).to eq "User not found, refusing to send im."
|
@@ -304,46 +315,52 @@ module Boty
|
|
304
315
|
end
|
305
316
|
|
306
317
|
describe "#desc" do
|
318
|
+
let(:know_how) {
|
319
|
+
bot.know_how.map { |action|
|
320
|
+
{ action.desc.command => action.desc.description }
|
321
|
+
}
|
322
|
+
}
|
323
|
+
|
307
324
|
it "describes the next command to be created" do
|
308
325
|
bot.desc "omg", "lol all the way down"
|
309
|
-
bot.respond(/omg/)
|
326
|
+
bot.respond(/omg/)
|
310
327
|
|
311
|
-
expect(
|
328
|
+
expect(know_how).to include(
|
312
329
|
"omg" => "lol all the way down"
|
313
|
-
|
330
|
+
)
|
314
331
|
end
|
315
332
|
|
316
333
|
it "describes the next match do be created" do
|
317
334
|
bot.desc "ula", "babula"
|
318
|
-
bot.match(/ula/)
|
335
|
+
bot.match(/ula/)
|
319
336
|
|
320
|
-
expect(
|
337
|
+
expect(know_how).to include(
|
321
338
|
"ula" => "babula"
|
322
|
-
|
339
|
+
)
|
323
340
|
end
|
324
341
|
|
325
342
|
it "stores the description for a regex when no command usage is given" do
|
326
343
|
bot.desc "just a description"
|
327
|
-
bot.match(/just desc/i)
|
328
|
-
expect(
|
344
|
+
bot.match(/just desc/i)
|
345
|
+
expect(know_how).to include(
|
329
346
|
"/just desc/i" => "just a description"
|
330
|
-
|
347
|
+
)
|
331
348
|
end
|
332
349
|
|
333
350
|
it "presents the commands without description as regexes" do
|
334
|
-
bot.match(/without desc/i)
|
351
|
+
bot.match(/without desc/i)
|
335
352
|
|
336
|
-
expect(
|
353
|
+
expect(know_how).to include(
|
337
354
|
"/without desc/i" => nil
|
338
|
-
|
355
|
+
)
|
339
356
|
end
|
340
357
|
|
341
358
|
it "knows when a regex is case insensitive" do
|
342
359
|
bot.match(/without desc insensitive/)
|
343
360
|
|
344
|
-
expect(
|
361
|
+
expect(know_how).to include(
|
345
362
|
"/without desc insensitive/" => nil
|
346
|
-
|
363
|
+
)
|
347
364
|
end
|
348
365
|
end
|
349
366
|
end
|