boty 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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
-