slack-ruby-bot 0.2.0 → 0.3.0
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_todo.yml +13 -4
- data/CHANGELOG.md +6 -0
- data/README.md +57 -3
- data/RELEASING.md +67 -0
- data/TUTORIAL.md +49 -2
- data/examples/minimal/pongbot.rb +1 -1
- data/examples/weather/Gemfile +3 -0
- data/examples/weather/weatherbot.rb +14 -0
- data/lib/slack-ruby-bot.rb +3 -2
- data/lib/slack-ruby-bot/app.rb +1 -1
- data/lib/slack-ruby-bot/commands/about.rb +2 -2
- data/lib/slack-ruby-bot/commands/base.rb +50 -19
- data/lib/slack-ruby-bot/commands/help.rb +1 -1
- data/lib/slack-ruby-bot/commands/hi.rb +1 -1
- data/lib/slack-ruby-bot/commands/unknown.rb +3 -1
- data/lib/slack-ruby-bot/hooks/message.rb +6 -80
- data/lib/slack-ruby-bot/rspec/support/slack-ruby-bot/respond_with_error.rb +2 -3
- data/lib/slack-ruby-bot/rspec/support/slack-ruby-bot/respond_with_slack_message.rb +1 -1
- data/lib/slack-ruby-bot/version.rb +1 -1
- data/screenshots/weather.gif +0 -0
- data/slack-ruby-bot.gemspec +1 -1
- data/spec/slack-ruby-bot/commands/commands_precedence_spec.rb +22 -0
- data/spec/slack-ruby-bot/commands/commands_spaces_spec.rb +20 -0
- data/spec/slack-ruby-bot/commands/commands_spec.rb +4 -4
- data/spec/slack-ruby-bot/commands/commands_with_block_spec.rb +23 -0
- data/spec/slack-ruby-bot/commands/empty_text_spec.rb +4 -4
- data/spec/slack-ruby-bot/commands/not_implemented_spec.rb +15 -0
- data/spec/slack-ruby-bot/commands/operators_spec.rb +3 -3
- data/spec/slack-ruby-bot/commands/operators_with_block_spec.rb +23 -0
- data/spec/slack-ruby-bot/rspec/respond_with_error_spec.rb +3 -3
- metadata +45 -31
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: e767ee739a4eb2e86b7b03affd315f7d20fdc866
         | 
| 4 | 
            +
              data.tar.gz: 5123671ea14bf10c590955d6a2391b436d3578bf
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: d13566b081e81835c685886917ba096bc0ec3c525287feab3ca50c6691f48139710ed4d0fb65c7e7369aee9a8608d83099f5e14b28c8a7d3fe5f85380beac3f4
         | 
| 7 | 
            +
              data.tar.gz: 4b6ed30645c1a9cc2ffaecd1924db4fd71bf6d4c845bc716e6107e76876066964f1f711ed0fc380d546ae192ab4ca1ca080fb89b15d95a59b02274a65d4b2d9b
         | 
    
        data/.rubocop_todo.yml
    CHANGED
    
    | @@ -1,5 +1,5 @@ | |
| 1 1 | 
             
            # This configuration was generated by `rubocop --auto-gen-config`
         | 
| 2 | 
            -
            # on 2015-07- | 
| 2 | 
            +
            # on 2015-07-19 12:16:52 -0400 using RuboCop version 0.32.1.
         | 
| 3 3 | 
             
            # The point is for the user to remove these configuration records
         | 
| 4 4 | 
             
            # one by one as the offenses are removed from the code base.
         | 
| 5 5 | 
             
            # Note that changes in the inspected code, or installation of new
         | 
| @@ -10,18 +10,22 @@ Lint/HandleExceptions: | |
| 10 10 | 
             
              Enabled: false
         | 
| 11 11 |  | 
| 12 12 | 
             
            # Offense count: 1
         | 
| 13 | 
            +
            Lint/UselessAccessModifier:
         | 
| 14 | 
            +
              Enabled: false
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            # Offense count: 2
         | 
| 13 17 | 
             
            Metrics/AbcSize:
         | 
| 14 18 | 
             
              Max: 21
         | 
| 15 19 |  | 
| 16 | 
            -
            # Offense count:  | 
| 20 | 
            +
            # Offense count: 37
         | 
| 17 21 | 
             
            # Configuration parameters: AllowURI, URISchemes.
         | 
| 18 22 | 
             
            Metrics/LineLength:
         | 
| 19 23 | 
             
              Max: 142
         | 
| 20 24 |  | 
| 21 | 
            -
            # Offense count:  | 
| 25 | 
            +
            # Offense count: 2
         | 
| 22 26 | 
             
            # Configuration parameters: CountComments.
         | 
| 23 27 | 
             
            Metrics/MethodLength:
         | 
| 24 | 
            -
              Max:  | 
| 28 | 
            +
              Max: 18
         | 
| 25 29 |  | 
| 26 30 | 
             
            # Offense count: 15
         | 
| 27 31 | 
             
            Style/Documentation:
         | 
| @@ -32,6 +36,11 @@ Style/Documentation: | |
| 32 36 | 
             
            Style/FileName:
         | 
| 33 37 | 
             
              Enabled: false
         | 
| 34 38 |  | 
| 39 | 
            +
            # Offense count: 1
         | 
| 40 | 
            +
            # Configuration parameters: EnforcedStyle, SupportedStyles.
         | 
| 41 | 
            +
            Style/MethodName:
         | 
| 42 | 
            +
              Enabled: false
         | 
| 43 | 
            +
             | 
| 35 44 | 
             
            # Offense count: 1
         | 
| 36 45 | 
             
            Style/ModuleFunction:
         | 
| 37 46 | 
             
              Enabled: false
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,9 @@ | |
| 1 | 
            +
            ### 0.3.0 (7/19/2015)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            * [#5](https://github.com/dblock/slack-ruby-bot/issues/5): Added support for free-formed routes via `match` - [@dblock](https://github.com/dblock).
         | 
| 4 | 
            +
            * [#6](https://github.com/dblock/slack-ruby-bot/issues/6): Commands and operators take blocks - [@dblock](https://github.com/dblock).
         | 
| 5 | 
            +
            * [#4](https://github.com/dblock/slack-ruby-bot/issues/4): Messages are posted with `as_user: true` by default - [@dblock](https://github.com/dblock).
         | 
| 6 | 
            +
             | 
| 1 7 | 
             
            ### 0.2.0 (7/10/2015)
         | 
| 2 8 |  | 
| 3 9 | 
             
            * Sending `send_message` with nil or empty text will yield `Nothing to see here.` with a GIF instead of `no_text` - [@dblock](https://github.com/dblock).
         | 
    
        data/README.md
    CHANGED
    
    | @@ -28,7 +28,7 @@ module PongBot | |
| 28 28 | 
             
              end
         | 
| 29 29 |  | 
| 30 30 | 
             
              class Ping < SlackRubyBot::Commands::Base
         | 
| 31 | 
            -
                 | 
| 31 | 
            +
                command 'ping' do |data, _match|
         | 
| 32 32 | 
             
                  send_message data.channel, 'pong'
         | 
| 33 33 | 
             
                end
         | 
| 34 34 | 
             
              end
         | 
| @@ -54,23 +54,69 @@ The following examples of production-grade bots based on slack-ruby-bot are list | |
| 54 54 |  | 
| 55 55 | 
             
            ### Commands and Operators
         | 
| 56 56 |  | 
| 57 | 
            -
            Bots are addressed by name and respond to commands and operators. 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 | 
| 57 | 
            +
            Bots are addressed by name and respond to commands and operators. 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.
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            ```ruby
         | 
| 60 | 
            +
            class Phone < SlackRubyBot::Commands::Base
         | 
| 61 | 
            +
              command 'call'
         | 
| 62 | 
            +
             | 
| 63 | 
            +
              def self.call(data, _match)
         | 
| 64 | 
            +
                send_message data.channel, 'called'
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
            end
         | 
| 67 | 
            +
            ```
         | 
| 68 | 
            +
             | 
| 69 | 
            +
            To respond to custom commands and to disable automatic class name matching, use the `command` keyword. The following command responds to `call` and `呼び出し` (call in Japanese).
         | 
| 58 70 |  | 
| 59 71 | 
             
            ```ruby
         | 
| 60 72 | 
             
            class Phone < SlackRubyBot::Commands::Base
         | 
| 61 73 | 
             
              command 'call'
         | 
| 62 74 | 
             
              command '呼び出し'
         | 
| 75 | 
            +
             | 
| 76 | 
            +
              def self.call(data, _match)
         | 
| 77 | 
            +
                send_message data.channel, 'called'
         | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
            end
         | 
| 80 | 
            +
            ```
         | 
| 81 | 
            +
             | 
| 82 | 
            +
            You can combine multiple commands and use a block to implement them.
         | 
| 83 | 
            +
             | 
| 84 | 
            +
            ```ruby
         | 
| 85 | 
            +
            class Phone < SlackRubyBot::Commands::Base
         | 
| 86 | 
            +
              command 'call', '呼び出し' do |data, _match|
         | 
| 87 | 
            +
                send_message data.channel, 'called'
         | 
| 88 | 
            +
              end
         | 
| 63 89 | 
             
            end
         | 
| 64 90 | 
             
            ```
         | 
| 65 91 |  | 
| 92 | 
            +
            Command match data includes `match['bot']`, `match['command']` and `match['expression']`. The `bot` match always checks against the `SlackRubyBot::Config.user` setting.
         | 
| 93 | 
            +
             | 
| 66 94 | 
             
            Operators are 1-letter long and are similar to commands. They don't require addressing a bot nor separating an operator from its arguments. The following class responds to `=2+2`.
         | 
| 67 95 |  | 
| 68 96 | 
             
            ```ruby
         | 
| 69 97 | 
             
            class Calculator < SlackRubyBot::Commands::Base
         | 
| 70 | 
            -
              operator '='
         | 
| 98 | 
            +
              operator '=' do |_data, _match|
         | 
| 99 | 
            +
                # implementation detail
         | 
| 100 | 
            +
              end
         | 
| 101 | 
            +
            end
         | 
| 102 | 
            +
            ```
         | 
| 103 | 
            +
             | 
| 104 | 
            +
            Operator match data includes `match['operator']` and `match['expression']`. The `bot` match always checks against the `SlackRubyBot::Config.user` setting.
         | 
| 105 | 
            +
             | 
| 106 | 
            +
            ### Generic Routing
         | 
| 107 | 
            +
             | 
| 108 | 
            +
            Commands and operators are generic versions of bot routes. You can respond to just about anything by defining a custom route.
         | 
| 109 | 
            +
             | 
| 110 | 
            +
            ```ruby
         | 
| 111 | 
            +
            class Weather < SlackRubyBot::Commands::Base
         | 
| 112 | 
            +
              match /^How is the weather in (<?location>\w*)\?$/ do |data, match|
         | 
| 113 | 
            +
                send_message data.channel, "The weather in #{match[:location]} is nice."
         | 
| 114 | 
            +
              end
         | 
| 71 115 | 
             
            end
         | 
| 72 116 | 
             
            ```
         | 
| 73 117 |  | 
| 118 | 
            +
            
         | 
| 119 | 
            +
             | 
| 74 120 | 
             
            ### Built-In Commands
         | 
| 75 121 |  | 
| 76 122 | 
             
            Slack-ruby-bot comes with several built-in commands. You can re-define built-in commands, normally, as described above.
         | 
| @@ -87,6 +133,14 @@ Politely says 'hi' back. | |
| 87 133 |  | 
| 88 134 | 
             
            Get help.
         | 
| 89 135 |  | 
| 136 | 
            +
            ### RSpec Shared Behaviors
         | 
| 137 | 
            +
             | 
| 138 | 
            +
            Slack-ruby-bot ships with a number of shared RSpec behaviors that can be used in your RSpec tests. Require 'slack-ruby-bot/rspec' in your `spec_helper.rb`.
         | 
| 139 | 
            +
             | 
| 140 | 
            +
            * [behaves like a slack bot](lib/slack-ruby-bot/rspec/support/slack-ruby-bot/it_behaves_like_a_slack_bot.rb): A bot quacks like a Slack Ruby bot.
         | 
| 141 | 
            +
            * [respond with slack message](lib/slack-ruby-bot/rspec/support/slack-ruby-bot/respond_with_slack_message.rb): The bot responds with a message.
         | 
| 142 | 
            +
            * [respond with error](lib/slack-ruby-bot/rspec/support/slack-ruby-bot/respond_with_error.rb): An exception is raised inside a bot command.
         | 
| 143 | 
            +
             | 
| 90 144 | 
             
            ## Contributing
         | 
| 91 145 |  | 
| 92 146 | 
             
            See [CONTRIBUTING](CONTRIBUTING.md).
         | 
    
        data/RELEASING.md
    ADDED
    
    | @@ -0,0 +1,67 @@ | |
| 1 | 
            +
            # Releasing Slack-Ruby-Bot
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            There're no particular rules about when to release slack-ruby-bot. Release bug fixes frequenty, features not so frequently and breaking API changes rarely.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            ### Release
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            Run tests, check that all tests succeed locally.
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            ```
         | 
| 10 | 
            +
            bundle install
         | 
| 11 | 
            +
            rake
         | 
| 12 | 
            +
            ```
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            Check that the last build succeeded in [Travis CI](https://travis-ci.org/dblock/slack-ruby-bot) for all supported platforms.
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            Increment the version, modify [lib/slack-ruby-bot/version.rb](lib/slack-ruby-bot/version.rb).
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            *  Increment the third number if the release has bug fixes and/or very minor features, only (eg. change `0.2.1` to `0.2.2`).
         | 
| 19 | 
            +
            *  Increment the second number if the release contains major features or breaking API changes (eg. change `0.2.1` to `0.3.0`).
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            Change "Next Release" in [CHANGELOG.md](CHANGELOG.md) to the new version.
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            ```
         | 
| 24 | 
            +
            ### 0.2.2 (7/10/2015)
         | 
| 25 | 
            +
            ```
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            Remove the line with "Your contribution here.", since there will be no more contributions to this release.
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            Commit your changes.
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            ```
         | 
| 32 | 
            +
            git add CHANGELOG.md lib/slack-ruby-bot/version.rb
         | 
| 33 | 
            +
            git commit -m "Preparing for release, 0.2.2."
         | 
| 34 | 
            +
            git push origin master
         | 
| 35 | 
            +
            ```
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            Release.
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            ```
         | 
| 40 | 
            +
            $ rake release
         | 
| 41 | 
            +
             | 
| 42 | 
            +
            slack-ruby-bot 0.2.2 built to pkg/slack-ruby-bot-0.2.2.gem.
         | 
| 43 | 
            +
            Tagged v0.2.2.
         | 
| 44 | 
            +
            Pushed git commits and tags.
         | 
| 45 | 
            +
            Pushed slack-ruby-bot 0.2.2 to rubygems.org.
         | 
| 46 | 
            +
            ```
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            ### Prepare for the Next Version
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            Add the next release to [CHANGELOG.md](CHANGELOG.md).
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            ```
         | 
| 53 | 
            +
            Next Release
         | 
| 54 | 
            +
            ============
         | 
| 55 | 
            +
             | 
| 56 | 
            +
            * Your contribution here.
         | 
| 57 | 
            +
            ```
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            Increment the third version number in [lib/slack-ruby-bot/version.rb](lib/slack-ruby-bot/version.rb).
         | 
| 60 | 
            +
             | 
| 61 | 
            +
            Comit your changes.
         | 
| 62 | 
            +
             | 
| 63 | 
            +
            ```
         | 
| 64 | 
            +
            git add CHANGELOG.md lib/slack-ruby-bot/version.rb
         | 
| 65 | 
            +
            git commit -m "Preparing for next development iteration, 0.2.3."
         | 
| 66 | 
            +
            git push origin master
         | 
| 67 | 
            +
            ```
         | 
    
        data/TUTORIAL.md
    CHANGED
    
    | @@ -51,7 +51,7 @@ Create a folder called `slack-mathbot/commands` and inside of it create `calcula | |
| 51 51 | 
             
            module SlackMathbot
         | 
| 52 52 | 
             
              module Commands
         | 
| 53 53 | 
             
                class Calculate < SlackRubyBot::Commands::Base
         | 
| 54 | 
            -
                   | 
| 54 | 
            +
                  command 'calculate' do |data, _match|
         | 
| 55 55 | 
             
                    send_message data.channel, '4'
         | 
| 56 56 | 
             
                  end
         | 
| 57 57 | 
             
                end
         | 
| @@ -139,10 +139,57 @@ Run `foreman start`. Your bot should be running. | |
| 139 139 | 
             
            14:32:36 web.1  | I, [2015-07-10T14:32:36.766955 #98948]  INFO -- : Successfully connected to https://xyz.slack.com/.
         | 
| 140 140 | 
             
            ```
         | 
| 141 141 |  | 
| 142 | 
            -
            ###  | 
| 142 | 
            +
            ### Try
         | 
| 143 143 |  | 
| 144 144 | 
             
            Invite the bot to a channel via `/invite [bot name]` and send it a `calculate` command with `[bot name] calculate 2+2`. It will respond with `4` from the code above.
         | 
| 145 145 |  | 
| 146 | 
            +
            ### Write Tests
         | 
| 147 | 
            +
             | 
| 148 | 
            +
            #### Spec Helper
         | 
| 149 | 
            +
             | 
| 150 | 
            +
            Create `spec/spec_helper.rb` that includes the bot files and shared RSpec support from slack-ruby-bot.
         | 
| 151 | 
            +
             | 
| 152 | 
            +
            ```ruby
         | 
| 153 | 
            +
            $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..'))
         | 
| 154 | 
            +
             | 
| 155 | 
            +
            require 'slack-ruby-bot/rspec'
         | 
| 156 | 
            +
            require 'slack-mathbot'
         | 
| 157 | 
            +
            ```
         | 
| 158 | 
            +
             | 
| 159 | 
            +
            #### Test the Bot Application
         | 
| 160 | 
            +
             | 
| 161 | 
            +
            Create a test for the bot application itself in `spec/slack-mathbot/app_spec.rb`.
         | 
| 162 | 
            +
             | 
| 163 | 
            +
            ```ruby
         | 
| 164 | 
            +
            require 'spec_helper'
         | 
| 165 | 
            +
             | 
| 166 | 
            +
            describe SlackMathbot::App do
         | 
| 167 | 
            +
              def app
         | 
| 168 | 
            +
                SlackMathbot::App.new
         | 
| 169 | 
            +
              end
         | 
| 170 | 
            +
              it_behaves_like 'a slack ruby bot'
         | 
| 171 | 
            +
            end
         | 
| 172 | 
            +
            ```
         | 
| 173 | 
            +
             | 
| 174 | 
            +
            #### Test a Command
         | 
| 175 | 
            +
             | 
| 176 | 
            +
            Create a test for the `calculate` command in `spec/slack-mathbot/commands/calculate_spec.rb`. The bot is addressed by its user name.
         | 
| 177 | 
            +
             | 
| 178 | 
            +
            ```ruby
         | 
| 179 | 
            +
            require 'spec_helper'
         | 
| 180 | 
            +
             | 
| 181 | 
            +
            describe SlackMathbot::Commands::Calculate do
         | 
| 182 | 
            +
              def app
         | 
| 183 | 
            +
                SlackMathbot::App.new
         | 
| 184 | 
            +
              end
         | 
| 185 | 
            +
              it 'returns 4' do
         | 
| 186 | 
            +
                expect(message: "#{SlackRubyBot.config.user} calculate 2+2", channel: 'channel').to respond_with_slack_message('4')
         | 
| 187 | 
            +
              end
         | 
| 188 | 
            +
            end
         | 
| 189 | 
            +
            ```
         | 
| 190 | 
            +
             | 
| 191 | 
            +
            See [lib/slack-ruby-bot/rspec/support/slack-ruby-bot](lib/slack-ruby-bot/rspec/support/slack-ruby-bot) for other shared RSpec behaviors.
         | 
| 192 | 
            +
             | 
| 146 193 | 
             
            ### Deploy
         | 
| 147 194 |  | 
| 148 195 | 
             
            See [DEPLOYMENT](DEPLOYMENT.md) for how to deploy your bot to production.
         | 
    
        data/examples/minimal/pongbot.rb
    CHANGED
    
    
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            require 'slack-ruby-bot'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module WeatherBot
         | 
| 4 | 
            +
              class App < SlackRubyBot::App
         | 
| 5 | 
            +
              end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              class Weather < SlackRubyBot::Commands::Base
         | 
| 8 | 
            +
                match(/^How is the weather in (?<location>\w*)\?$/i) do |data, match|
         | 
| 9 | 
            +
                  send_message data.channel, "The weather in #{match[:location]} is nice."
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
            end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            WeatherBot::App.instance.run
         | 
    
        data/lib/slack-ruby-bot.rb
    CHANGED
    
    | @@ -4,8 +4,6 @@ require 'slack-ruby-bot/version' | |
| 4 4 | 
             
            require 'slack-ruby-bot/about'
         | 
| 5 5 | 
             
            require 'slack-ruby-bot/config'
         | 
| 6 6 | 
             
            require 'slack-ruby-bot/hooks'
         | 
| 7 | 
            -
            require 'slack-ruby-bot/commands'
         | 
| 8 | 
            -
            require 'slack-ruby-bot/app'
         | 
| 9 7 |  | 
| 10 8 | 
             
            module SlackRubyBot
         | 
| 11 9 | 
             
              class << self
         | 
| @@ -18,3 +16,6 @@ module SlackRubyBot | |
| 18 16 | 
             
                end
         | 
| 19 17 | 
             
              end
         | 
| 20 18 | 
             
            end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            require 'slack-ruby-bot/commands'
         | 
| 21 | 
            +
            require 'slack-ruby-bot/app'
         | 
    
        data/lib/slack-ruby-bot/app.rb
    CHANGED
    
    | @@ -57,7 +57,7 @@ module SlackRubyBot | |
| 57 57 | 
             
                        rescue StandardError => e
         | 
| 58 58 | 
             
                          logger.error e
         | 
| 59 59 | 
             
                          begin
         | 
| 60 | 
            -
                            Slack.chat_postMessage(channel: data['channel'], text: e.message) if data.key?('channel')
         | 
| 60 | 
            +
                            Slack.chat_postMessage(channel: data['channel'], text: e.message, as_user: true) if data.key?('channel')
         | 
| 61 61 | 
             
                          rescue
         | 
| 62 62 | 
             
                            # ignore
         | 
| 63 63 | 
             
                          end
         | 
| @@ -1,10 +1,10 @@ | |
| 1 1 | 
             
            module SlackRubyBot
         | 
| 2 2 | 
             
              module Commands
         | 
| 3 3 | 
             
                class Default < Base
         | 
| 4 | 
            -
                  command 'default'
         | 
| 5 4 | 
             
                  command 'about'
         | 
| 5 | 
            +
                  match(/^(?<bot>\w*)$/)
         | 
| 6 6 |  | 
| 7 | 
            -
                  def self.call(data,  | 
| 7 | 
            +
                  def self.call(data, _match)
         | 
| 8 8 | 
             
                    send_message_with_gif data.channel, SlackRubyBot::ABOUT, 'selfie'
         | 
| 9 9 | 
             
                  end
         | 
| 10 10 | 
             
                end
         | 
| @@ -1,18 +1,17 @@ | |
| 1 1 | 
             
            module SlackRubyBot
         | 
| 2 2 | 
             
              module Commands
         | 
| 3 3 | 
             
                class Base
         | 
| 4 | 
            -
                  class_attribute : | 
| 5 | 
            -
                  class_attribute :commands
         | 
| 4 | 
            +
                  class_attribute :routes
         | 
| 6 5 |  | 
| 7 | 
            -
                  def self.send_message(channel, text)
         | 
| 6 | 
            +
                  def self.send_message(channel, text, options = { as_user: true })
         | 
| 8 7 | 
             
                    if text && text.length > 0
         | 
| 9 | 
            -
                       | 
| 8 | 
            +
                      chat_postMessage({ channel: channel, text: text }.merge(options))
         | 
| 10 9 | 
             
                    else
         | 
| 11 | 
            -
                      send_message_with_gif channel, 'Nothing to see here.', 'nothing'
         | 
| 10 | 
            +
                      send_message_with_gif channel, 'Nothing to see here.', 'nothing', options
         | 
| 12 11 | 
             
                    end
         | 
| 13 12 | 
             
                  end
         | 
| 14 13 |  | 
| 15 | 
            -
                  def self.send_message_with_gif(channel, text, keywords)
         | 
| 14 | 
            +
                  def self.send_message_with_gif(channel, text, keywords, options = { as_user: true })
         | 
| 16 15 | 
             
                    gif = begin
         | 
| 17 16 | 
             
                      Giphy.random(keywords)
         | 
| 18 17 | 
             
                    rescue StandardError => e
         | 
| @@ -20,7 +19,7 @@ module SlackRubyBot | |
| 20 19 | 
             
                      nil
         | 
| 21 20 | 
             
                    end
         | 
| 22 21 | 
             
                    text = text + "\n" + gif.image_url.to_s if gif
         | 
| 23 | 
            -
                    send_message channel, text
         | 
| 22 | 
            +
                    send_message channel, text, options
         | 
| 24 23 | 
             
                  end
         | 
| 25 24 |  | 
| 26 25 | 
             
                  def self.logger
         | 
| @@ -30,26 +29,58 @@ module SlackRubyBot | |
| 30 29 | 
             
                    end
         | 
| 31 30 | 
             
                  end
         | 
| 32 31 |  | 
| 33 | 
            -
                  def self.responds_to_command?(command)
         | 
| 34 | 
            -
                    commands ? commands.include?(command) : command == default_command_name
         | 
| 35 | 
            -
                  end
         | 
| 36 | 
            -
             | 
| 37 32 | 
             
                  def self.default_command_name
         | 
| 38 33 | 
             
                    name && name.split(':').last.downcase
         | 
| 39 34 | 
             
                  end
         | 
| 40 35 |  | 
| 41 | 
            -
                  def self. | 
| 42 | 
            -
                     | 
| 36 | 
            +
                  def self.operator(*values, &block)
         | 
| 37 | 
            +
                    values.each do |value|
         | 
| 38 | 
            +
                      match Regexp.new("^(?<operator>\\#{value})(?<expression>.*)$", Regexp::IGNORECASE), &block
         | 
| 39 | 
            +
                    end
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  def self.command(*values, &block)
         | 
| 43 | 
            +
                    values.each do |value|
         | 
| 44 | 
            +
                      match Regexp.new("^(?<bot>\\w*)[\\s]+(?<command>#{value})$", Regexp::IGNORECASE), &block
         | 
| 45 | 
            +
                      match Regexp.new("^(?<bot>\\w*)[\\s]+(?<command>#{value})[\\s]+(?<expression>.*)$", Regexp::IGNORECASE), &block
         | 
| 46 | 
            +
                    end
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  def self.invoke(data)
         | 
| 50 | 
            +
                    self.finalize_routes!
         | 
| 51 | 
            +
                    expression = data.text
         | 
| 52 | 
            +
                    called = false
         | 
| 53 | 
            +
                    routes.each_pair do |route, method|
         | 
| 54 | 
            +
                      match = route.match(expression)
         | 
| 55 | 
            +
                      next unless match
         | 
| 56 | 
            +
                      next if match.names.include?('bot') && match['bot'].downcase != SlackRubyBot.config.user
         | 
| 57 | 
            +
                      called = true
         | 
| 58 | 
            +
                      if method
         | 
| 59 | 
            +
                        method.call(data, match)
         | 
| 60 | 
            +
                      elsif self.respond_to?(:call)
         | 
| 61 | 
            +
                        send(:call, data, match)
         | 
| 62 | 
            +
                      else
         | 
| 63 | 
            +
                        fail NotImplementedError, data.text
         | 
| 64 | 
            +
                      end
         | 
| 65 | 
            +
                      break
         | 
| 66 | 
            +
                    end
         | 
| 67 | 
            +
                    called
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  def self.match(match, &block)
         | 
| 71 | 
            +
                    self.routes ||= {}
         | 
| 72 | 
            +
                    self.routes[match] = block
         | 
| 43 73 | 
             
                  end
         | 
| 44 74 |  | 
| 45 | 
            -
                   | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 75 | 
            +
                  private
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                  def self.chat_postMessage(message)
         | 
| 78 | 
            +
                    Slack.chat_postMessage(message)
         | 
| 48 79 | 
             
                  end
         | 
| 49 80 |  | 
| 50 | 
            -
                  def self. | 
| 51 | 
            -
                    self. | 
| 52 | 
            -
                     | 
| 81 | 
            +
                  def self.finalize_routes!
         | 
| 82 | 
            +
                    return if self.routes && self.routes.any?
         | 
| 83 | 
            +
                    command default_command_name
         | 
| 53 84 | 
             
                  end
         | 
| 54 85 | 
             
                end
         | 
| 55 86 | 
             
              end
         | 
| @@ -1,7 +1,9 @@ | |
| 1 1 | 
             
            module SlackRubyBot
         | 
| 2 2 | 
             
              module Commands
         | 
| 3 3 | 
             
                class Unknown < Base
         | 
| 4 | 
            -
                   | 
| 4 | 
            +
                  match(/^(?<bot>\w*)[\s]*(?<expression>.*)$/)
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  def self.call(data, _match)
         | 
| 5 7 | 
             
                    send_message_with_gif data.channel, "Sorry <@#{data.user}>, I don't understand that command!", 'idiot'
         | 
| 6 8 | 
             
                  end
         | 
| 7 9 | 
             
                end
         | 
| @@ -5,62 +5,15 @@ module SlackRubyBot | |
| 5 5 |  | 
| 6 6 | 
             
                  def message(data)
         | 
| 7 7 | 
             
                    data = Hashie::Mash.new(data)
         | 
| 8 | 
            -
                     | 
| 9 | 
            -
                     | 
| 10 | 
            -
                     | 
| 8 | 
            +
                    data.text.strip!
         | 
| 9 | 
            +
                    result = child_command_classes.detect { |d| d.invoke(data) }
         | 
| 10 | 
            +
                    result ||= built_in_command_classes.detect { |d| d.invoke(data) }
         | 
| 11 | 
            +
                    result ||= SlackRubyBot::Commands::Unknown.tap { |d| d.invoke(data) }
         | 
| 12 | 
            +
                    result
         | 
| 11 13 | 
             
                  end
         | 
| 12 14 |  | 
| 13 15 | 
             
                  private
         | 
| 14 16 |  | 
| 15 | 
            -
                  #
         | 
| 16 | 
            -
                  # Lookup a class that can execute a command or an operator.
         | 
| 17 | 
            -
                  #
         | 
| 18 | 
            -
                  # @param [String] text Free-formed text from Slack.
         | 
| 19 | 
            -
                  #
         | 
| 20 | 
            -
                  # @return [SlackRubyBot::Commands::Base] A child class of SlackRubyBot::Commands::Base.
         | 
| 21 | 
            -
                  #
         | 
| 22 | 
            -
                  def text_to_class(text)
         | 
| 23 | 
            -
                    return unless text
         | 
| 24 | 
            -
                    command, arguments = parse_command(text)
         | 
| 25 | 
            -
                    if command
         | 
| 26 | 
            -
                      [command_to_class(command) || SlackRubyBot::Commands::Unknown, command, arguments]
         | 
| 27 | 
            -
                    else
         | 
| 28 | 
            -
                      command, arguments = parse_operator(text)
         | 
| 29 | 
            -
                      [operator_to_class(command), command, arguments]
         | 
| 30 | 
            -
                    end
         | 
| 31 | 
            -
                  end
         | 
| 32 | 
            -
             | 
| 33 | 
            -
                  #
         | 
| 34 | 
            -
                  # Split text into a command and its arguments.
         | 
| 35 | 
            -
                  #
         | 
| 36 | 
            -
                  # @param [String] text Free-formed text from Slack, eg. `bot do something`.
         | 
| 37 | 
            -
                  #
         | 
| 38 | 
            -
                  # @return [Array] An array of command and arguments or nil.
         | 
| 39 | 
            -
                  #
         | 
| 40 | 
            -
                  def parse_command(text)
         | 
| 41 | 
            -
                    return unless text
         | 
| 42 | 
            -
                    parts = text.split.reject(&:blank?)
         | 
| 43 | 
            -
                    return unless parts && parts.any?
         | 
| 44 | 
            -
                    # command is [bot] <command> (argument1, ...)
         | 
| 45 | 
            -
                    bot_or_operator = parts.first.downcase
         | 
| 46 | 
            -
                    return unless SlackRubyBot.config.user == bot_or_operator
         | 
| 47 | 
            -
                    command = parts[1].try(:downcase) || 'default'
         | 
| 48 | 
            -
                    arguments = parts[2..parts.length]
         | 
| 49 | 
            -
                    [command, arguments]
         | 
| 50 | 
            -
                  end
         | 
| 51 | 
            -
             | 
| 52 | 
            -
                  #
         | 
| 53 | 
            -
                  # Split text into an operator and its arguments.
         | 
| 54 | 
            -
                  #
         | 
| 55 | 
            -
                  # @param [String] text Free-formed text from Slack, eg. =2+2.
         | 
| 56 | 
            -
                  #
         | 
| 57 | 
            -
                  # @return [Array] An array and arguments or nil.
         | 
| 58 | 
            -
                  #
         | 
| 59 | 
            -
                  def parse_operator(text)
         | 
| 60 | 
            -
                    return unless text && text.length > 0
         | 
| 61 | 
            -
                    [text[0], text[1..text.length].split.reject(&:blank?)]
         | 
| 62 | 
            -
                  end
         | 
| 63 | 
            -
             | 
| 64 17 | 
             
                  #
         | 
| 65 18 | 
             
                  # All commands.
         | 
| 66 19 | 
             
                  #
         | 
| @@ -88,34 +41,7 @@ module SlackRubyBot | |
| 88 41 | 
             
                  #
         | 
| 89 42 | 
             
                  def built_in_command_classes
         | 
| 90 43 | 
             
                    command_classes.select do |k|
         | 
| 91 | 
            -
                      k.name && k.name.starts_with?('SlackRubyBot::Commands::')
         | 
| 92 | 
            -
                    end
         | 
| 93 | 
            -
                  end
         | 
| 94 | 
            -
             | 
| 95 | 
            -
                  #
         | 
| 96 | 
            -
                  # Converts a command to a class.
         | 
| 97 | 
            -
                  #
         | 
| 98 | 
            -
                  # @param [String] command Command tet.
         | 
| 99 | 
            -
                  #
         | 
| 100 | 
            -
                  # @return [SlackRubyBot::Commands::Base] A command implementation.
         | 
| 101 | 
            -
                  #
         | 
| 102 | 
            -
                  def command_to_class(command)
         | 
| 103 | 
            -
                    # prioritize implementations to built-in classes
         | 
| 104 | 
            -
                    klass = child_command_classes.detect { |d| d.responds_to_command?(command) }
         | 
| 105 | 
            -
                    klass ||= built_in_command_classes.detect { |d| d.responds_to_command?(command) }
         | 
| 106 | 
            -
                    klass
         | 
| 107 | 
            -
                  end
         | 
| 108 | 
            -
             | 
| 109 | 
            -
                  #
         | 
| 110 | 
            -
                  # Converts an operator to a class.
         | 
| 111 | 
            -
                  #
         | 
| 112 | 
            -
                  # @param [String] operator Operator text.
         | 
| 113 | 
            -
                  #
         | 
| 114 | 
            -
                  # @return [<type>] An operator implementation.
         | 
| 115 | 
            -
                  #
         | 
| 116 | 
            -
                  def operator_to_class(operator)
         | 
| 117 | 
            -
                    command_classes.detect do |k|
         | 
| 118 | 
            -
                      k.responds_to_operator?(operator)
         | 
| 44 | 
            +
                      k.name && k.name.starts_with?('SlackRubyBot::Commands::') && k != SlackRubyBot::Commands::Unknown
         | 
| 119 45 | 
             
                    end
         | 
| 120 46 | 
             
                  end
         | 
| 121 47 | 
             
                end
         | 
| @@ -1,14 +1,13 @@ | |
| 1 1 | 
             
            require 'rspec/expectations'
         | 
| 2 2 |  | 
| 3 | 
            -
            RSpec::Matchers.define :respond_with_error do | | 
| 3 | 
            +
            RSpec::Matchers.define :respond_with_error do |error, error_message|
         | 
| 4 4 | 
             
              match do |actual|
         | 
| 5 5 | 
             
                channel, user, message = parse(actual)
         | 
| 6 | 
            -
                app = SlackRubyBot::App.new
         | 
| 7 6 | 
             
                allow(Giphy).to receive(:random)
         | 
| 8 7 | 
             
                begin
         | 
| 9 8 | 
             
                  expect do
         | 
| 10 9 | 
             
                    app.send(:message, text: message, channel: channel, user: user)
         | 
| 11 | 
            -
                  end.to raise_error  | 
| 10 | 
            +
                  end.to raise_error error, error_message
         | 
| 12 11 | 
             
                rescue RSpec::Expectations::ExpectationNotMetError => e
         | 
| 13 12 | 
             
                  @error_message = e.message
         | 
| 14 13 | 
             
                  raise e
         | 
| @@ -4,7 +4,7 @@ RSpec::Matchers.define :respond_with_slack_message do |expected| | |
| 4 4 | 
             
              match do |actual|
         | 
| 5 5 | 
             
                channel, user, message = parse(actual)
         | 
| 6 6 | 
             
                allow(Giphy).to receive(:random)
         | 
| 7 | 
            -
                expect(SlackRubyBot::Commands::Base).to receive(: | 
| 7 | 
            +
                expect(SlackRubyBot::Commands::Base).to receive(:chat_postMessage).with(channel: channel, text: expected, as_user: true)
         | 
| 8 8 | 
             
                app.send(:message, text: message, channel: channel, user: user)
         | 
| 9 9 | 
             
                true
         | 
| 10 10 | 
             
              end
         | 
| Binary file | 
    
        data/slack-ruby-bot.gemspec
    CHANGED
    
    | @@ -13,7 +13,7 @@ Gem::Specification.new do |s| | |
| 13 13 | 
             
              s.require_paths = ['lib']
         | 
| 14 14 | 
             
              s.homepage = 'http://github.com/dblock/slack-ruby-bot'
         | 
| 15 15 | 
             
              s.licenses = ['MIT']
         | 
| 16 | 
            -
              s.summary = ' | 
| 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-api', '~> 1.1.6'
         | 
| 19 19 | 
             
              s.add_dependency 'activesupport'
         | 
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe SlackRubyBot::Commands do
         | 
| 4 | 
            +
              let! :command do
         | 
| 5 | 
            +
                Class.new(SlackRubyBot::Commands::Base) do
         | 
| 6 | 
            +
                  command 'tomato' do |data, match|
         | 
| 7 | 
            +
                    send_message data.channel, "#{match[:command]}: #{match[:expression]}", as_user: true
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  command 'tomatoes' do |data, match|
         | 
| 11 | 
            +
                    send_message data.channel, "#{match[:command]}: #{match[:expression]}", as_user: true
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
              def app
         | 
| 16 | 
            +
                SlackRubyBot::App.new
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
              it 'matches commands' do
         | 
| 19 | 
            +
                expect(message: "#{SlackRubyBot.config.user} tomato red").to respond_with_slack_message('tomato: red')
         | 
| 20 | 
            +
                expect(message: "#{SlackRubyBot.config.user} tomatoes green").to respond_with_slack_message('tomatoes: green')
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
            end
         | 
| @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe SlackRubyBot::Commands do
         | 
| 4 | 
            +
              let! :command do
         | 
| 5 | 
            +
                Class.new(SlackRubyBot::Commands::Base) do
         | 
| 6 | 
            +
                  command 'space' do |data, match|
         | 
| 7 | 
            +
                    send_message data.channel, "#{match[:command]}: #{match[:expression]}", as_user: true
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
              def app
         | 
| 12 | 
            +
                SlackRubyBot::App.new
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
              it 'matches leading spaces' do
         | 
| 15 | 
            +
                expect(message: "  #{SlackRubyBot.config.user}   space red").to respond_with_slack_message('space: red')
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
              it 'matches trailing spaces' do
         | 
| 18 | 
            +
                expect(message: "#{SlackRubyBot.config.user}   space    red   ").to respond_with_slack_message('space: red')
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
            end
         | 
| @@ -6,8 +6,8 @@ describe SlackRubyBot::Commands do | |
| 6 6 | 
             
                  command 'sayhi'
         | 
| 7 7 | 
             
                  command 'saybye'
         | 
| 8 8 |  | 
| 9 | 
            -
                  def self.call(data,  | 
| 10 | 
            -
                    send_message data.channel, "#{command}: #{ | 
| 9 | 
            +
                  def self.call(data, match)
         | 
| 10 | 
            +
                    send_message data.channel, "#{match[:command]}: #{match[:expression]}", as_user: true
         | 
| 11 11 | 
             
                  end
         | 
| 12 12 | 
             
                end
         | 
| 13 13 | 
             
              end
         | 
| @@ -15,7 +15,7 @@ describe SlackRubyBot::Commands do | |
| 15 15 | 
             
                SlackRubyBot::App.new
         | 
| 16 16 | 
             
              end
         | 
| 17 17 | 
             
              it 'supports multiple commands' do
         | 
| 18 | 
            -
                expect(message: "#{SlackRubyBot.config.user} sayhi arg1 arg2").to respond_with_slack_message('sayhi:  | 
| 19 | 
            -
                expect(message: "#{SlackRubyBot.config.user} saybye arg1 arg2").to respond_with_slack_message('saybye:  | 
| 18 | 
            +
                expect(message: "#{SlackRubyBot.config.user} sayhi arg1 arg2").to respond_with_slack_message('sayhi: arg1 arg2')
         | 
| 19 | 
            +
                expect(message: "#{SlackRubyBot.config.user} saybye arg1 arg2").to respond_with_slack_message('saybye: arg1 arg2')
         | 
| 20 20 | 
             
              end
         | 
| 21 21 | 
             
            end
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe SlackRubyBot::Commands do
         | 
| 4 | 
            +
              let! :command do
         | 
| 5 | 
            +
                Class.new(SlackRubyBot::Commands::Base) do
         | 
| 6 | 
            +
                  command 'sayhi' do |data, match|
         | 
| 7 | 
            +
                    send_message data.channel, "#{match[:command]}: #{match[:expression]}", as_user: true
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  command 'one', 'two' do |data, match|
         | 
| 11 | 
            +
                    send_message data.channel, "#{match[:command]}: #{match[:expression]}", as_user: true
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
              def app
         | 
| 16 | 
            +
                SlackRubyBot::App.new
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
              it 'supports multiple commands' do
         | 
| 19 | 
            +
                expect(message: "#{SlackRubyBot.config.user} sayhi arg1 arg2").to respond_with_slack_message('sayhi: arg1 arg2')
         | 
| 20 | 
            +
                expect(message: "#{SlackRubyBot.config.user} one arg1 arg2").to respond_with_slack_message('one: arg1 arg2')
         | 
| 21 | 
            +
                expect(message: "#{SlackRubyBot.config.user} two arg1 arg2").to respond_with_slack_message('two: arg1 arg2')
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
| @@ -3,9 +3,9 @@ require 'spec_helper' | |
| 3 3 | 
             
            describe SlackRubyBot::Commands do
         | 
| 4 4 | 
             
              let! :command do
         | 
| 5 5 | 
             
                Class.new(SlackRubyBot::Commands::Base) do
         | 
| 6 | 
            -
                  command ' | 
| 6 | 
            +
                  command 'empty_text'
         | 
| 7 7 |  | 
| 8 | 
            -
                  def self.call(data,  | 
| 8 | 
            +
                  def self.call(data, _match)
         | 
| 9 9 | 
             
                    send_message data.channel, nil
         | 
| 10 10 | 
             
                  end
         | 
| 11 11 | 
             
                end
         | 
| @@ -15,7 +15,7 @@ describe SlackRubyBot::Commands do | |
| 15 15 | 
             
              end
         | 
| 16 16 | 
             
              it 'sends default text' do
         | 
| 17 17 | 
             
                allow(Giphy).to receive(:random)
         | 
| 18 | 
            -
                expect(SlackRubyBot::Commands::Base).to receive(:send_message_with_gif).with('channel', 'Nothing to see here.', 'nothing')
         | 
| 19 | 
            -
                app.send(:message, text: "#{SlackRubyBot.config.user}  | 
| 18 | 
            +
                expect(SlackRubyBot::Commands::Base).to receive(:send_message_with_gif).with('channel', 'Nothing to see here.', 'nothing', as_user: true)
         | 
| 19 | 
            +
                app.send(:message, text: "#{SlackRubyBot.config.user} empty_text", channel: 'channel', user: 'user')
         | 
| 20 20 | 
             
              end
         | 
| 21 21 | 
             
            end
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe SlackRubyBot::Commands::Base do
         | 
| 4 | 
            +
              let! :command do
         | 
| 5 | 
            +
                Class.new(SlackRubyBot::Commands::Base) do
         | 
| 6 | 
            +
                  command 'not_implemented'
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
              def app
         | 
| 10 | 
            +
                SlackRubyBot::App.new
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
              it 'raises not implemented' do
         | 
| 13 | 
            +
                expect(message: "#{SlackRubyBot.config.user} not_implemented").to respond_with_error(NotImplementedError, 'rubybot not_implemented')
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
            end
         | 
| @@ -6,8 +6,8 @@ describe SlackRubyBot::Commands do | |
| 6 6 | 
             
                  operator '='
         | 
| 7 7 | 
             
                  operator '-'
         | 
| 8 8 |  | 
| 9 | 
            -
                  def self.call(data,  | 
| 10 | 
            -
                    send_message data.channel, "#{ | 
| 9 | 
            +
                  def self.call(data, match)
         | 
| 10 | 
            +
                    send_message data.channel, "#{match[:operator]}: #{match[:expression]}", as_user: true
         | 
| 11 11 | 
             
                  end
         | 
| 12 12 | 
             
                end
         | 
| 13 13 | 
             
              end
         | 
| @@ -15,6 +15,6 @@ describe SlackRubyBot::Commands do | |
| 15 15 | 
             
                SlackRubyBot::App.new
         | 
| 16 16 | 
             
              end
         | 
| 17 17 | 
             
              it 'supports operators' do
         | 
| 18 | 
            -
                expect(message: '=2+2').to respond_with_slack_message('=:  | 
| 18 | 
            +
                expect(message: '=2+2').to respond_with_slack_message('=: 2+2')
         | 
| 19 19 | 
             
              end
         | 
| 20 20 | 
             
            end
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe SlackRubyBot::Commands do
         | 
| 4 | 
            +
              let! :command do
         | 
| 5 | 
            +
                Class.new(SlackRubyBot::Commands::Base) do
         | 
| 6 | 
            +
                  operator '=' do |data, match|
         | 
| 7 | 
            +
                    send_message data.channel, "#{match[:operator]}: #{match[:expression]}", as_user: true
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  operator '+', '-' do |data, match|
         | 
| 11 | 
            +
                    send_message data.channel, "#{match[:operator]}: #{match[:expression]}", as_user: true
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
              def app
         | 
| 16 | 
            +
                SlackRubyBot::App.new
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
              it 'supports operator blocks' do
         | 
| 19 | 
            +
                expect(message: '=2+2').to respond_with_slack_message('=: 2+2')
         | 
| 20 | 
            +
                expect(message: '+2+2').to respond_with_slack_message('+: 2+2')
         | 
| 21 | 
            +
                expect(message: '-2+2').to respond_with_slack_message('-: 2+2')
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
| @@ -5,8 +5,8 @@ describe RSpec do | |
| 5 5 | 
             
                Class.new(SlackRubyBot::Commands::Base) do
         | 
| 6 6 | 
             
                  command 'raise'
         | 
| 7 7 |  | 
| 8 | 
            -
                  def self.call(_data,  | 
| 9 | 
            -
                    fail ArgumentError, command
         | 
| 8 | 
            +
                  def self.call(_data, match)
         | 
| 9 | 
            +
                    fail ArgumentError, match[:command]
         | 
| 10 10 | 
             
                  end
         | 
| 11 11 | 
             
                end
         | 
| 12 12 | 
             
              end
         | 
| @@ -14,6 +14,6 @@ describe RSpec do | |
| 14 14 | 
             
                SlackRubyBot::App.new
         | 
| 15 15 | 
             
              end
         | 
| 16 16 | 
             
              it 'respond_with_error' do
         | 
| 17 | 
            -
                expect(message: "#{SlackRubyBot.config.user} raise").to respond_with_error('raise')
         | 
| 17 | 
            +
                expect(message: "#{SlackRubyBot.config.user} raise").to respond_with_error(ArgumentError, 'raise')
         | 
| 18 18 | 
             
              end
         | 
| 19 19 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,153 +1,153 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: slack-ruby-bot
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.3.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Daniel Doubrovkine
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2015-07- | 
| 11 | 
            +
            date: 2015-07-19 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: hashie
         | 
| 15 15 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 16 | 
             
                requirements:
         | 
| 17 | 
            -
                - -  | 
| 17 | 
            +
                - - ">="
         | 
| 18 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 19 | 
             
                    version: '0'
         | 
| 20 20 | 
             
              type: :runtime
         | 
| 21 21 | 
             
              prerelease: false
         | 
| 22 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 23 | 
             
                requirements:
         | 
| 24 | 
            -
                - -  | 
| 24 | 
            +
                - - ">="
         | 
| 25 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 26 | 
             
                    version: '0'
         | 
| 27 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 28 | 
             
              name: slack-api
         | 
| 29 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 30 | 
             
                requirements:
         | 
| 31 | 
            -
                - - ~>
         | 
| 31 | 
            +
                - - "~>"
         | 
| 32 32 | 
             
                  - !ruby/object:Gem::Version
         | 
| 33 33 | 
             
                    version: 1.1.6
         | 
| 34 34 | 
             
              type: :runtime
         | 
| 35 35 | 
             
              prerelease: false
         | 
| 36 36 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 37 | 
             
                requirements:
         | 
| 38 | 
            -
                - - ~>
         | 
| 38 | 
            +
                - - "~>"
         | 
| 39 39 | 
             
                  - !ruby/object:Gem::Version
         | 
| 40 40 | 
             
                    version: 1.1.6
         | 
| 41 41 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 42 42 | 
             
              name: activesupport
         | 
| 43 43 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 44 | 
             
                requirements:
         | 
| 45 | 
            -
                - -  | 
| 45 | 
            +
                - - ">="
         | 
| 46 46 | 
             
                  - !ruby/object:Gem::Version
         | 
| 47 47 | 
             
                    version: '0'
         | 
| 48 48 | 
             
              type: :runtime
         | 
| 49 49 | 
             
              prerelease: false
         | 
| 50 50 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 51 | 
             
                requirements:
         | 
| 52 | 
            -
                - -  | 
| 52 | 
            +
                - - ">="
         | 
| 53 53 | 
             
                  - !ruby/object:Gem::Version
         | 
| 54 54 | 
             
                    version: '0'
         | 
| 55 55 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 56 56 | 
             
              name: giphy
         | 
| 57 57 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 58 | 
             
                requirements:
         | 
| 59 | 
            -
                - - ~>
         | 
| 59 | 
            +
                - - "~>"
         | 
| 60 60 | 
             
                  - !ruby/object:Gem::Version
         | 
| 61 61 | 
             
                    version: 2.0.2
         | 
| 62 62 | 
             
              type: :runtime
         | 
| 63 63 | 
             
              prerelease: false
         | 
| 64 64 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 65 65 | 
             
                requirements:
         | 
| 66 | 
            -
                - - ~>
         | 
| 66 | 
            +
                - - "~>"
         | 
| 67 67 | 
             
                  - !ruby/object:Gem::Version
         | 
| 68 68 | 
             
                    version: 2.0.2
         | 
| 69 69 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 70 70 | 
             
              name: websocket-driver
         | 
| 71 71 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 72 72 | 
             
                requirements:
         | 
| 73 | 
            -
                - - ~>
         | 
| 73 | 
            +
                - - "~>"
         | 
| 74 74 | 
             
                  - !ruby/object:Gem::Version
         | 
| 75 75 | 
             
                    version: 0.5.4
         | 
| 76 76 | 
             
              type: :runtime
         | 
| 77 77 | 
             
              prerelease: false
         | 
| 78 78 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 79 79 | 
             
                requirements:
         | 
| 80 | 
            -
                - - ~>
         | 
| 80 | 
            +
                - - "~>"
         | 
| 81 81 | 
             
                  - !ruby/object:Gem::Version
         | 
| 82 82 | 
             
                    version: 0.5.4
         | 
| 83 83 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 84 84 | 
             
              name: rake
         | 
| 85 85 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 86 86 | 
             
                requirements:
         | 
| 87 | 
            -
                - -  | 
| 87 | 
            +
                - - ">="
         | 
| 88 88 | 
             
                  - !ruby/object:Gem::Version
         | 
| 89 89 | 
             
                    version: '0'
         | 
| 90 90 | 
             
              type: :development
         | 
| 91 91 | 
             
              prerelease: false
         | 
| 92 92 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 93 93 | 
             
                requirements:
         | 
| 94 | 
            -
                - -  | 
| 94 | 
            +
                - - ">="
         | 
| 95 95 | 
             
                  - !ruby/object:Gem::Version
         | 
| 96 96 | 
             
                    version: '0'
         | 
| 97 97 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 98 98 | 
             
              name: rspec
         | 
| 99 99 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 100 100 | 
             
                requirements:
         | 
| 101 | 
            -
                - -  | 
| 101 | 
            +
                - - ">="
         | 
| 102 102 | 
             
                  - !ruby/object:Gem::Version
         | 
| 103 103 | 
             
                    version: '0'
         | 
| 104 104 | 
             
              type: :development
         | 
| 105 105 | 
             
              prerelease: false
         | 
| 106 106 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 107 107 | 
             
                requirements:
         | 
| 108 | 
            -
                - -  | 
| 108 | 
            +
                - - ">="
         | 
| 109 109 | 
             
                  - !ruby/object:Gem::Version
         | 
| 110 110 | 
             
                    version: '0'
         | 
| 111 111 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 112 112 | 
             
              name: rack-test
         | 
| 113 113 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 114 114 | 
             
                requirements:
         | 
| 115 | 
            -
                - -  | 
| 115 | 
            +
                - - ">="
         | 
| 116 116 | 
             
                  - !ruby/object:Gem::Version
         | 
| 117 117 | 
             
                    version: '0'
         | 
| 118 118 | 
             
              type: :development
         | 
| 119 119 | 
             
              prerelease: false
         | 
| 120 120 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 121 121 | 
             
                requirements:
         | 
| 122 | 
            -
                - -  | 
| 122 | 
            +
                - - ">="
         | 
| 123 123 | 
             
                  - !ruby/object:Gem::Version
         | 
| 124 124 | 
             
                    version: '0'
         | 
| 125 125 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 126 126 | 
             
              name: vcr
         | 
| 127 127 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 128 128 | 
             
                requirements:
         | 
| 129 | 
            -
                - -  | 
| 129 | 
            +
                - - ">="
         | 
| 130 130 | 
             
                  - !ruby/object:Gem::Version
         | 
| 131 131 | 
             
                    version: '0'
         | 
| 132 132 | 
             
              type: :development
         | 
| 133 133 | 
             
              prerelease: false
         | 
| 134 134 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 135 135 | 
             
                requirements:
         | 
| 136 | 
            -
                - -  | 
| 136 | 
            +
                - - ">="
         | 
| 137 137 | 
             
                  - !ruby/object:Gem::Version
         | 
| 138 138 | 
             
                    version: '0'
         | 
| 139 139 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 140 140 | 
             
              name: webmock
         | 
| 141 141 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 142 142 | 
             
                requirements:
         | 
| 143 | 
            -
                - -  | 
| 143 | 
            +
                - - ">="
         | 
| 144 144 | 
             
                  - !ruby/object:Gem::Version
         | 
| 145 145 | 
             
                    version: '0'
         | 
| 146 146 | 
             
              type: :development
         | 
| 147 147 | 
             
              prerelease: false
         | 
| 148 148 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 149 149 | 
             
                requirements:
         | 
| 150 | 
            -
                - -  | 
| 150 | 
            +
                - - ">="
         | 
| 151 151 | 
             
                  - !ruby/object:Gem::Version
         | 
| 152 152 | 
             
                    version: '0'
         | 
| 153 153 | 
             
            - !ruby/object:Gem::Dependency
         | 
| @@ -170,22 +170,25 @@ executables: [] | |
| 170 170 | 
             
            extensions: []
         | 
| 171 171 | 
             
            extra_rdoc_files: []
         | 
| 172 172 | 
             
            files:
         | 
| 173 | 
            -
            - .gitignore
         | 
| 174 | 
            -
            - .rspec
         | 
| 175 | 
            -
            - .rubocop.yml
         | 
| 176 | 
            -
            - .rubocop_todo.yml
         | 
| 177 | 
            -
            - .travis.yml
         | 
| 173 | 
            +
            - ".gitignore"
         | 
| 174 | 
            +
            - ".rspec"
         | 
| 175 | 
            +
            - ".rubocop.yml"
         | 
| 176 | 
            +
            - ".rubocop_todo.yml"
         | 
| 177 | 
            +
            - ".travis.yml"
         | 
| 178 178 | 
             
            - CHANGELOG.md
         | 
| 179 179 | 
             
            - CONTRIBUTING.md
         | 
| 180 180 | 
             
            - DEPLOYMENT.md
         | 
| 181 181 | 
             
            - Gemfile
         | 
| 182 182 | 
             
            - LICENSE.md
         | 
| 183 183 | 
             
            - README.md
         | 
| 184 | 
            +
            - RELEASING.md
         | 
| 184 185 | 
             
            - Rakefile
         | 
| 185 186 | 
             
            - TUTORIAL.md
         | 
| 186 187 | 
             
            - examples/minimal/Gemfile
         | 
| 187 188 | 
             
            - examples/minimal/Gemfile.lock
         | 
| 188 189 | 
             
            - examples/minimal/pongbot.rb
         | 
| 190 | 
            +
            - examples/weather/Gemfile
         | 
| 191 | 
            +
            - examples/weather/weatherbot.rb
         | 
| 189 192 | 
             
            - lib/config/application.rb
         | 
| 190 193 | 
             
            - lib/config/boot.rb
         | 
| 191 194 | 
             
            - lib/config/environment.rb
         | 
| @@ -217,14 +220,20 @@ files: | |
| 217 220 | 
             
            - lib/slack_ruby_bot.rb
         | 
| 218 221 | 
             
            - screenshots/demo.gif
         | 
| 219 222 | 
             
            - screenshots/register-bot.png
         | 
| 223 | 
            +
            - screenshots/weather.gif
         | 
| 220 224 | 
             
            - slack-ruby-bot.gemspec
         | 
| 221 225 | 
             
            - spec/slack-ruby-bot/app_spec.rb
         | 
| 222 226 | 
             
            - spec/slack-ruby-bot/commands/about_spec.rb
         | 
| 227 | 
            +
            - spec/slack-ruby-bot/commands/commands_precedence_spec.rb
         | 
| 228 | 
            +
            - spec/slack-ruby-bot/commands/commands_spaces_spec.rb
         | 
| 223 229 | 
             
            - spec/slack-ruby-bot/commands/commands_spec.rb
         | 
| 230 | 
            +
            - spec/slack-ruby-bot/commands/commands_with_block_spec.rb
         | 
| 224 231 | 
             
            - spec/slack-ruby-bot/commands/empty_text_spec.rb
         | 
| 225 232 | 
             
            - spec/slack-ruby-bot/commands/help_spec.rb
         | 
| 226 233 | 
             
            - spec/slack-ruby-bot/commands/hi_spec.rb
         | 
| 234 | 
            +
            - spec/slack-ruby-bot/commands/not_implemented_spec.rb
         | 
| 227 235 | 
             
            - spec/slack-ruby-bot/commands/operators_spec.rb
         | 
| 236 | 
            +
            - spec/slack-ruby-bot/commands/operators_with_block_spec.rb
         | 
| 228 237 | 
             
            - spec/slack-ruby-bot/commands/unknown_spec.rb
         | 
| 229 238 | 
             
            - spec/slack-ruby-bot/rspec/respond_with_error_spec.rb
         | 
| 230 239 | 
             
            - spec/slack-ruby-bot/version_spec.rb
         | 
| @@ -239,28 +248,33 @@ require_paths: | |
| 239 248 | 
             
            - lib
         | 
| 240 249 | 
             
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 241 250 | 
             
              requirements:
         | 
| 242 | 
            -
              - -  | 
| 251 | 
            +
              - - ">="
         | 
| 243 252 | 
             
                - !ruby/object:Gem::Version
         | 
| 244 253 | 
             
                  version: '0'
         | 
| 245 254 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 246 255 | 
             
              requirements:
         | 
| 247 | 
            -
              - -  | 
| 256 | 
            +
              - - ">="
         | 
| 248 257 | 
             
                - !ruby/object:Gem::Version
         | 
| 249 258 | 
             
                  version: 1.3.6
         | 
| 250 259 | 
             
            requirements: []
         | 
| 251 260 | 
             
            rubyforge_project: 
         | 
| 252 | 
            -
            rubygems_version: 2. | 
| 261 | 
            +
            rubygems_version: 2.2.2
         | 
| 253 262 | 
             
            signing_key: 
         | 
| 254 263 | 
             
            specification_version: 4
         | 
| 255 | 
            -
            summary:  | 
| 264 | 
            +
            summary: The easiest way to write a Slack bot in Ruby.
         | 
| 256 265 | 
             
            test_files:
         | 
| 257 266 | 
             
            - spec/slack-ruby-bot/app_spec.rb
         | 
| 258 267 | 
             
            - spec/slack-ruby-bot/commands/about_spec.rb
         | 
| 268 | 
            +
            - spec/slack-ruby-bot/commands/commands_precedence_spec.rb
         | 
| 269 | 
            +
            - spec/slack-ruby-bot/commands/commands_spaces_spec.rb
         | 
| 259 270 | 
             
            - spec/slack-ruby-bot/commands/commands_spec.rb
         | 
| 271 | 
            +
            - spec/slack-ruby-bot/commands/commands_with_block_spec.rb
         | 
| 260 272 | 
             
            - spec/slack-ruby-bot/commands/empty_text_spec.rb
         | 
| 261 273 | 
             
            - spec/slack-ruby-bot/commands/help_spec.rb
         | 
| 262 274 | 
             
            - spec/slack-ruby-bot/commands/hi_spec.rb
         | 
| 275 | 
            +
            - spec/slack-ruby-bot/commands/not_implemented_spec.rb
         | 
| 263 276 | 
             
            - spec/slack-ruby-bot/commands/operators_spec.rb
         | 
| 277 | 
            +
            - spec/slack-ruby-bot/commands/operators_with_block_spec.rb
         | 
| 264 278 | 
             
            - spec/slack-ruby-bot/commands/unknown_spec.rb
         | 
| 265 279 | 
             
            - spec/slack-ruby-bot/rspec/respond_with_error_spec.rb
         | 
| 266 280 | 
             
            - spec/slack-ruby-bot/version_spec.rb
         |