lita 2.7.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.rubocop.yml +26 -0
  4. data/CONTRIBUTING.md +1 -1
  5. data/README.md +6 -470
  6. data/Rakefile +3 -3
  7. data/lib/lita.rb +27 -19
  8. data/lib/lita/adapter.rb +46 -5
  9. data/lib/lita/adapters/shell.rb +18 -13
  10. data/lib/lita/authorization.rb +1 -1
  11. data/lib/lita/cli.rb +37 -23
  12. data/lib/lita/common.rb +35 -0
  13. data/lib/lita/config.rb +33 -13
  14. data/lib/lita/daemon.rb +15 -12
  15. data/lib/lita/handler.rb +49 -9
  16. data/lib/lita/handlers/authorization.rb +47 -47
  17. data/lib/lita/handlers/help.rb +16 -17
  18. data/lib/lita/handlers/info.rb +38 -0
  19. data/lib/lita/handlers/room.rb +32 -0
  20. data/lib/lita/http_route.rb +30 -19
  21. data/lib/lita/message.rb +3 -6
  22. data/lib/lita/rack_app.rb +11 -89
  23. data/lib/lita/response.rb +5 -15
  24. data/lib/lita/robot.rb +26 -10
  25. data/lib/lita/rspec.rb +6 -8
  26. data/lib/lita/rspec/handler.rb +49 -121
  27. data/lib/lita/rspec/matchers/event_subscription_matcher.rb +67 -0
  28. data/lib/lita/rspec/matchers/http_route_matcher.rb +72 -0
  29. data/lib/lita/rspec/matchers/route_matcher.rb +69 -0
  30. data/lib/lita/source.rb +5 -18
  31. data/lib/lita/timer.rb +45 -0
  32. data/lib/lita/user.rb +51 -4
  33. data/lib/lita/util.rb +5 -5
  34. data/lib/lita/version.rb +1 -1
  35. data/lita.gemspec +6 -3
  36. data/spec/lita/adapter_spec.rb +10 -2
  37. data/spec/lita/adapters/shell_spec.rb +3 -3
  38. data/spec/lita/authorization_spec.rb +11 -11
  39. data/spec/lita/config_spec.rb +8 -0
  40. data/spec/lita/daemon_spec.rb +65 -0
  41. data/spec/lita/handler_spec.rb +50 -11
  42. data/spec/lita/handlers/authorization_spec.rb +1 -1
  43. data/spec/lita/handlers/info_spec.rb +31 -0
  44. data/spec/lita/handlers/room_spec.rb +20 -0
  45. data/spec/lita/logger_spec.rb +1 -1
  46. data/spec/lita/message_spec.rb +4 -4
  47. data/spec/lita/rack_app_spec.rb +92 -0
  48. data/spec/lita/response_spec.rb +17 -8
  49. data/spec/lita/robot_spec.rb +23 -14
  50. data/spec/lita/rspec_spec.rb +1 -1
  51. data/spec/lita/source_spec.rb +0 -16
  52. data/spec/lita/timer_spec.rb +30 -0
  53. data/spec/lita/user_spec.rb +66 -6
  54. data/spec/lita_spec.rb +37 -0
  55. data/spec/spec_helper.rb +11 -0
  56. data/templates/locales/en.yml +90 -0
  57. data/templates/plugin/Rakefile +1 -1
  58. data/templates/plugin/lib/lita/plugin_type/plugin.tt +4 -0
  59. data/templates/plugin/locales/en.yml.tt +4 -0
  60. metadata +77 -18
  61. data/lib/lita/handlers/web.rb +0 -25
  62. data/spec/lita/handlers/web_spec.rb +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d2302524669ae6fe1850b52bcd8478e510b774e7
4
- data.tar.gz: 0b47aa81f50dd2fbbb1540274438b28fb7c03350
3
+ metadata.gz: cd6d6161c1eadbc15d2edf48936f67ac8b42b1b5
4
+ data.tar.gz: 08133568571ac4fc50726e7c275cb937b4efbfdd
5
5
  SHA512:
6
- metadata.gz: 11706cb22bee31459b40b327edf4fbf714654f5e0145c935a244ba49813189c630d723a10acdc0d82d33021a933df592ad3d1a9329985799dd7851beb805be38
7
- data.tar.gz: 90f09f696a6a071bb892cc7253d408b4803b80e9b13d98289859b7e37251a9a35f5d3bdbea466f5eddd5473a368797c6cb58e7791169e629975560b2d9d98cb6
6
+ metadata.gz: ee9fc74314dd3cbb5f9d55478ba82f6481913e55b3d904cacd414eec6733a661a11284d921df4e5eeb2dea0b9028ae46042ce41aa96efe5abbed734f2fe7ca48
7
+ data.tar.gz: 925e426308386e860d9d1334015565f6c0d5a1b528f5aa493455bd8f9a714143ade62593b360ea2c18890233374cead1620d9851c078dfc620f9c102626b1187
data/.gitignore CHANGED
@@ -16,4 +16,4 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  .idea
19
-
19
+ lita_config.rb
@@ -0,0 +1,26 @@
1
+ AlignParameters:
2
+ Enabled: false
3
+ AndOr:
4
+ Enabled: false
5
+ CaseEquality:
6
+ Enabled: false
7
+ ClassLength:
8
+ Enabled: false
9
+ Documentation:
10
+ Enabled: false
11
+ EndAlignment:
12
+ AlignWith: variable
13
+ LineLength:
14
+ Max: 100
15
+ MethodLength:
16
+ Enabled: false
17
+ RescueException:
18
+ Enabled: false
19
+ SignalException:
20
+ Enabled: false
21
+ StringLiterals:
22
+ EnforcedStyle: double_quotes
23
+ TrailingComma:
24
+ Enabled: false
25
+ TrivialAccessors:
26
+ AllowPredicates: true
@@ -9,6 +9,6 @@ Found a bug in Lita? Open an issue on [GitHub Issues](https://github.com/jimmycu
9
9
  Ready to submit a pull request? Great! Contributions are most welcome. To get your contributions accepted, make sure:
10
10
 
11
11
  * All the tests pass. Run `rspec`.
12
- * No code quality warnings are generated by [Cane](https://github.com/square/cane). Run `cane`.
12
+ * No code quality warnings are generated by [RuboCop](https://github.com/bbatsov/rubocop). Run `rubocop`.
13
13
  * Any new code paths you've added are covered by tests.
14
14
  * Any new classes or methods you've added have API documentation compatible with [YARD](http://yardoc.org/). If you've significantly changed the behavior of an existing class or method, you should also update any existing API documentation.
data/README.md CHANGED
@@ -7,483 +7,19 @@
7
7
 
8
8
  ![Lita](http://f.cl.ly/items/0c271a2P3k2V180B1R0X/lita.jpg)
9
9
 
10
- **Lita** is a chat bot written in Ruby with persistent storage provided by [Redis](http://redis.io/). It can connect to any chat service (given that there is an [adapter](#adapters) available for it) and can have new behavior added via [handlers](#handlers). The plugin system is managed with regular RubyGems and [Bundler](http://gembundler.com/).
10
+ **Lita** is a chat bot written in [Ruby](https://www.ruby-lang.org/) with persistent storage provided by [Redis](http://redis.io/). It uses a plugin system to connect to different chat services and to provide new behavior. The plugin system uses the familiar tools of the Ruby ecosystem: [RubyGems](https://rubygems.org/) and [Bundler](http://gembundler.com/).
11
11
 
12
12
  Automate your business and have fun with your very own robot companion.
13
13
 
14
- ## Features
14
+ ## Documentation
15
15
 
16
- * Can work with any chat service
17
- * Simple installation and setup
18
- * Easily extendable with plugins
19
- * Data persistence with Redis
20
- * Built-in web server and routing
21
- * Event system for behavior triggered in response to arbitrary events
22
- * Support for outgoing HTTP requests
23
- * Group-based authorization
24
- * Configurable logging
25
- * Generators for creating new plugins
26
- * Built-in process daemonization
16
+ Please visit [lita.io](http://www.lita.io/) for comprehensive documentation.
27
17
 
28
- ## Why?
18
+ ## Plugins
29
19
 
30
- Lita draws much inspiration from GitHub's fantastic [Hubot](http://hubot.github.com/), but has a few key differences and strengths:
20
+ A list of all publicly available Lita plugins is available on the [lita.io plugins page](http://www.lita.io/plugins).
31
21
 
32
- * It's written in Ruby.
33
- * It exposes the full power of Redis rather than using it to serialize JSON.
34
- * It's easy to develop and test plugins for with the provied [RSpec](https://github.com/rspec/rspec) extras. Lita strongly encourages thorough testing of plugins.
35
- * It uses the Ruby ecosystem's standard tools (RubyGems and Bundler) for plugin installation and loading.
36
- * It's thoroughly documented.
37
-
38
- ## Is it any good?
39
-
40
- Yes.
41
-
42
- ## Dependencies
43
-
44
- * Ruby 2.0
45
- * Redis
46
-
47
- ## Installation
48
-
49
- First, install the gem with `gem install lita`. This gives you access to the `lita` command. Run `lita help` to list available tasks.
50
-
51
- Generate a new Lita instance by running `lita new NAME`. This will create a new directory called NAME (defaults to "lita") with a Gemfile and Lita configuration file.
52
-
53
- ## Usage
54
-
55
- To start your Lita instance, simply run `lita`. This will load up all the plugins (adapters and handlers) declared in your Gemfile, load any configuration you've defined (more on that later) and start the bot.
56
-
57
- ## Adapters
58
-
59
- The core Lita gem by itself doesn't do much. To make real use of it, you'll want to install an adapter gem to allow Lita to connect to the chat service of your choice. Find the gem for the service you want to use on [the list of adapters](https://github.com/jimmycuadra/lita/wiki/Adapters), then add it to your Gemfile. For example:
60
-
61
- ``` ruby
62
- gem "lita-hipchat"
63
- ```
64
-
65
- Adapters will likely require some configuration to be able to connect. See the documentation for the adapter for details.
66
-
67
- Without installing an adapter, you can use the default shell adapter to chat with Lita in your terminal. Lita doesn't respond to many messages by default, however, so you'll want to add some new behavior to Lita via handlers.
68
-
69
- ## Handlers
70
-
71
- Handlers are gems that add new behavior to Lita. They are responsible for listening for incoming messages and responding to them appropriately. Find the handler gems you want for your bot on [the list of handlers](https://github.com/jimmycuadra/lita/wiki/Handlers), then add them to your Gemfile. For example:
72
-
73
- ``` ruby
74
- gem "lita-karma"
75
- ```
76
-
77
- ## Configuration
78
-
79
- To configure Lita, edit the file `lita_config.rb` generated by the `lita new` command. This is just a plain Ruby file that will be evaluated when the bot is starting up. A Lita config file looks something like this:
80
-
81
- ``` ruby
82
- Lita.configure do |config|
83
- config.robot.name = "Sir Bottington"
84
- config.robot.mention_name = "bottington"
85
- config.robot.alias = "/"
86
- config.robot.adapter = :example_chat_service
87
- config.adapter.username = "bottington"
88
- config.adapter.password = "secret"
89
- config.redis.host = "redis.example.com"
90
- config.handlers.karma.cooldown = 300
91
- config.handlers.google_images.safe_search = :off
92
- end
93
- ```
94
-
95
- The main config objects are:
96
-
97
- * `robot` - General settings for Lita.
98
- * `name` (String) - The display name the bot will use on the chat service. Default: `"Lita"`.
99
- * `mention_name` (String) - The name the bot will look for in messages to determine if the message is being addressed to it. Usually this is the same as the display name, but in some cases it may not be. For example, in HipChat, display names are required to be a first and last name, such as "Lita Bot", whereas the mention system would use a name like "LitaBot". Default: `Lita.config.robot.name`.
100
- * `alias` (String) - The alias the bot will look for in messages to determine if the message is being addressed to it. Useful if you want to use something shorter than the robot's name or mention name, such as a slash, to send it a command. No default.
101
- * `adapter` (Symbol, String) - The adapter to load. Default: `:shell`.
102
- * `log_level` (Symbol, String) - The severity level of log messages to output. Valid options are, in order of severity: `:debug`, `:info`, `:warn`, `:error`, and `:fatal`. For whichever level you choose, log messages of that severity and greater will be output. Default: `:info`.
103
- * `admins` (Array<String>) - An array of string user IDs which tell Lita which users are considered administrators. Only these users will have access to Lita's `auth` command. Default: `nil`.
104
- * `redis` - Options for the Redis connection. See the [Redis gem](https://github.com/redis/redis-rb) documentation.
105
- * `http` - Settings related to Lita's built-in web server.
106
- * `port` (Integer) - The port the server should run on. Default: `8080`.
107
- * `debug` (Boolean) - Set to true to display the web server's logs mixed in with Lita's own logs. Default: `false`.
108
- * `adapter` - Options for the chosen adapter. See the adapter's documentation.
109
- * `handlers` - Handlers may choose to expose a config object here with their own options. See the handler's documentation.
110
-
111
- If you want to use a config file with a different name or location, invoke `lita` with the `-c` option and provide the path to the config file.
112
-
113
- ## Authorization
114
-
115
- Access to commands can be allowed for only certain users by means of authorization groups. Users set as admins (by adding their user IDs to the `config.robot.admins` array in Lita's configuration) have access to two commands:
116
-
117
- ```
118
- Lita: auth add joe committers
119
- Lita: auth remove joe committers
120
- ```
121
-
122
- The first command adds a user whose ID or name is "joe" to the authorization group "committers." If the group doesn't yet exist, it is created. The second command removes joe from the group. Handlers can specify that a route (a method that matches an incoming message) requires that the user sending the message be in a certain authorization group. See the section on writing handlers for more details.
123
-
124
- To list all the authorization groups and the names of the users in them, send Lita this command:
125
-
126
- ```
127
- Lita: auth list
128
- ```
129
-
130
- You can optionally suffix the command with the name of a group if you're only interested in the memebers of one group.
131
-
132
- ## Online help
133
-
134
- Message Lita `help` for a list of commands it knows about. You can also message it `help FOO` to list only commands beginning with FOO.
135
-
136
- ## Shell adapter
137
-
138
- Lita ships with one adapter for use directly in the shell. Simply type text at the input to send messages, and Lita will respond with any registered handlers. The shell adapter has one configuration attribute:
139
-
140
- * `private_chat` (Boolean) - If true, all messages will be treated as though they were sent in a private chat, so they will be considered commands even when not prefixed with the bot's name. Default: `false`.
141
-
142
- ## Writing an adapter
143
-
144
- An adapter is a packaged as a RubyGem. The adapter is a class that inherits from `Lita::Adapter`, implements a few required methods, and is registered by calling `Lita.register_adapter(:symbol_that_identifies_the_adapter, TheAdapterClass)`.
145
-
146
- To generate a starting template for a new adapter gem, run `lita adapter NAME`, where NAME is the name of the new gem.
147
-
148
- ### Example
149
-
150
- Here is a bare bones example of an adapter for the fictitious chat service, FancyChat.
151
-
152
- ``` ruby
153
- module Lita
154
- module Adapters
155
- class FancyChat < Adapter
156
- # Optional. Makes the bot produce an error message and quit upon start up
157
- # if `config.adapter.username` or `config.adapter.password` are not set.
158
- require_configs :username, :password
159
-
160
- # Connects to the chat service and dispatches incoming messages to a
161
- # Lita::Robot instance.
162
- def run
163
- end
164
-
165
- # Sends a message from the robot to a user or room on the chat service.
166
- def send_messages(target, strings)
167
- end
168
-
169
- # Sets the topic for a chat room.
170
- def set_topic(target, topic)
171
- end
172
-
173
- # Does any clean up necessary when disconnecting from the chat service.
174
- def shut_down
175
- end
176
- end
177
-
178
- Lita.register_adapter(:fancy_chat, FancyChat)
179
- end
180
- end
181
- ```
182
-
183
- It's important to note that each adapter should employ its own thread or event mechanism so that incoming messages can still be processed even while a handler is processing a previous message.
184
-
185
- For more detailed examples, check out the built in shell adapter, [lita-hipchat](https://github.com/jimmycuadra/lita-hipchat), or [lita-irc](https://github.com/jimmycuadra/lita-irc). See the API documentation for the exact methods and signatures adapters must implement.
186
-
187
- ## Writing a handler
188
-
189
- A handler is packaged as a RubyGem. A handler is a class that inherits from `Lita::Handler` and is registered by calling `Lita.register_handler(TheHandlerClass)`. There are two components to a handler: route definitions, and the methods that implement those routes. There are chat routes, HTTP routes, and event subscriptions available to handlers.
190
-
191
- To generate a starting template for a new handler gem, run `lita handler NAME`, where NAME is the name of the new gem.
192
-
193
- ### Chat routes
194
-
195
- To define a route, use the class method `route`:
196
-
197
- ``` ruby
198
- route /^echo\s+(.+)/, :echo
199
- ```
200
-
201
- `route` takes a regular expression that will be used to determine whether or not an incoming message should trigger the route, and the name of the method that should be called when this route is triggered. `route` takes a few additional options:
202
-
203
- * `:command` (Boolean) - If set to true, the route will only trigger when "directed" at the robot. Directed means that it's sent via a private message, or the message is prefixed with the bot's name in some form (optionally prefixed with an @, and optionally followed by a colon or comma and white space). This prefix is stripped from the message body itself, but `Lita::Message#command?` available in handlers can be used if you need to determine whether or not a message was a command after it's been routed. Default: `false`.
204
- * `:restrict_to` (Symbol, String, Array<String, Symbol>) - Authorization groups necessary to trigger the route. The user sending the message must be a member of at least one of the supplied groups. See the section on authorization for more information. Default: `nil`.
205
- * `:help` (Hash<String>) - A map of example invocations of the route and descriptions of what they do. These values will be used to generate the listing for the built-in "help" handler. The robot's mention name will automatically be added to the front of the example if the route is a command. Default: `{}`.
206
-
207
- Here is an example of a route declaration with all the options:
208
-
209
- ``` ruby
210
- route /^echo\s+(.+)/, :echo, command: true, restrict_to: [:testers, :committers], help => {
211
- "echo FOO" => "Replies back with FOO."
212
- }
213
- ```
214
-
215
- Each method that is called by a route takes one argument, a `Lita::Response` object. This object has the following useful methods:
216
-
217
- * `reply` - Sends one or more string messages back to the source of the original message, either a private message or a chat room.
218
- * `reply_privately` - Sends one or more string messages back to the user who sent the original message, whether it initated in a private message or a chat room.
219
- * `matches` - An array of regular expression matches obtained by calling `body_of_message.scan(route_regex)`.
220
- * `match_data` - A `MatchData` object obtained by calling `route_regex.match(body_of_message)`.
221
- * `args` - The user's message as an array of strings, as it would be parsed by `Shellwords.split`. For example, if the message was "Lita: auth add joe committers", calling `args` would return `["add", "joe", "committers"]`. ("auth" is considered the command and so is not included in the arguments.) This is very handy for commands that take arguments in a way similar to how a UNIX shell would work.
222
- * `message` - A `Lita::Message` object for the incoming message.
223
- * `user` - A `Lita::User` object for the user who sent the message.
224
-
225
- Additionally, handlers have access to these top-level methods:
226
-
227
- * `robot` - Direct access to the currently running `Lita::Robot` object.
228
- * `redis` - A `Redis::Namespace` object which provides each handler with its own isolated Redis store, suitable for many data persistence and manipulation tasks.
229
- * `http` - A `Faraday::Connection` object for making HTTP requests. Takes an optional hash of options and optional block which are passed on to [Faraday](https://github.com/lostisland/faraday).
230
-
231
- If a handler method crashes, the backtrace will be output to Lita's log with the `:error` level, but it will not crash the robot itself.
232
-
233
- ### HTTP routes
234
-
235
- In addition to chat routes, handlers can also define HTTP routes for the built-in web server. This is done with the class-level `http` method. `http` returns a `Lita::HTTPRoute` object, which has methods for the most common HTTP methods. These methods take two arguments: the path for the route, and the name of the method that it will invoke as a symbol. The callback method takes two arguments: a `Rack::Request` and a `Rack::Response`. For example:
236
-
237
- ``` ruby
238
- http.get "/foo/bar", :baz
239
-
240
- def baz(request, response)
241
- response.body = "Hello, world!"
242
- end
243
- ```
244
-
245
- ### Event subscriptions
246
-
247
- Handlers can communicate with each other or respond to arbitrary system events with the built-in pub-sub event system. Subscribe to an event by name, and provide the name of the instance method that should be invoked when the event triggers. Event callback methods are passed a payload hash with any arbitrary data the caller chooses to provide.
248
-
249
- ``` ruby
250
- on :connected, :greet
251
-
252
- def greet(payload)
253
- target = Source.new(room: payload[:room])
254
- robot.send_message(target, "Hello #{payload[:room]}!")
255
- end
256
- ```
257
-
258
- Trigger an event from anywhere and pass any payload data you want the subscribed handlers to receive:
259
-
260
- ``` ruby
261
- robot.trigger(:connected, room: "#litabot")
262
- ```
263
-
264
- Since the `trigger` method is available on `Lita::Robot`, it can be used from anywhere in the Lita runtime (both adapters and handlers).
265
-
266
- ### Built-in events
267
-
268
- Lita has a few built-in events:
269
-
270
- * `:loaded` - Fired when the `Lita::Robot` object has been initialized during start up. This can be used as a hook point for handlers to define routes that depend on user configuration not known until runtime, run migrations on data in Redis, or other start up tasks.
271
- * `:shut_down_started` - Fired when the robot first begins shutting down.
272
- * `:shut_down_completed` - Fired when the robot has finished shutting down both the built-in web server and the chat adapter.
273
-
274
- ### Handler-specific configuration
275
-
276
- If you want your handler to expose config settings to the user, use the class-level `default_config` method. This method accepts a single config object as an argument, which will be exposed to the user as `Lita.config.handlers.your_handler_namespace`.
277
-
278
- ``` ruby
279
- module Lita
280
- module Handlers
281
- class HandlerWithConfig < Handler
282
- def self.default_config(config)
283
- config.enabled = true
284
- end
285
- end
286
- end
287
- end
288
-
289
- Lita.config.handlers.handler_with_config.enabled # => true
290
- ```
291
-
292
- ### Examples
293
-
294
- Here is a basic handler which simply echoes back whatever the user says.
295
-
296
- ``` ruby
297
- module Lita
298
- module Handlers
299
- class Echo < Handler
300
- route /^echo\s+(.+)/, :echo, help: { "echo FOO" => "Echoes back FOO." }
301
-
302
- def echo(response)
303
- response.reply(response.matches)
304
- end
305
- end
306
-
307
- Lita.register_handler(Echo)
308
- end
309
- end
310
- ```
311
-
312
- Here is a handler that tells a user who their United States congressional representative is based on zip code with data from a fictional HTTP API. The results are saved in the handler's namespaced Redis store to save HTTP calls on future requests.
313
-
314
- ``` ruby
315
- module Lita
316
- module Handlers
317
- class Representative < Handler
318
- route /representative\s+(\d{5})/, :lookup, command: true, help: {
319
- "representative ZIP_CODE" => "Looks up the United States congressional representative for your zip code."
320
- }
321
-
322
- def lookup(response)
323
- zip = response.matches[0][0]
324
- rep = redis.get(zip)
325
- rep = get_rep(zip) unless rep
326
- response.reply "The representative for #{zip} is #{rep}."
327
- end
328
-
329
- private
330
-
331
- def get_rep(zip)
332
- http_response = http.get(
333
- "http://www.example.com/api/represenative",
334
- zip_code: zip
335
- )
336
-
337
- data = MultiJson.load(http_response.body)
338
- rep = data["representative"]["name"]
339
- redis.set(zip, rep)
340
- rep
341
- end
342
- end
343
-
344
- Lita.register_handler(Representative)
345
- end
346
- end
347
- ```
348
-
349
- For more detailed examples, check out the built in authorization, help, and web handlers, or external handlers [lita-karma](https://github.com/jimmycuadra/lita-karma) and [lita-google-images](https://github.com/jimmycuadra/lita-google-images). See the API documentation for exact specifications for handlers' methods.
350
-
351
- ## Testing
352
-
353
- It's a core philosophy of Lita that any plugins you write for your robot should be as thoroughly tested as any other program you would write. To make this easier, Lita ships with some handy extras for [RSpec](https://github.com/rspec/rspec) that make testing a plugin dead simple. They require the full RSpec suite (rspec-core, rspec-expectations, and rspec-mocks) version 2.14 or higher, as they use the newer "expect" syntax.
354
-
355
- ### Testing adapters
356
-
357
- To include some helpful setup for testing Lita code, require "lita/rspec", then add `lita: true` to the metadata for an example group.
358
-
359
- ``` ruby
360
- require "lita/rspec"
361
-
362
- describe Lita::Adapters::MyAdapter, lita: true do
363
- # ...
364
- end
365
- ```
366
-
367
- This will have the following effects:
368
-
369
- * All Redis interaction will be namespaced to a test environment and automatically cleared out before each example.
370
- * Lita's logger is stubbed to prevent log messages from cluttering up your test output.
371
- * Lita's configuration is cleared out before each example, so that the first call to `Lita.config` will start from the default configuration.
372
-
373
- ### Testing handlers
374
-
375
- To include Lita's RSpec extras for testing a handler, require "lita/rspec", then add `lita_handler: true` to the metadata for the example group.
376
-
377
- ``` ruby
378
- require "lita/rspec"
379
-
380
- describe Lita::Handlers::MyHandler, lita_handler: true do
381
- # ...
382
- end
383
- ```
384
-
385
- This will have the following effects, in addition to the effects of the `lita: true` metadata hook:
386
-
387
- * `Lita.handlers` will return an array with only the class you're testing (`described_class`).
388
- * Strings sent with `Lita::Robot#send_messages` will be pushed to an array accessible as `replies` so you can make expectations about output from the robot.
389
- * You have access to the following cached objects set with `let`: `robot`, `source`, and `user`. Note that these objects are instances of the real classes and not test doubles.
390
-
391
- The custom helper methods are where `Lita::RSpec` really shines. You can test routes (both chat and HTTP routes) and event subscriptions very easily using this syntax:
392
-
393
- #### Testing routes
394
-
395
- ``` ruby
396
- it { routes("some message").to(:some_method) }
397
- it { routes_command("directed message").to(:some_command_method) }
398
- it { doesnt_route("message").to(:some_command_method) }
399
- it { routes_http(:get, "/foo/bar").to(:baz) }
400
- it { doesnt_route_http(:post, "/foo/bar").to(:baz) }
401
- it { routes_event(:connected).to(:greet) }
402
- it { doesnt_route_event(:some_other_event).to(:greet) }
403
- ```
404
-
405
- * `routes` - Sets an expectation that the given string will trigger the given method when overheard by the robot.
406
- * `routes_command` - Sets an expectation that the given string will trigger the given method when directed at the robot, either in a private message, or by prefixing a message in a chat room with the robot's mention name.
407
- * `doesnt_route` - Sets an expectation that is the inverse of the one set by `routes`. Also aliased to `does_not_route`.
408
- * `doesnt_route_command` - Sets an expectation that is the inverse of the one set by `routes_command`. Also aliased to `does_not_route_command`.
409
- * `routes_http` - Sets an expectation that an HTTP request with the given HTTP method and path will route to the given handler method.
410
- * `doesnt_route_http` - Sets an expectation that is the inverse of `routes_http`. Also aliased to `does_not_route_http`.
411
- * `routes_event` - Sets an expectation that the given event will trigger the given subscribed method.
412
- * `doesnt_route_event` - Sets an expectation that is the inverse of `routes_event`. Also aliased to `does_not_route_event`.
413
-
414
- **Note: These routing helpers bypass authorization for routes restricted to authorization groups.**
415
-
416
- #### Testing handler methods
417
-
418
- Since the behavior in handlers are regular instance methods, you can unit test them just as you would any other methods in a Ruby class. However, if you prefer a more integration test approach, there are some helper methods available to help with this.
419
-
420
- To send a message to the robot, use `send_message` and `send_command`. Then set expectations about the contents of the `replies` array.
421
-
422
- ``` ruby
423
- it "lets everyone know when someone is happy" do
424
- send_message("I'm happy!")
425
- expect(replies.last).to eq("Hey, everyone! #{user.name} is happy! Isn't that nice?")
426
- end
427
-
428
- it "greets anyone that says hi to it" do
429
- send_command("hi")
430
- expect(repliest.last).to eq("Hello, #{user.name}!")
431
- end
432
- ```
433
-
434
- If you want to send a message or command from a user other than the default test user (set up for you with `let(:user)` by `Lita::RSpec`), you can invoke either method with the `:as` option, supplying a `Lita::User` object.
435
-
436
- ``` ruby
437
- it "lets everyone know that Carl is happy" do
438
- carl = Lita::User.create(123, name: "Carl")
439
- send_message("I'm happy!", as: carl)
440
- expect(replies.last).to eq("Hey, everyone! Carl is happy! Isn't that nice?")
441
- end
442
- ```
443
-
444
- * `send_message(string, as: user)` - Sends the given string to the robot.
445
- * `send_command(string, as: user)` - Sends the given string to the robot, prefixing it with the robot's mention name.
446
-
447
- ## Running as a daemon
448
-
449
- Lita has built-in support for daemonization on Unix systems. When run as a daemon, Lita will redirect standard output and standard error to a log file, and write the process ID to a PID file. To start Lita as a daemon, run `lita -d`. There are additional command line flags for specifying the path of the log and PID files, which override the defaults. If an existing Lita process is running when `lita -d` is invoked, Lita will abort and leave the original process running, unless the `-k` flag is specified, in which case it will kill the existing process. Run `lita help` for information about all the possible command line flags.
450
-
451
- ## Deploying to Heroku
452
-
453
- There are a few things worth mentioning when deploying an instance of Lita to Heroku:
454
-
455
- 1. Your Procfile should contain one process: `web: bundle exec lita`.
456
-
457
- 1. To use the Redis To Go add-on and the HTTP port set by Heroku, configure Lita like this:
458
-
459
- ``` ruby
460
- Lita.configure do |config|
461
- config.redis.url = ENV["REDISTOGO_URL"]
462
- config.http.port = ENV["PORT"]
463
- end
464
- ```
465
-
466
- 1. Consider using a service like [Uptime Robot](http://www.uptimerobot.com/) to monitor your Lita instance and keep it from [sleeping](https://blog.heroku.com/archives/2013/6/20/app_sleeping_on_heroku) when running on a free dyno. `/lita/info` is a reliable path to hit from the web to keep it running.
467
-
468
- ## API documentation
469
-
470
- Complete documentation for all of Lita's classes and methods can be found at [rdoc.info](http://rdoc.info/gems/lita/frames).
471
-
472
- ## Available plugins
473
-
474
- * [Adapters](https://github.com/jimmycuadra/lita/wiki/Adapters)
475
- * [Handlers](https://github.com/jimmycuadra/lita/wiki/Handlers)
476
-
477
- If you release a Lita plugin of your own, be sure to add it to one of the above lists!
478
-
479
- ## Questions, feedback, and discussion
480
-
481
- * [Google Group](http://groups.google.com/group/litaio)
482
- * [IRC](https://webchat.freenode.net/) (`#lita.io` on the Freenode network)
483
-
484
- ## Bug reports
485
-
486
- * [GitHub Issues](https://github.com/jimmycuadra/lita/issues)
22
+ The plugins page automatically updates daily with information from RubyGems. See [publishing](http://www.lita.io/plugin-authoring#publishing) for more information.
487
23
 
488
24
  ## Contributing
489
25