slack-ruby-bot 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c8b86a027a9c17bbb4d3e69212493162aacfffca
4
- data.tar.gz: 94ec098315fd7611325f567da9c5964d4847d47b
3
+ metadata.gz: f872fa7b4cc7c405bc25e0802e243826672c098f
4
+ data.tar.gz: ed6a6038cf90aea81894759e73b2991a484f0d09
5
5
  SHA512:
6
- metadata.gz: c97a004bbcfadbbd318158cc8ffe1d59637c7b0026139e771f655393cb362acd02adff508cff69a961781b5da25efa199756c326ca18f098fefc8f6ee85c4b6b
7
- data.tar.gz: 15014981779338072114308822e4018d9bfc21b067f58689489ec2fffaec88b7fbf46a05a40a09d963c302da70d9312f9f0d08c42fe25a080ecfab2e78a171cc
6
+ metadata.gz: 2823b93a71bd803ebdbd3d753785e457250275dc2a0bb9eee72a4b7e9986f9060fa42487676d7ca6ed32513173c5ee51cc33274f69fc6c1e43d5c7311fce1386
7
+ data.tar.gz: 6d08cab72ee6db777d275550654154d9186b35643107529ee25c59e449fb19b52f6a7dde58bcef583dba4c19fb201bfe140cfe832daff91f07321e6cec0483c2
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
1
  .env
2
2
  pkg
3
3
  Gemfile.lock
4
+ .bundle
@@ -1,6 +1,7 @@
1
1
  AllCops:
2
2
  Exclude:
3
3
  - vendor/**/*
4
+ - examples/**/vendor/**/*
4
5
  - bin/**/*
5
6
 
6
7
  inherit_from: .rubocop_todo.yml
@@ -1,3 +1,11 @@
1
+ ### 0.8.1 (6/10/2016)
2
+
3
+ * [#69](https://github.com/dblock/slack-ruby-bot/pull/69): Ability to add help info to bot and commands - [@accessd](https://github.com/accessd).
4
+ * [#75](https://github.com/dblock/slack-ruby-bot/issues/75): Guarantee order of command evaluation - [@dblock](https://github.com/dblock).
5
+ * [#76](https://github.com/dblock/slack-ruby-bot/issues/76): Infinity error when app disabled - [@slayershadow](https://github.com/SlayerShadow).
6
+ * [#81](https://github.com/dblock/slack-ruby-bot/pull/81): Removed dependency on Bundler - [@derekddecker](https://github.com/derekddecker).
7
+ * [#84](https://github.com/dblock/slack-ruby-bot/pull/84): Removed dependency on ActiveSupport - [@rmulligan](https://github.com/rmulligan).
8
+
1
9
  ### 0.8.0 (5/5/2016)
2
10
 
3
11
  * [#32](https://github.com/dblock/slack-ruby-bot/issues/32): Don't include `faye-websocket` by default, support `celluloid-io` - [@dblock](https://github.com/dblock).
data/README.md CHANGED
@@ -7,17 +7,19 @@ Slack-Ruby-Bot
7
7
 
8
8
  A generic Slack bot framework written in Ruby on top of [slack-ruby-client](https://github.com/dblock/slack-ruby-client). This library does all the heavy lifting, such as message parsing, so you can focus on implementing slack bot commands. It also attempts to introduce the bare minimum number of requirements or any sorts of limitations. It's a Slack bot boilerplate.
9
9
 
10
+ If you are not familiar with Slack bots or Slack API concepts, you might want to watch [this video](http://code.dblock.org/2016/03/11/your-first-slack-bot-service-video.html).
11
+
10
12
  ![](slack.png)
11
13
 
12
14
  ## Useful to Me?
13
15
 
14
16
  * If you are just trying to send messages to Slack, use [slack-ruby-client](https://github.com/dblock/slack-ruby-client), which this library is built on top of.
15
- * If you're trying to roll out a full service with Slack button integration, check out [slack-bot-server](https://github.com/dblock/slack-bot-server), which uses this library.
17
+ * If you're trying to roll out a full service with Slack button integration, check out [slack-ruby-bot-server](https://github.com/dblock/slack-ruby-bot-server), which uses this library.
16
18
  * Otherwise, this piece of the puzzle will help you create a single bot instance for one team.
17
19
 
18
20
  ## Stable Release
19
21
 
20
- You're reading the documentation for the **stable** release of slack-ruby-bot 0.8.0. See [CHANGELOG](CHANGELOG.md) for a history of changes and [UPGRADING](UPGRADING.md) for how to upgrade to more recent versions.
22
+ You're reading the documentation for the **stable** release of slack-ruby-bot, 0.8.1. See [CHANGELOG](CHANGELOG.md) for a history of changes and [UPGRADING](UPGRADING.md) for how to upgrade to more recent versions.
21
23
 
22
24
  ## Usage
23
25
 
@@ -140,6 +142,47 @@ end
140
142
 
141
143
  See [examples/market](examples/market/marketbot.rb) for a working example.
142
144
 
145
+ ### Providing description for your bot and commands
146
+
147
+ You can specify help information for bot or commands with `help` block, for example:
148
+
149
+ in case of bot:
150
+
151
+ ```ruby
152
+ class WeatherBot < SlackRubyBot::Bot
153
+ help do
154
+ title 'Weather Bot'
155
+ desc 'This bot tells you the weather.'
156
+
157
+ command 'clouds' do
158
+ desc 'Tells you how many clouds there\'re above you.'
159
+ end
160
+
161
+ command 'What\'s the weather in <city>?' do
162
+ desc 'Tells you the weather in a <city>.'
163
+ long_desc "Accurate 10 Day Weather Forecasts for thousands of places around the World.\n" \
164
+ 'Bot provides detailed Weather Forecasts over a 10 day period updated four times a day.'
165
+ end
166
+ end
167
+
168
+ # commands implementation
169
+ end
170
+ ```
171
+
172
+ ![](screenshots/help.png)
173
+
174
+ in case of your own command:
175
+
176
+ ```ruby
177
+ class Deploy < SlackRubyBot::Commands::Base
178
+ help do
179
+ title 'deploy'
180
+ desc 'deploys your app'
181
+ long_desc 'command format: *deploy <branch> to <env>* where <env> is production or staging'
182
+ end
183
+ end
184
+ ```
185
+
143
186
  ### SlackRubyBot::Commands::Base
144
187
 
145
188
  The `SlackRubyBot::Bot` class is DSL sugar deriving from `SlackRubyBot::Commands::Base`. For more involved bots you can organize the bot implementation into subclasses of `SlackRubyBot::Commands::Base` manually. By default a command class responds, case-insensitively, to its name. A class called `Phone` that inherits from `SlackRubyBot::Commands::Base` responds to `phone` and `Phone` and calls the `call` method when implemented.
@@ -221,8 +264,6 @@ For example, the following hook handles [user_change](https://api.slack.com/even
221
264
  module MyBot
222
265
  module Hooks
223
266
  class UserChange
224
- extend SlackRubyBot::Hooks::Base
225
-
226
267
  def call(client, data)
227
268
  # data['user']['id'] contains the user ID
228
269
  # data['user']['name'] contains the new user name
@@ -3,6 +3,21 @@ require 'slack-ruby-bot'
3
3
  SlackRubyBot::Client.logger.level = Logger::WARN
4
4
 
5
5
  class WeatherBot < SlackRubyBot::Bot
6
+ help do
7
+ title 'Weather Bot'
8
+ desc 'This bot tells you the weather.'
9
+
10
+ command 'clouds' do
11
+ desc 'Tells you how many clouds there\'re above you.'
12
+ end
13
+
14
+ command 'What\'s the weather in <city>?' do
15
+ desc 'Tells you the weather in a <city>.'
16
+ long_desc "Accurate 10 Day Weather Forecasts for thousands of places around the World.\n" \
17
+ 'We provide detailed Weather Forecasts over a 10 day period updated four times a day.'
18
+ end
19
+ end
20
+
6
21
  match(/^How is the weather in (?<location>\w*)\?$/i) do |client, data, match|
7
22
  client.say(channel: data.channel, text: "The weather in #{match[:location]} is nice.")
8
23
  end
@@ -3,8 +3,6 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
3
 
4
4
  require 'boot'
5
5
 
6
- Bundler.require :default, ENV['RACK_ENV']
7
-
8
6
  Dir[File.expand_path('../../initializers', __FILE__) + '/**/*.rb'].each do |file|
9
7
  require file
10
8
  end
@@ -1,5 +1,4 @@
1
1
  require 'rubygems'
2
- require 'bundler/setup'
3
2
  require 'logger'
4
3
  require 'active_support'
5
4
  require 'active_support/core_ext'
@@ -19,6 +19,7 @@ module SlackRubyBot
19
19
  end
20
20
 
21
21
  require 'slack-ruby-client'
22
+ require 'slack-ruby-bot/support/commands_helper'
22
23
  require 'slack-ruby-bot/commands'
23
24
  require 'slack-ruby-bot/client'
24
25
  require 'slack-ruby-bot/server'
@@ -24,6 +24,10 @@ module SlackRubyBot
24
24
  client.say(options.merge(channel: channel, text: '', gif: keywords))
25
25
  end
26
26
 
27
+ def help(&block)
28
+ CommandsHelper.instance.capture_help(name, &block)
29
+ end
30
+
27
31
  def default_command_name
28
32
  name && name.split(':').last.downcase
29
33
  end
@@ -69,12 +73,12 @@ module SlackRubyBot
69
73
  end
70
74
 
71
75
  def match(match, &block)
72
- self.routes ||= {}
76
+ self.routes ||= ActiveSupport::OrderedHash.new
73
77
  self.routes[match] = { match_method: :match, call: block }
74
78
  end
75
79
 
76
80
  def scan(match, &block)
77
- self.routes ||= {}
81
+ self.routes ||= ActiveSupport::OrderedHash.new
78
82
  self.routes[match] = { match_method: :scan, call: block }
79
83
  end
80
84
 
@@ -1,8 +1,40 @@
1
1
  module SlackRubyBot
2
2
  module Commands
3
- class Help < Base
4
- def self.call(client, data, _match)
5
- client.say(channel: data.channel, text: 'See https://github.com/dblock/slack-ruby-bot, please.', gif: 'help')
3
+ class HelpCommand < Base
4
+ help do
5
+ title 'help'
6
+ desc 'Shows help information.'
7
+ end
8
+
9
+ command 'help' do |client, data, match|
10
+ command = match[:expression]
11
+
12
+ text = if command.present?
13
+ CommandsHelper.instance.command_full_desc(command)
14
+ else
15
+ general_text
16
+ end
17
+
18
+ client.say(channel: data.channel, text: text, gif: 'help')
19
+ end
20
+
21
+ class << self
22
+ private
23
+
24
+ def general_text
25
+ bot_desc = CommandsHelper.instance.bot_desc_and_commands
26
+ other_commands_descs = CommandsHelper.instance.other_commands_descs
27
+ <<TEXT
28
+ #{bot_desc.join("\n")}
29
+
30
+ *Other commands:*
31
+ #{other_commands_descs.join("\n")}
32
+
33
+ For getting description of the command use: *help <command>*
34
+
35
+ For more information see https://github.com/dblock/slack-ruby-bot, please.
36
+ TEXT
37
+ end
6
38
  end
7
39
  end
8
40
  end
@@ -0,0 +1,34 @@
1
+ module SlackRubyBot
2
+ module Commands
3
+ module Help
4
+ class Attrs
5
+ attr_accessor :command_name, :command_desc, :command_long_desc
6
+ attr_reader :class_name, :commands
7
+
8
+ def initialize(class_name)
9
+ @class_name = class_name
10
+ @commands = []
11
+ end
12
+
13
+ def title(title)
14
+ self.command_name = title
15
+ end
16
+
17
+ def desc(desc)
18
+ self.command_desc = desc
19
+ end
20
+
21
+ def long_desc(long_desc)
22
+ self.command_long_desc = long_desc
23
+ end
24
+
25
+ def command(title, &block)
26
+ @commands << self.class.new(class_name).tap do |k|
27
+ k.title(title)
28
+ k.instance_eval(&block)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,6 +1,11 @@
1
1
  module SlackRubyBot
2
2
  module Commands
3
3
  class Hi < Base
4
+ help do
5
+ title 'hi'
6
+ desc 'Says hello.'
7
+ end
8
+
4
9
  def self.call(client, data, _match)
5
10
  client.say(channel: data.channel, text: "Hi <@#{data.user}>!", gif: 'hi')
6
11
  end
@@ -0,0 +1,33 @@
1
+ module Testing
2
+ class WeatherBot < SlackRubyBot::Bot
3
+ help do
4
+ title 'Weather Bot'
5
+ desc 'This bot tells you the weather.'
6
+
7
+ command 'clouds' do
8
+ desc 'Tells you how many clouds there\'re above you.'
9
+ end
10
+
11
+ command '' do
12
+ desc 'empty description'
13
+ end
14
+
15
+ command 'command_without_description' do
16
+ end
17
+
18
+ command 'What\'s the weather in <city>?' do
19
+ desc 'Tells you the weather in a <city>.'
20
+ long_desc "Accurate 10 Day Weather Forecasts for thousands of places around the World.\n" \
21
+ 'We provide detailed Weather Forecasts over a 10 day period updated four times a day.'
22
+ end
23
+ end
24
+ end
25
+
26
+ class HelloCommand < SlackRubyBot::Commands::Base
27
+ help do
28
+ title 'hello'
29
+ desc 'Says hello.'
30
+ long_desc 'The long description'
31
+ end
32
+ end
33
+ end
@@ -51,10 +51,16 @@ module SlackRubyBot
51
51
  def restart!(wait = 1)
52
52
  @async ? start_async : start!
53
53
  rescue StandardError => e
54
- sleep wait
55
- logger.error "#{e.message}, reconnecting in #{wait} second(s)."
56
- logger.debug e
57
- restart! [wait * 2, 60].min
54
+ case e.message
55
+ when 'account_inactive', 'invalid_auth'
56
+ logger.error "#{token}: #{e.message}, team will be deactivated."
57
+ @stopping = true
58
+ else
59
+ sleep wait
60
+ logger.error "#{e.message}, reconnecting in #{wait} second(s)."
61
+ logger.debug e
62
+ restart! [wait * 2, 60].min
63
+ end
58
64
  end
59
65
 
60
66
  private
@@ -0,0 +1,76 @@
1
+ require 'singleton'
2
+ require_relative '../commands/help/attrs'
3
+
4
+ module SlackRubyBot
5
+ class CommandsHelper
6
+ include Singleton
7
+ attr_reader :commands_help_attrs
8
+
9
+ def initialize
10
+ @commands_help_attrs = []
11
+ end
12
+
13
+ def capture_help(class_name, &block)
14
+ k = Commands::Help::Attrs.new(class_name)
15
+ k.instance_eval(&block)
16
+ @commands_help_attrs << k
17
+ end
18
+
19
+ def bot_desc_and_commands
20
+ collect_help_attrs(bot_help_attrs) do |help_attrs|
21
+ bot_commands_descs = collect_name_and_desc(help_attrs.commands)
22
+ "#{command_name_and_desc(help_attrs)}\n\n*Commands:*\n#{bot_commands_descs.join("\n")}"
23
+ end
24
+ end
25
+
26
+ def other_commands_descs
27
+ collect_name_and_desc(other_commands_help_attrs)
28
+ end
29
+
30
+ def command_full_desc(name)
31
+ unescaped_name = Slack::Messages::Formatting.unescape(name)
32
+ help_attrs = find_command_help_attrs(unescaped_name)
33
+ return "There's no command *#{unescaped_name}*" unless help_attrs
34
+ return "There's no description for command *#{unescaped_name}*" if help_attrs.command_long_desc.blank?
35
+ "#{command_name_and_desc(help_attrs)}\n\n#{help_attrs.command_long_desc}"
36
+ end
37
+
38
+ private
39
+
40
+ def find_command_help_attrs(name)
41
+ help_attrs = commands_help_attrs.find { |k| k.command_name == name }
42
+ return help_attrs if help_attrs
43
+ commands_help_attrs.each { |k| k.commands.each { |c| return c if c.command_name == name } }
44
+ nil
45
+ end
46
+
47
+ def collect_help_attrs(help_attrs)
48
+ help_attrs_with_present_names(help_attrs).map do |ha|
49
+ yield(ha)
50
+ end
51
+ end
52
+
53
+ def collect_name_and_desc(help_attrs)
54
+ collect_help_attrs(help_attrs) do |ha|
55
+ command_name_and_desc(ha)
56
+ end
57
+ end
58
+
59
+ def command_name_and_desc(help_attrs)
60
+ desc = help_attrs.command_desc.present? ? " - #{help_attrs.command_desc}" : ''
61
+ "*#{help_attrs.command_name}*#{desc}"
62
+ end
63
+
64
+ def help_attrs_with_present_names(help_attrs)
65
+ help_attrs.select { |k| k.command_name.present? }
66
+ end
67
+
68
+ def bot_help_attrs
69
+ commands_help_attrs.select { |k| k.class_name.constantize.superclass == SlackRubyBot::Bot }
70
+ end
71
+
72
+ def other_commands_help_attrs
73
+ commands_help_attrs.select { |k| k.class_name.constantize.superclass == SlackRubyBot::Commands::Base }
74
+ end
75
+ end
76
+ end
@@ -1,20 +1,21 @@
1
1
  module SlackRubyBot
2
2
  module Loggable
3
- extend ActiveSupport::Concern
4
-
5
- class_methods do
6
- def logger
7
- @logger ||= begin
8
- $stdout.sync = true
9
- Logger.new(STDOUT)
10
- end
11
- end
3
+ def self.included(base)
4
+ base.send :include, LoggingMethods
5
+ base.extend(LoggingMethods)
12
6
  end
13
7
 
14
- private
8
+ def self.logger
9
+ @logger ||= begin
10
+ $stdout.sync = true
11
+ Logger.new(STDOUT)
12
+ end
13
+ end
14
+ end
15
15
 
16
+ module LoggingMethods
16
17
  def logger
17
- self.class.logger
18
+ Loggable.logger
18
19
  end
19
20
  end
20
21
  end
@@ -1,3 +1,3 @@
1
1
  module SlackRubyBot
2
- VERSION = '0.8.0'.freeze
2
+ VERSION = '0.8.1'.freeze
3
3
  end
Binary file
@@ -16,7 +16,6 @@ Gem::Specification.new do |s|
16
16
  s.summary = 'The easiest way to write a Slack bot in Ruby.'
17
17
  s.add_dependency 'hashie'
18
18
  s.add_dependency 'slack-ruby-client', '>= 0.6.0'
19
- s.add_dependency 'activesupport'
20
19
  s.add_dependency 'giphy', '~> 2.0.2'
21
20
  s.add_development_dependency 'rake'
22
21
  s.add_development_dependency 'rspec'
@@ -12,4 +12,11 @@ describe SlackRubyBot::App do
12
12
  expect(klass.instance.class).to be klass
13
13
  end
14
14
  end
15
+
16
+ describe 'executable' do
17
+ it 'can be required as a dependency' do
18
+ response = system("ruby -e \"Bundler = nil ; require 'slack-ruby-bot'\"")
19
+ expect(response).to be true
20
+ end
21
+ end
15
22
  end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe SlackRubyBot::Commands::Help::Attrs do
4
+ let(:help_attrs) { described_class.new('WeatherBot') }
5
+
6
+ it 'captures commands help attributes' do
7
+ expect(help_attrs.commands).to be_empty
8
+
9
+ sample_title = 'how\'s the weather?'
10
+ sample_desc = 'Tells you the weather in a <city>.'
11
+ sample_long_desc = "Accurate 10 Day Weather Forecasts for thousands of places around the World.\n" \
12
+ 'We provide detailed Weather Forecasts over a 10 day period updated four times a day.'
13
+
14
+ help_attrs.command(sample_title) do
15
+ desc sample_desc
16
+ long_desc sample_long_desc
17
+ end
18
+
19
+ expect(help_attrs.commands.count).to eq(1)
20
+ command = help_attrs.commands.first
21
+ expect(command.command_name).to eq(sample_title)
22
+ expect(command.command_desc).to eq(sample_desc)
23
+ expect(command.command_long_desc).to eq(sample_long_desc)
24
+ end
25
+ end
@@ -5,6 +5,24 @@ describe SlackRubyBot::Commands::Help do
5
5
  SlackRubyBot::App.new
6
6
  end
7
7
  it 'help' do
8
- expect(message: "#{SlackRubyBot.config.user} help").to respond_with_slack_message('See https://github.com/dblock/slack-ruby-bot, please.')
8
+ message = <<MSG
9
+ *Weather Bot* - This bot tells you the weather.
10
+
11
+ *Commands:*
12
+ *clouds* - Tells you how many clouds there're above you.
13
+ *command_without_description*
14
+ *What's the weather in <city>?* - Tells you the weather in a <city>.
15
+
16
+ *Other commands:*
17
+ *help* - Shows help information.
18
+ *hi* - Says hello.
19
+ *hello* - Says hello.
20
+
21
+ For getting description of the command use: *help <command>*
22
+
23
+ For more information see https://github.com/dblock/slack-ruby-bot, please.
24
+ MSG
25
+
26
+ expect(message: "#{SlackRubyBot.config.user} help").to respond_with_slack_message(message)
9
27
  end
10
28
  end
@@ -16,7 +16,7 @@ describe SlackRubyBot::Hooks::Message do
16
16
  it 'returns only built in command classes' do
17
17
  expect(built_in_command_classes).to include SlackRubyBot::Commands::Hi
18
18
  expect(built_in_command_classes).to include SlackRubyBot::Commands::Default
19
- expect(built_in_command_classes).to include SlackRubyBot::Commands::Help
19
+ expect(built_in_command_classes).to include SlackRubyBot::Commands::HelpCommand
20
20
  expect(built_in_command_classes).to_not include SlackRubyBot::Bot
21
21
  end
22
22
  it 'does not return unknown command class' do
@@ -88,4 +88,21 @@ describe SlackRubyBot::Server do
88
88
  end
89
89
  end
90
90
  end
91
+ context '#restart!' do
92
+ subject do
93
+ SlackRubyBot::Server.new(token: 'token')
94
+ end
95
+ it 'reloads server after disconnection' do
96
+ expect(subject).to receive(:restart!)
97
+ subject.send(:client).send(:callbacks)['close'].first.call
98
+ expect(subject.instance_variable_get(:@stopping)).to be_falsy
99
+ end
100
+ it 'does not reload server for inactive account' do
101
+ stopping = -> { subject.instance_variable_get :@stopping }
102
+ allow(subject).to receive(:start!) { raise StandardError, 'account_inactive' }
103
+ expect(stopping.call).to be_falsy
104
+ subject.restart!
105
+ expect(stopping.call).to be true
106
+ end
107
+ end
91
108
  end
@@ -0,0 +1,121 @@
1
+ require 'spec_helper'
2
+
3
+ describe SlackRubyBot::CommandsHelper do
4
+ let(:bot_class_name) { 'Testing::WeatherBot' }
5
+ let(:command_class_name) { 'Testing::HelloCommand' }
6
+ let(:commands_helper) { described_class.instance }
7
+
8
+ describe '#capture_help' do
9
+ let(:help_attrs) { commands_helper.commands_help_attrs }
10
+ let(:bot_help_attrs) { help_attrs.find { |k| k.class_name == bot_class_name } }
11
+ let(:command_help_attrs) { help_attrs.find { |k| k.class_name == command_class_name } }
12
+
13
+ it 'should save bot class name' do
14
+ expect(bot_help_attrs).to be
15
+ end
16
+
17
+ describe 'captures help attributes correctly' do
18
+ context 'for command' do
19
+ it 'command name' do
20
+ expect(command_help_attrs.command_name).to eq('hello')
21
+ end
22
+
23
+ it 'command description' do
24
+ expect(command_help_attrs.command_desc).to eq('Says hello.')
25
+ end
26
+
27
+ it 'command long description' do
28
+ expect(command_help_attrs.command_long_desc).to eq('The long description')
29
+ end
30
+ end
31
+
32
+ context 'for bot' do
33
+ it 'name' do
34
+ expect(bot_help_attrs.command_name).to eq('Weather Bot')
35
+ end
36
+
37
+ it 'description' do
38
+ expect(bot_help_attrs.command_desc).to eq('This bot tells you the weather.')
39
+ end
40
+
41
+ describe 'commands' do
42
+ let(:clouds_command) { bot_help_attrs.commands.find { |k| k.command_name == 'clouds' } }
43
+ let(:weather_command) { bot_help_attrs.commands.find { |k| k.command_name == "What's the weather in <city>?" } }
44
+
45
+ it 'command name' do
46
+ expect(clouds_command).to be
47
+ expect(weather_command).to be
48
+ end
49
+
50
+ it 'command description' do
51
+ expect(clouds_command.command_desc).to eq("Tells you how many clouds there're above you.")
52
+ expect(weather_command.command_desc).to eq('Tells you the weather in a <city>.')
53
+ end
54
+
55
+ it 'command long description' do
56
+ expect(weather_command.command_long_desc).to eq("Accurate 10 Day Weather Forecasts for thousands of places around the World.\n" \
57
+ 'We provide detailed Weather Forecasts over a 10 day period updated four times a day.')
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ describe '#bot_desc_and_commands' do
65
+ let(:bot_desc) { commands_helper.bot_desc_and_commands.first }
66
+
67
+ it 'returns bot name and description' do
68
+ expect(bot_desc).to include('*Weather Bot* - This bot tells you the weather.')
69
+ end
70
+
71
+ it 'returns possible commands for bot' do
72
+ expect(bot_desc).to include("\n\n*Commands:*\n")
73
+ expect(bot_desc).to include("*clouds* - Tells you how many clouds there're above you.\n")
74
+ expect(bot_desc).to include("*What's the weather in <city>?* - Tells you the weather in a <city>.")
75
+ end
76
+
77
+ it 'do not return command with empty name' do
78
+ expect(bot_desc).to_not include('**')
79
+ end
80
+
81
+ it 'do not show description for command without description' do
82
+ expect(bot_desc).to include("*command_without_description*\n")
83
+ end
84
+ end
85
+
86
+ describe '#other_commands_descs' do
87
+ let(:commands_desc) { commands_helper.other_commands_descs }
88
+ let(:hello_command_desc) { commands_desc.find { |desc| desc =~ /\*hello\*/ } }
89
+
90
+ it 'returns command name and description' do
91
+ expect(hello_command_desc).to eq('*hello* - Says hello.')
92
+ end
93
+ end
94
+
95
+ describe '#command_full_desc' do
96
+ context 'for bot commands' do
97
+ it 'returns long description' do
98
+ full_desc = commands_helper.command_full_desc("What's the weather in &lt;city&gt;?")
99
+ expect(full_desc).to include "Accurate 10 Day Weather Forecasts for thousands of places around the World.\n" \
100
+ 'We provide detailed Weather Forecasts over a 10 day period updated four times a day.'
101
+ end
102
+ end
103
+
104
+ context 'for other commands' do
105
+ it 'returns long description' do
106
+ full_desc = commands_helper.command_full_desc('hello')
107
+ expect(full_desc).to include 'The long description'
108
+ end
109
+ end
110
+
111
+ it 'returns correct message if there is no such command' do
112
+ full_desc = commands_helper.command_full_desc('deploy')
113
+ expect(full_desc).to eq "There's no command *deploy*"
114
+ end
115
+
116
+ it 'returns correct message if there is no long description for the command' do
117
+ full_desc = commands_helper.command_full_desc('clouds')
118
+ expect(full_desc).to eq "There's no description for command *clouds*"
119
+ end
120
+ end
121
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slack-ruby-bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Doubrovkine
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-05 00:00:00.000000000 Z
11
+ date: 2016-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hashie
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.6.0
41
- - !ruby/object:Gem::Dependency
42
- name: activesupport
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: giphy
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -193,6 +179,7 @@ files:
193
179
  - lib/slack-ruby-bot/commands/about.rb
194
180
  - lib/slack-ruby-bot/commands/base.rb
195
181
  - lib/slack-ruby-bot/commands/help.rb
182
+ - lib/slack-ruby-bot/commands/help/attrs.rb
196
183
  - lib/slack-ruby-bot/commands/hi.rb
197
184
  - lib/slack-ruby-bot/commands/unknown.rb
198
185
  - lib/slack-ruby-bot/config.rb
@@ -202,6 +189,7 @@ files:
202
189
  - lib/slack-ruby-bot/hooks/message.rb
203
190
  - lib/slack-ruby-bot/hooks/set.rb
204
191
  - lib/slack-ruby-bot/rspec.rb
192
+ - lib/slack-ruby-bot/rspec/support/bots_for_tests.rb
205
193
  - lib/slack-ruby-bot/rspec/support/fixtures/slack/migration_in_progress.yml
206
194
  - lib/slack-ruby-bot/rspec/support/slack-ruby-bot/it_behaves_like_a_slack_bot.rb
207
195
  - lib/slack-ruby-bot/rspec/support/slack-ruby-bot/respond_with_error.rb
@@ -210,12 +198,14 @@ files:
210
198
  - lib/slack-ruby-bot/rspec/support/slack_ruby_bot_configure.rb
211
199
  - lib/slack-ruby-bot/rspec/support/vcr.rb
212
200
  - lib/slack-ruby-bot/server.rb
201
+ - lib/slack-ruby-bot/support/commands_helper.rb
213
202
  - lib/slack-ruby-bot/support/loggable.rb
214
203
  - lib/slack-ruby-bot/version.rb
215
204
  - lib/slack_ruby_bot.rb
216
205
  - screenshots/aliases.gif
217
206
  - screenshots/demo.gif
218
207
  - screenshots/dms.gif
208
+ - screenshots/help.png
219
209
  - screenshots/market.gif
220
210
  - screenshots/register-bot.png
221
211
  - screenshots/weather.gif
@@ -234,6 +224,7 @@ files:
234
224
  - spec/slack-ruby-bot/commands/commands_with_expression_spec.rb
235
225
  - spec/slack-ruby-bot/commands/direct_messages_spec.rb
236
226
  - spec/slack-ruby-bot/commands/empty_text_spec.rb
227
+ - spec/slack-ruby-bot/commands/help/attrs_spec.rb
237
228
  - spec/slack-ruby-bot/commands/help_spec.rb
238
229
  - spec/slack-ruby-bot/commands/hi_spec.rb
239
230
  - spec/slack-ruby-bot/commands/match_spec.rb
@@ -253,6 +244,7 @@ files:
253
244
  - spec/slack-ruby-bot/hooks/set_spec.rb
254
245
  - spec/slack-ruby-bot/rspec/respond_with_error_spec.rb
255
246
  - spec/slack-ruby-bot/server_spec.rb
247
+ - spec/slack-ruby-bot/support/commands_helper_spec.rb
256
248
  - spec/slack-ruby-bot/support/loggable_spec.rb
257
249
  - spec/slack-ruby-bot/version_spec.rb
258
250
  - spec/spec_helper.rb
@@ -276,7 +268,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
276
268
  version: 1.3.6
277
269
  requirements: []
278
270
  rubyforge_project:
279
- rubygems_version: 2.5.1
271
+ rubygems_version: 2.4.8
280
272
  signing_key:
281
273
  specification_version: 4
282
274
  summary: The easiest way to write a Slack bot in Ruby.
@@ -294,6 +286,7 @@ test_files:
294
286
  - spec/slack-ruby-bot/commands/commands_with_expression_spec.rb
295
287
  - spec/slack-ruby-bot/commands/direct_messages_spec.rb
296
288
  - spec/slack-ruby-bot/commands/empty_text_spec.rb
289
+ - spec/slack-ruby-bot/commands/help/attrs_spec.rb
297
290
  - spec/slack-ruby-bot/commands/help_spec.rb
298
291
  - spec/slack-ruby-bot/commands/hi_spec.rb
299
292
  - spec/slack-ruby-bot/commands/match_spec.rb
@@ -313,6 +306,7 @@ test_files:
313
306
  - spec/slack-ruby-bot/hooks/set_spec.rb
314
307
  - spec/slack-ruby-bot/rspec/respond_with_error_spec.rb
315
308
  - spec/slack-ruby-bot/server_spec.rb
309
+ - spec/slack-ruby-bot/support/commands_helper_spec.rb
316
310
  - spec/slack-ruby-bot/support/loggable_spec.rb
317
311
  - spec/slack-ruby-bot/version_spec.rb
318
312
  - spec/spec_helper.rb