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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -0
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +18 -1
  5. data/README.md +39 -3
  6. data/Rakefile +1 -1
  7. data/boty.gemspec +9 -5
  8. data/lib/boty.rb +2 -1
  9. data/lib/boty/action.rb +26 -35
  10. data/lib/boty/action_description.rb +24 -0
  11. data/lib/boty/bot.rb +36 -25
  12. data/lib/boty/dsl.rb +3 -3
  13. data/lib/boty/eventable.rb +4 -3
  14. data/lib/boty/http.rb +3 -4
  15. data/lib/boty/locale.rb +12 -13
  16. data/lib/boty/logger.rb +14 -3
  17. data/lib/boty/rspec.rb +15 -16
  18. data/lib/boty/session.rb +7 -8
  19. data/lib/boty/slack.rb +11 -3
  20. data/lib/boty/slack/channel.rb +2 -1
  21. data/lib/boty/slack/chat.rb +5 -1
  22. data/lib/boty/slack/rtm.rb +1 -1
  23. data/lib/boty/slack/url.rb +10 -5
  24. data/lib/boty/slack/user.rb +2 -1
  25. data/lib/boty/slack/users.rb +1 -1
  26. data/lib/boty/version.rb +1 -1
  27. data/script/knows.rb +10 -9
  28. data/script/pug.rb +5 -1
  29. data/spec/boty/bot_spec.rb +89 -72
  30. data/spec/boty/cli_spec.rb +5 -5
  31. data/spec/boty/dsl_spec.rb +12 -13
  32. data/spec/boty/rspec_spec.rb +2 -1
  33. data/spec/boty/script_loader_spec.rb +8 -6
  34. data/spec/boty/session_spec.rb +2 -2
  35. data/spec/boty/slack/chat_spec.rb +18 -18
  36. data/spec/boty/slack/im_spec.rb +4 -4
  37. data/spec/boty/slack/message_spec.rb +11 -9
  38. data/spec/boty/slack/rtm_spec.rb +3 -3
  39. data/spec/boty/slack/url_spec.rb +5 -5
  40. data/spec/boty/slack/users_spec.rb +23 -23
  41. data/spec/happy_path_spec.rb +19 -18
  42. data/spec/script/i18n_spec.rb +18 -10
  43. data/spec/script/knows_spec.rb +8 -7
  44. data/spec/script/pug_spec.rb +27 -10
  45. data/spec/script/remember_spec.rb +27 -21
  46. data/spec/spec_helper.rb +4 -3
  47. data/spec/support/em_support.rb +1 -3
  48. data/spec/support/faraday_support.rb +0 -1
  49. data/spec/support/faye_support.rb +9 -6
  50. data/spec/support/file_system_matchers.rb +4 -4
  51. data/spec/support/logger_support.rb +9 -12
  52. data/spec/support/session_support.rb +26 -15
  53. data/spec/support/slack_support.rb +9 -6
  54. data/spec/support/template_project_support.rb +24 -23
  55. data/spec/support/thor_support.rb +3 -3
  56. data/template/project/%bot_name%.rb +4 -1
  57. data/template/project/spec/spec_helper.rb +4 -2
  58. metadata +21 -4
@@ -6,21 +6,21 @@ module Boty
6
6
  subject(:cli) { described_class.new }
7
7
 
8
8
  before(:all) do
9
- FileUtils.mkdir_p "tmp" if !Dir.exists? "tmp"
9
+ FileUtils.mkdir_p "tmp" unless Dir.exist? "tmp"
10
10
  FileUtils.chdir "tmp"
11
11
  end
12
12
 
13
13
  before do
14
- FileUtils.rm_rf "nice_bot" if Dir.exists? "nice_bot"
14
+ FileUtils.rm_rf "nice_bot" if Dir.exist? "nice_bot"
15
15
 
16
- allow(cli).to receive(:ask).
17
- and_return ENV["SLACK_COMPANY"], ENV["SLACK_BOT_API_TOKEN"]
16
+ allow(cli).to receive(:ask)
17
+ .and_return ENV["SLACK_COMPANY"], ENV["SLACK_BOT_API_TOKEN"]
18
18
 
19
19
  allow(cli).to receive(:run)
20
20
  end
21
21
 
22
22
  after(:all) do
23
- FileUtils.rm_rf "nice_bot" if Dir.exists? "nice_bot"
23
+ FileUtils.rm_rf "nice_bot" if Dir.exist? "nice_bot"
24
24
  FileUtils.chdir "../"
25
25
  end
26
26
 
@@ -1,6 +1,6 @@
1
1
  module Boty
2
2
  RSpec.describe DSL do
3
- let(:bot) { Bot.new({"id" => "U123", "name" => "jeeba"}) }
3
+ let(:bot) { Bot.new("id" => "U123", "name" => "jeeba") }
4
4
  subject(:dsl) { described_class.new bot }
5
5
 
6
6
  def message(text, extras = {})
@@ -13,12 +13,11 @@ module Boty
13
13
 
14
14
  before do
15
15
  # used by message class
16
- allow(Slack.users).to receive(:info).with("U5678").
17
- and_return(Slack::User.new("id" => "U5678", "name" => "julian"))
16
+ allow(Slack.users).to receive(:info).with("U5678")
17
+ .and_return Slack::User.new("id" => "U5678", "name" => "julian")
18
18
  end
19
19
 
20
- methods_from_bot = [ :name, :brain, :know_how, :im, :say,
21
- :desc, :respond, :match ]
20
+ methods_from_bot = %i(name brain know_how im say desc respond match)
22
21
  methods_from_bot.each do |bot_method|
23
22
  it "responds to :#{bot_method}" do
24
23
  expect(dsl.respond_to?(bot_method)).to eq true
@@ -36,8 +35,8 @@ module Boty
36
35
  say "Ohay <@#{user.id}>! I'm here, that's for sure."
37
36
  end
38
37
 
39
- expect(dsl).to receive(:say).
40
- with "Ohay <@U5678>! I'm here, that's for sure."
38
+ expect(dsl).to receive(:say)
39
+ .with "Ohay <@U5678>! I'm here, that's for sure."
41
40
 
42
41
  message "jeeba, are you there?"
43
42
  end
@@ -47,8 +46,8 @@ module Boty
47
46
  say "Ohay <@#{user.id}>! It matched."
48
47
  end
49
48
 
50
- expect(bot).to receive(:say).
51
- with "Ohay <@U5678>! It matched."
49
+ expect(bot).to receive(:say)
50
+ .with "Ohay <@U5678>! It matched."
52
51
 
53
52
  message "called with match?"
54
53
  end
@@ -80,16 +79,16 @@ module Boty
80
79
  executed = false
81
80
  dsl.match "omg" do executed = true end
82
81
 
83
- expect { message "bbq omg lol." }.
84
- to change { executed }.from(false).to true
82
+ expect { message "bbq omg lol." }
83
+ .to change { executed }.from(false).to true
85
84
  end
86
85
 
87
86
  it "binds a string with #respond" do
88
87
  executed = false
89
88
  dsl.respond "omg" do executed = true end
90
89
 
91
- expect { message "<@jeeba>: bbq omg lol." }.
92
- to change { executed }.from(false).to true
90
+ expect { message "<@jeeba>: bbq omg lol." }
91
+ .to change { executed }.from(false).to true
93
92
  end
94
93
  end
95
94
 
@@ -28,7 +28,8 @@ module Boty
28
28
 
29
29
  context "helpers" do
30
30
  it "includes #message_event to fire `data['type'] = 'message' events" do
31
- expect(@_bot).to receive(:event).with "type" => "message", "text" => "omg"
31
+ expect(@_bot).to receive(:event)
32
+ .with "type" => "message", "text" => "omg"
32
33
  message "omg"
33
34
  end
34
35
  end
@@ -1,15 +1,17 @@
1
1
  module Boty
2
2
  RSpec.describe Boty::ScriptLoader, :fakefs, :users do
3
- let(:dsl) { Boty::DSL.new Bot.new({ "name" => "jabber", "id" => "123" }) }
4
- let(:data) {{
5
- "type" => "message",
6
- "text" => "hey <@jabber>, pug me"
7
- }}
3
+ let(:dsl) { Boty::DSL.new Bot.new("name" => "jabber", "id" => "123") }
4
+ let(:data) do
5
+ {
6
+ "type" => "message",
7
+ "text" => "hey <@jabber>, pug me"
8
+ }
9
+ end
8
10
 
9
11
  subject(:loader) { described_class.new Boty::DSL.new(bot) }
10
12
 
11
13
  before do
12
- FileUtils.mkdir "script" unless Dir.exists? "script"
14
+ FileUtils.mkdir "script" unless Dir.exist? "script"
13
15
  File.open "script/omg.rb", "w" do |f|
14
16
  f.write <<-RUBY
15
17
  respond(/pug me/i) do
@@ -33,8 +33,8 @@ module Boty
33
33
  end
34
34
 
35
35
  it "intializes the sse client with the session url" do
36
- expect(Faye::WebSocket::Client).to receive(:new).
37
- with("ws://example.org/slack/sse/url")
36
+ expect(Faye::WebSocket::Client).to receive(:new)
37
+ .with("ws://example.org/slack/sse/url")
38
38
 
39
39
  session.start
40
40
  end
@@ -8,26 +8,26 @@ module Boty
8
8
  }
9
9
 
10
10
  let(:post_message_url) {
11
- "https://slack.com/api/chat.postMessage?"+
12
- "token=#{ENV['SLACK_BOT_API_TOKEN']}&#{parameters}"
11
+ "https://slack.com/api/chat.postMessage?" \
12
+ "token=#{ENV['SLACK_BOT_API_TOKEN']}&#{parameters}"
13
13
  }
14
14
 
15
15
  describe "#post_message" do
16
16
  it "uses api end point to send message with default parameters" do
17
- expect(Slack::URL).to receive(:get).
18
- with(post_message_url + "&text=omglolbbq")
17
+ expect(Slack::URL).to receive(:get)
18
+ .with(post_message_url + "&text=omglolbbq")
19
19
  chat.post_message "omglolbbq"
20
20
  end
21
21
 
22
22
  it "uri encodes the message" do
23
- expect(Slack::URL).to receive(:get).
24
- with(post_message_url + "&text=omg%20lol%20bbq")
23
+ expect(Slack::URL).to receive(:get)
24
+ .with(post_message_url + "&text=omg%20lol%20bbq")
25
25
  chat.post_message "omg lol bbq"
26
26
  end
27
27
 
28
28
  it "accepts extra api parameters" do
29
- expect(Slack::URL).to receive(:get).
30
- with(post_message_url + "&text=omg&extra=param")
29
+ expect(Slack::URL).to receive(:get)
30
+ .with(post_message_url + "&text=omg&extra=param")
31
31
  chat.post_message "omg", extra: "param"
32
32
  end
33
33
 
@@ -35,8 +35,8 @@ module Boty
35
35
  let(:parameters) { "as_user=true&channel=lol" }
36
36
 
37
37
  it "sends to a specific channel when one is given" do
38
- expect(Slack::URL).to receive(:get).
39
- with(post_message_url + "&text=omg")
38
+ expect(Slack::URL).to receive(:get)
39
+ .with(post_message_url + "&text=omg")
40
40
  chat.post_message "omg", channel: "lol"
41
41
  end
42
42
  end
@@ -44,26 +44,26 @@ module Boty
44
44
 
45
45
  describe "#post_im" do
46
46
  let(:im_open_url) {
47
- "https://slack.com/api/im.open?"+
48
- "token=#{ENV['SLACK_BOT_API_TOKEN']}&user=U1234"
47
+ "https://slack.com/api/im.open?" \
48
+ "token=#{ENV['SLACK_BOT_API_TOKEN']}&user=U1234"
49
49
  }
50
50
 
51
51
  before do
52
- allow(Slack::URL).to receive(:get).with(im_open_url).
53
- and_return("channel" => { "id" => "C4321" })
52
+ allow(Slack::URL).to receive(:get).with(im_open_url)
53
+ .and_return("channel" => { "id" => "C4321" })
54
54
  allow(chat).to receive(:post_message)
55
55
  end
56
56
 
57
57
  it "calls `#im.open` to open the channel" do
58
- expect(chat.im).to receive(:open).with("U1234").
59
- and_return Channel.new(id: "C4321", info: {})
58
+ expect(chat.im).to receive(:open).with("U1234")
59
+ .and_return Channel.new(id: "C4321", info: {})
60
60
 
61
61
  chat.post_im "U1234", "message"
62
62
  end
63
63
 
64
64
  it "sends the message to the im channel returned by `#im.open`" do
65
- expect(chat).to receive(:post_message).
66
- with "message", channel: "C4321"
65
+ expect(chat).to receive(:post_message)
66
+ .with "message", channel: "C4321"
67
67
 
68
68
  chat.post_im "U1234", "message"
69
69
  end
@@ -8,8 +8,8 @@ module Boty
8
8
  let(:action) { :open }
9
9
 
10
10
  let(:im_url) {
11
- "https://slack.com/api/im.#{action}?"+
12
- "token=#{ENV['SLACK_BOT_API_TOKEN']}"
11
+ "https://slack.com/api/im.#{action}?" \
12
+ "token=#{ENV['SLACK_BOT_API_TOKEN']}"
13
13
  }
14
14
 
15
15
  describe "#open" do
@@ -20,8 +20,8 @@ module Boty
20
20
  end
21
21
 
22
22
  it "returns a channel object with the im channel information" do
23
- expect(Slack::URL).to receive(:get).with(im_url + "&user=U1234").
24
- and_return(
23
+ expect(Slack::URL).to receive(:get).with(im_url + "&user=U1234")
24
+ .and_return(
25
25
  "ok" => true,
26
26
  "channel" => { "id" => "D024BFF1M" }
27
27
  )
@@ -6,14 +6,16 @@ module Boty
6
6
  let(:user_id) { "U7777" }
7
7
  let(:user_name) { "julian" }
8
8
 
9
- let(:message_json) {{
10
- "type" => "message",
11
- "text" => "omg lol bbq",
12
- "user" => "U7777",
13
- "channel" => "333",
14
- "ts" => "1234",
15
- "team" => "3452"
16
- }}
9
+ let(:message_json) do
10
+ {
11
+ "type" => "message",
12
+ "text" => "omg lol bbq",
13
+ "user" => "U7777",
14
+ "channel" => "333",
15
+ "ts" => "1234",
16
+ "team" => "3452"
17
+ }
18
+ end
17
19
 
18
20
  it "uses Slack.users.info to create a User instance" do
19
21
  expect(message.user.id).to eq "U7777"
@@ -25,7 +27,7 @@ module Boty
25
27
  expect(message.from? "U7777").to eq true
26
28
  end
27
29
 
28
- it "returns true if the param `respond_to? :id` returning the message author" do
30
+ it "returns true when param `#respond_to? :id` is the message author" do
29
31
  expect(message.from? OpenStruct.new(id: "U7777")).to eq true
30
32
  end
31
33
  end
@@ -4,9 +4,9 @@ module Boty
4
4
  subject(:rtm) { described_class.new }
5
5
 
6
6
  let(:url_with_default_parameters) {
7
- "https://#{ENV["SLACK_COMPANY"]}.slack.com/api/rtm.start?"+
8
- "token=#{ENV["SLACK_BOT_API_TOKEN"]}&"+
9
- "simple_latest=true&no_unreads=true"
7
+ "https://#{ENV['SLACK_COMPANY']}.slack.com/api/rtm.start?" \
8
+ "token=#{ENV['SLACK_BOT_API_TOKEN']}&" \
9
+ "simple_latest=true&no_unreads=true"
10
10
  }
11
11
 
12
12
  describe "#start" do
@@ -31,8 +31,8 @@ module Boty
31
31
  end
32
32
 
33
33
  it "parses the json response" do
34
- expect(Net::HTTP).to receive(:get).with(URI("http://example.org")).
35
- and_return "{\"it\": \"works\"}"
34
+ expect(Net::HTTP).to receive(:get).with(URI("http://example.org"))
35
+ .and_return "{\"it\": \"works\"}"
36
36
  response = url.get "http://example.org"
37
37
  expect(response).to eq "it" => "works"
38
38
  end
@@ -48,11 +48,11 @@ module Boty
48
48
 
49
49
  it "appends the api token" do
50
50
  url = client.send :parameterize, {}
51
- expect(url).to include "token=#{ENV["SLACK_BOT_API_TOKEN"]}"
51
+ expect(url).to include "token=#{ENV['SLACK_BOT_API_TOKEN']}"
52
52
  end
53
53
 
54
54
  it "add extra parameters" do
55
- url = client.send :parameterize, {really: "omg"}
55
+ url = client.send :parameterize, really: "omg"
56
56
  expect(url).to include "really=omg"
57
57
  end
58
58
 
@@ -62,7 +62,7 @@ module Boty
62
62
  end
63
63
 
64
64
  it "applies URI.encode to parameter values" do
65
- url = client.send :parameterize, {really: "omg lol"}
65
+ url = client.send :parameterize, really: "omg lol"
66
66
  expect(url).to include "really=omg%20lol"
67
67
  end
68
68
  end
@@ -2,49 +2,49 @@ module Boty
2
2
  module Slack
3
3
  RSpec.describe Users do
4
4
  def url_for(action)
5
- "https://slack.com/api/users.#{action}?"+
5
+ "https://slack.com/api/users.#{action}?" \
6
6
  "token=#{ENV['SLACK_BOT_API_TOKEN']}"
7
7
  end
8
8
 
9
9
  subject(:users) { described_class.new }
10
10
 
11
11
  before do
12
- allow(Slack::URL).to receive(:get).with(url_for(:info) + "&user=U123456").
13
- and_return(
12
+ allow(Slack::URL).to receive(:get)
13
+ .with(url_for(:info) + "&user=U123456").and_return(
14
14
  "ok" => true,
15
15
  "user" => {
16
16
  "id" => "U123456",
17
17
  "name" => "julian"
18
18
  }
19
- )
19
+ )
20
20
 
21
- allow(Slack::URL).to receive(:get).with(url_for(:list)).
22
- and_return(
23
- {
24
- "ok" => true,
25
- "members" => [
26
- {
27
- "id" => "U023BECGF",
28
- "name" => "bobby"
29
- },
30
- {
31
- "id" => "U123456",
32
- "name" => "julian"
33
- }
34
- ]
35
- }
36
- )
21
+ allow(Slack::URL).to receive(:get).with(url_for(:list))
22
+ .and_return(
23
+ "ok" => true,
24
+ "members" => [
25
+ {
26
+ "id" => "U023BECGF",
27
+ "name" => "bobby"
28
+ },
29
+ {
30
+ "id" => "U123456",
31
+ "name" => "julian"
32
+ }
33
+ ]
34
+ )
37
35
  end
38
36
 
39
37
  describe "#info" do
40
38
  it "calls Slack::URL get with token and user" do
41
- expect(Slack::URL).to receive(:get).with(url_for(:info) + "&user=U123456")
39
+ expect(Slack::URL).to receive(:get)
40
+ .with(url_for(:info) + "&user=U123456")
42
41
 
43
42
  users.info "U123456"
44
43
  end
45
44
 
46
45
  it "returns a channel object with the im channel information" do
47
- expect(Slack::URL).to receive(:get).with(url_for(:info) + "&user=U123456")
46
+ expect(Slack::URL).to receive(:get)
47
+ .with(url_for(:info) + "&user=U123456")
48
48
 
49
49
  user = users.info("U123456")
50
50
 
@@ -56,7 +56,7 @@ module Boty
56
56
  describe "#list" do
57
57
  it "retrieves the users list" do
58
58
  list = Slack.users.list
59
- expect(list.map(&:name)).to eq ["bobby", "julian"]
59
+ expect(list.map(&:name)).to eq %w(bobby julian)
60
60
  end
61
61
  end
62
62
 
@@ -5,13 +5,13 @@ module Boty
5
5
  def start_session(only_knows: nil)
6
6
  executable_bot = File.read "bot"
7
7
  @session = instance_eval executable_bot, "bot", 1
8
+ return unless only_knows
8
9
 
9
- if only_knows
10
- extra_to_remove = bot.know_how.keys - only_knows
11
- extra_to_remove.each do |command_desc|
12
- bot.no command_desc
10
+ bot.know_how.each { |action|
11
+ unless only_knows.include? action.desc.command
12
+ bot.no action.desc.command
13
13
  end
14
- end
14
+ }
15
15
  end
16
16
 
17
17
  def message(message)
@@ -37,13 +37,14 @@ module Boty
37
37
  allow(cli).to receive(:ask).and_return "omg", "lol"
38
38
  cli.new bot_name
39
39
  end
40
- expect(Dir.exists? bot_name).to eq true
40
+
41
+ expect(Dir.exist? bot_name).to eq true
41
42
 
42
43
  Dir.chdir bot_name
43
44
 
44
- expect(File.read ".env.local").to eq %{SLACK_COMPANY=omg
45
+ expect(File.read ".env.local").to eq %(SLACK_COMPANY=omg
45
46
  SLACK_BOT_API_TOKEN=lol
46
- }
47
+ )
47
48
  end
48
49
  end
49
50
 
@@ -61,37 +62,37 @@ SLACK_BOT_API_TOKEN=lol
61
62
  expect(Faye::WebSocket::Client).to receive(:new).with(rtm_ws_url)
62
63
  start_session
63
64
 
64
- expect(bot).to receive(:say).
65
- with "Ohay <@#{current_user}>! I'm here, that's for sure."
65
+ expect(bot).to receive(:say)
66
+ .with "Ohay <@#{current_user}>! I'm here, that's for sure."
66
67
  message "hey boty!"
67
68
  end
68
69
 
69
70
  describe "knows" do
70
71
  before do
71
- start_session only_knows: ['knows']
72
+ start_session only_knows: ["knows"]
72
73
  end
73
74
 
74
75
  it "responds in particular with the known commands and handlers" do
75
76
  # check that a im arrived to the current user with knows result
76
77
  message = "```\nknows: List all the commands known by this bot.\n```"
77
- expect{ message "<@boty>: knows" }.
78
- to send_im(current_user_id, message)
78
+ expect { message "<@boty>: knows" }
79
+ .to send_im(current_user_id, message)
79
80
  end
80
81
  end
81
82
 
82
83
  it "overrides default locale with the project specific one" do
83
84
  File.open("locale/xpto.yml", "w") do |file|
84
- file.write(%{xpto:
85
+ file.write(%(xpto:
85
86
  scripts:
86
- knows: "Wow! Such commands!"})
87
+ knows: "Wow! Such commands!"))
87
88
  end
88
- start_session only_knows: ['knows']
89
+ start_session only_knows: ["knows"]
89
90
  ::Boty.locale = :xpto
90
91
 
91
92
  message = "```\nknows: List all the commands known by this bot.\n```"
92
93
 
93
- expect{ message "<@boty>: knows" }.
94
- to send_im(current_user_id, message)
94
+ expect { message "<@boty>: knows" }
95
+ .to send_im(current_user_id, message)
95
96
  end
96
97
  end
97
98
  end