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
@@ -5,24 +5,32 @@ RSpec.describe "I18n on default scripts", :session do
5
5
 
6
6
  it "describes scripts in :en locale (default)" do
7
7
  session = Boty::Session.new
8
- _know_how = nil
9
- session.start do |bot|
10
- _know_how = know_how
8
+ know_how = nil
9
+ session.start do
10
+ know_how = self.know_how
11
11
  end
12
12
 
13
- expect(_know_how["knows"]).
14
- to eq "List all the commands known by this bot."
13
+ actions = know_how.reduce({}) { |hsh, action|
14
+ hsh[action.desc.command] = action.desc.description
15
+ hsh
16
+ }
17
+
18
+ expect(actions["knows"]).to eq "List all the commands known by this bot."
15
19
  end
16
20
 
17
21
  it "describes scripts in :pt-br local when forced" do
18
22
  Boty.locale = :"pt-br"
19
23
  session = Boty::Session.new
20
- _know_how = nil
21
- session.start do |bot|
22
- _know_how = know_how
24
+ know_how = nil
25
+ session.start do
26
+ know_how = self.know_how
23
27
  end
24
28
 
25
- expect(_know_how["knows"]).
26
- to eq "Lista os comandos conhecidos por esse bot."
29
+ actions = know_how.reduce({}) { |hsh, action|
30
+ hsh[action.desc.command] = action.desc.description
31
+ hsh
32
+ }
33
+
34
+ expect(actions["knows"]).to eq "Lista os comandos conhecidos por esse bot."
27
35
  end
28
36
  end
@@ -2,17 +2,18 @@ RSpec.describe "script/knows", :session do
2
2
  before do
3
3
  start_session
4
4
 
5
- extra_to_remove = bot.know_how.keys - ['knows', 'pug me']
6
- extra_to_remove.each do |command_desc|
7
- bot.no command_desc
8
- end
5
+ bot.know_how.each { |action|
6
+ next if action.desc.command == "knows" ||
7
+ action.desc.command == "pug me"
8
+ bot.no action.desc.command
9
+ }
9
10
  end
10
11
 
11
12
  it "formats the output indenting by the command name size" do
12
- expect(bot).to receive(:im).
13
- with %{```\n knows: List all the commands known by this bot.
13
+ expect(bot).to receive(:im)
14
+ .with %(```\n knows: List all the commands known by this bot.
14
15
  pug me: Send some nice pug in the channel.
15
- ```}
16
+ ```)
16
17
  faye.message "<@jeeba>: knows"
17
18
  end
18
19
  end
@@ -7,11 +7,11 @@ RSpec.describe "script/pug", :session do
7
7
 
8
8
  describe "pug me", :faraday do
9
9
  before do
10
- requests.get("/random") { |env|
10
+ requests.get("/random") do
11
11
  [200,
12
- {"Content-Type" => "application/json;charset=utf-8"},
13
- {pug: "some_pug"}.to_json]
14
- }
12
+ { "Content-Type" => "application/json;charset=utf-8" },
13
+ { pug: "some_pug" }.to_json]
14
+ end
15
15
  end
16
16
 
17
17
  it "displays a pug" do
@@ -23,12 +23,13 @@ RSpec.describe "script/pug", :session do
23
23
 
24
24
  describe "pug bomb x", :faraday do
25
25
  it "displays x pugs" do
26
- requests.get("/bomb") { |env|
26
+ requests.get("/bomb") do |env|
27
27
  expect(env.params).to eq "count" => "3"
28
28
  [200,
29
29
  { "Content-Type" => "application/json;charset=utf-8" },
30
- { pugs: ["1", "2", "3"] }.to_json]
31
- }
30
+ { pugs: %w(1 2 3) }.to_json]
31
+ end
32
+
32
33
  (1..3).each do |num|
33
34
  expect(bot).to receive(:say).with("<#{num}>")
34
35
  end
@@ -37,17 +38,33 @@ RSpec.describe "script/pug", :session do
37
38
  end
38
39
 
39
40
  it "defaults to 5 pugs when no count is given" do
40
- requests.get("/bomb") { |env|
41
+ requests.get("/bomb") do |env|
41
42
  expect(env.params).to eq "count" => "5"
42
43
  [200,
43
44
  { "Content-Type" => "application/json;charset=utf-8" },
44
- { pugs: ["1", "2", "3", "4", "5"] }.to_json]
45
- }
45
+ { pugs: %w(1 2 3 4 5) }.to_json]
46
+ end
47
+
46
48
  (1..5).each do |num|
47
49
  expect(bot).to receive(:say).with("<#{num}>")
48
50
  end
49
51
 
50
52
  faye.message "<@jeeba>: pug bomb"
51
53
  end
54
+
55
+ it "forbbidens more than 5 pugs" do
56
+ requests.get("/bomb") do |env|
57
+ expect(env.params).to eq "count" => "5"
58
+ [200,
59
+ { "Content-Type" => "application/json;charset=utf-8" },
60
+ { pugs: %w(1 2 3 4 5) }.to_json]
61
+ end
62
+ expect(bot).to receive(:say).with("wow! so many pugs! sendind 5 instead.")
63
+ (1..5).each do |num|
64
+ expect(bot).to receive(:say).with("<#{num}>")
65
+ end
66
+
67
+ faye.message "<@jeeba>: pug bomb 20"
68
+ end
52
69
  end
53
70
  end
@@ -1,43 +1,49 @@
1
1
  RSpec.describe "script/brain", :session do
2
- before do
3
- allow(::Boty::Slack.users).to receive(:info).with("U9876").and_return(
4
- ::Boty::Slack::User.new({
5
- "id" => "U9876",
6
- "name" => "valeriano"
7
- })
2
+ let(:julian) {
3
+ ::Boty::Slack::User.new(
4
+ "id" => "U7777",
5
+ "name" => "julian"
8
6
  )
7
+ }
9
8
 
10
- allow(::Boty::Slack.users).to receive(:info).with("U7777").and_return(
11
- ::Boty::Slack::User.new({
12
- "id" => "U7777",
13
- "name" => "julian"
14
- })
9
+ let(:valeriano) {
10
+ ::Boty::Slack::User.new(
11
+ "id" => "U9876",
12
+ "name" => "valeriano"
15
13
  )
14
+ }
15
+
16
+ before do
17
+ allow(::Boty::Slack.users).to receive(:info).with("U9876")
18
+ .and_return(valeriano)
19
+ allow(::Boty::Slack.users).to receive(:info).with("U7777")
20
+ .and_return julian
16
21
 
17
22
  start_session
18
23
  end
19
24
 
20
25
  it "stores something about the user issuing the command" do
21
- expect(bot).to receive(:im).
22
- with "No worries, your secrets aren't safe with me... oh wait..."
26
+ expect(bot).to receive(:im)
27
+ .with "No worries, your secrets aren't safe with me... oh wait..."
23
28
 
24
29
  faye.message "<@#{bot.name}>: remember I'm at the dentist until 12pm",
25
- user: "U9876"
30
+ user: "U9876"
26
31
 
27
- expect(bot.brain[:user]["valeriano"].first).to eq "I'm at the dentist until 12pm"
32
+ expect(bot.brain[:user]["valeriano"].first)
33
+ .to eq "I'm at the dentist until 12pm"
28
34
  end
29
35
 
30
36
  it "recovers information from the brain" do
31
37
  allow(bot).to receive(:im)
32
38
  faye.message "<@#{bot.name}>: remember I'm at the dentist until 12pm",
33
- user: "U9876"
39
+ user: "U9876"
34
40
 
35
- expect(bot).to receive(:im).
36
- with("julian, I'm searching my user database for valeriano:\n")
37
- expect(bot).to receive(:im).
38
- with("```\n - I'm at the dentist until 12pm\n```")
41
+ expect(bot).to receive(:im)
42
+ .with("julian, I'm searching my user database for valeriano:\n")
43
+ expect(bot).to receive(:im)
44
+ .with("```\n - I'm at the dentist until 12pm\n```")
39
45
 
40
46
  faye.message "<@#{bot.name}>: about user valeriano",
41
- user: "U7777"
47
+ user: "U7777"
42
48
  end
43
49
  end
@@ -1,14 +1,15 @@
1
- $:.unshift File.expand_path("..", __FILE__)
2
- $:.unshift File.expand_path("../../lib", __FILE__)
1
+ $LOAD_PATH.unshift File.expand_path("..", __FILE__)
2
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
3
3
 
4
4
  begin
5
5
  require "byebug"
6
6
  require "rubinius/debugger"
7
7
  rescue LoadError
8
8
  end
9
+
9
10
  require "boty"
10
11
 
11
- Dir['./spec/support/**/*.rb'].each { |f| require f }
12
+ Dir["./spec/support/**/*.rb"].each do |f| require f end
12
13
 
13
14
  RSpec.configure do |config|
14
15
  config.include EMSupport, em: true
@@ -5,9 +5,7 @@ module EMSupport
5
5
  allow(EM).to receive(:run).and_yield
6
6
  end
7
7
 
8
- around do |example|
9
- example.run
10
- end
8
+ around(&:run)
11
9
  end
12
10
  end
13
11
  end
@@ -1,7 +1,6 @@
1
1
  module FaradaySupport
2
2
  def self.included(base)
3
3
  base.instance_eval do
4
-
5
4
  let(:requests) { Faraday::Adapter::Test::Stubs.new }
6
5
 
7
6
  around do |example|
@@ -11,9 +11,14 @@ module FayeSupport
11
11
  end
12
12
 
13
13
  def message(message, extra_args = {})
14
- send_event(:message, OpenStruct.new(data: {
15
- "type" => "message",
16
- "text" => message }.merge(extra_args).to_json)
14
+ send_event(
15
+ :message,
16
+ OpenStruct.new(
17
+ data: {
18
+ "type" => "message",
19
+ "text" => message
20
+ }.merge(extra_args).to_json
21
+ )
17
22
  )
18
23
  end
19
24
  end
@@ -26,9 +31,7 @@ module FayeSupport
26
31
  allow(Faye::WebSocket::Client).to receive(:new).and_return faye
27
32
  end
28
33
 
29
- around do |example|
30
- example.run
31
- end
34
+ around(&:run)
32
35
  end
33
36
  end
34
37
  end
@@ -1,8 +1,8 @@
1
1
  RSpec::Matchers.define :create_directory do |dir_name|
2
2
  match do |block|
3
- return false if Dir.exists? dir_name # change this to use a proper message
3
+ return false if Dir.exist? dir_name # change this to use a proper message
4
4
  block.call
5
- Dir.exists? dir_name
5
+ Dir.exist? dir_name
6
6
  end
7
7
 
8
8
  supports_block_expectations
@@ -10,9 +10,9 @@ end
10
10
 
11
11
  RSpec::Matchers.define :create_file do |file_name|
12
12
  match do |block|
13
- return false if File.exists? file_name # change this to use a proper message
13
+ return false if File.exist? file_name # change this to use a proper message
14
14
  block.call
15
- File.exists? file_name
15
+ File.exist? file_name
16
16
  end
17
17
 
18
18
  supports_block_expectations
@@ -2,19 +2,16 @@ module LoggerSupport
2
2
  def self.included(base)
3
3
  base.instance_eval do
4
4
  let(:logger) { Boty::Logger.adapter }
5
+ before do change_to_memory_adapter end
6
+ around(&:run)
7
+ after do Boty::Logger.adapter = @adapter end
8
+ end
9
+ end
5
10
 
6
- before do
7
- @adapter = Boty::Logger.adapter
8
- Boty::Logger.adapter = Boty::Logger::Memory.new
9
- end
10
-
11
- around do |example|
12
- example.run
13
- end
11
+ private
14
12
 
15
- after do
16
- Boty::Logger.adapter = @adapter
17
- end
18
- end
13
+ def change_to_memory_adapter
14
+ @adapter = Boty::Logger.adapter
15
+ Boty::Logger.adapter = Boty::Logger::Memory.new
19
16
  end
20
17
  end
@@ -1,31 +1,42 @@
1
1
  module SessionSupport
2
2
  def self.included(base)
3
- def start_session(only_knows:nil)
4
- @session = Boty::Session.new
5
- @session.start do |_| end
6
- end
3
+ memoize = ->(rspec_suite) { create_local_memoized_values_on(rspec_suite) }
7
4
 
8
5
  base.instance_eval do
9
6
  include EMSupport
10
7
  include FayeSupport
11
8
  include SlackSupport::Users
12
9
 
10
+ memoize[base]
11
+
12
+ before do
13
+ allow(Boty::Slack.rtm).to receive(:start).and_return parsed_response
14
+ end
15
+ end
16
+ end
17
+
18
+ def self.create_local_memoized_values_on(base)
19
+ base.instance_eval do
13
20
  let(:dsl) { ::Boty::DSL.new @session.bot }
14
21
  let(:bot) { dsl.bot }
15
22
  let(:bot_name) { "jeeba" }
16
23
  let(:bot_id) { "U1234" }
17
24
  let(:rtm_ws_url) { "ws://example.org/slack/sse/url" }
18
-
19
- before do
20
- allow(Boty::Slack.rtm).to receive(:start).
21
- and_return JSON.parse '{
22
- "url": "'+ rtm_ws_url + '",
23
- "self": {
24
- "id": "'+ bot_id + '",
25
- "name": "'+ bot_name + '"
26
- }
27
- }'
28
- end
29
25
  end
30
26
  end
27
+
28
+ def start_session
29
+ @session = Boty::Session.new
30
+ @session.start do |_| end
31
+ end
32
+
33
+ def parsed_response
34
+ JSON.parse '{
35
+ "url": "' + rtm_ws_url + '",
36
+ "self": {
37
+ "id": "' + bot_id + '",
38
+ "name": "' + bot_name + '"
39
+ }
40
+ }'
41
+ end
31
42
  end
@@ -1,17 +1,20 @@
1
1
  module SlackSupport
2
2
  module Users
3
+ def new_user(id, name)
4
+ ::Boty::Slack::User.new(
5
+ "id" => id,
6
+ "name" => name
7
+ )
8
+ end
9
+
3
10
  def self.included(base)
4
11
  base.instance_eval do
5
12
  let(:user_name) { "julian" }
6
13
  let(:user_id) { "U023BECGF" }
7
14
 
8
15
  before do
9
- allow(::Boty::Slack.users).to receive(:info).and_return(
10
- ::Boty::Slack::User.new({
11
- "id" => user_id,
12
- "name" => user_name
13
- })
14
- )
16
+ allow(::Boty::Slack.users).to receive(:info)
17
+ .and_return(new_user(user_id, user_name))
15
18
  end
16
19
  end
17
20
  end
@@ -4,36 +4,38 @@ require "boty/cli"
4
4
  module TemplateProjectSupport
5
5
  include ThorSupport
6
6
 
7
- def self.included(base)
8
- def dry_run
9
- allow(cli).to receive(:run)
10
- end
7
+ def dry_run
8
+ allow(cli).to receive(:run)
9
+ end
11
10
 
12
- def create_bot(name = nil, company:, api_key:)
13
- allow(cli).to receive(:ask).and_return company, api_key
14
- cli.new name || bot_name
15
- end
11
+ def create_bot(name = nil, company:, api_key:)
12
+ allow(cli).to receive(:ask).and_return company, api_key
13
+ cli.new name || bot_name
14
+ end
16
15
 
16
+ def self.included(base)
17
17
  base.instance_eval do
18
- before(:all) do
19
- @original_dir = FileUtils.pwd
20
- FileUtils.mkdir_p "tpl_project_tmp" if !Dir.exists? "tpl_project_tmp"
21
- FileUtils.chdir "tpl_project_tmp"
22
- end
23
-
24
- before do
25
- FileUtils.rm_rf bot_name if Dir.exists? bot_name
26
- end
27
-
28
- after(:all) do
29
- FileUtils.chdir @original_dir
30
- FileUtils.rm_rf "tpl_project_tmp"
31
- end
18
+ before(:all) do go_to_tmp_project_dir end
19
+ before do FileUtils.rm_rf bot_name if Dir.exist? bot_name end
20
+ after(:all) do remove_tmp_project_dir end
32
21
 
33
22
  subject(:cli) { Boty::CLI.new }
34
23
  let(:bot_name) { "jeeba" }
35
24
  end
36
25
  end
26
+
27
+ private
28
+
29
+ def go_to_tmp_project_dir
30
+ @original_dir = FileUtils.pwd
31
+ FileUtils.mkdir_p "tpl_project_tmp" unless Dir.exist? "tpl_project_tmp"
32
+ FileUtils.chdir "tpl_project_tmp"
33
+ end
34
+
35
+ def remove_tmp_project_dir
36
+ FileUtils.chdir @original_dir
37
+ FileUtils.rm_rf "tpl_project_tmp"
38
+ end
37
39
  end
38
40
 
39
41
  RSpec::Matchers.define :run do |command|
@@ -41,4 +43,3 @@ RSpec::Matchers.define :run do |command|
41
43
  expect(bot).to receive(:run).with command
42
44
  end
43
45
  end
44
-