lita 4.4.3 → 4.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 60f8a5c4baff97cb21c6bda0e37416b919747443
4
- data.tar.gz: 2ecdd16eb4c246c566178a31f4cfc277e0794282
3
+ metadata.gz: b05600a1b35088abb38dbb5f4bf68e3f97f3758e
4
+ data.tar.gz: d67724a6e50664c074e71729ca0cda9a389fcaa6
5
5
  SHA512:
6
- metadata.gz: 1f9d6e452648e187da436d3b9fbb248ff90243abc47ac671340df664f42b4c12c7d7fb832f169583cb485dd4adb44b554a79f4751f6ba011b6be6ed22fdc35d0
7
- data.tar.gz: 55d2096400b2dca088b16b40f07ae0888ed30ec98ad9dc6e873c5a2b7a23132b7b16c8649a3b61c49a1a0a6c9009c830bc0e7b5ce6f7c589aeef37c0b105eb57
6
+ metadata.gz: 425041c5ed45f464f8374053f45f85ce0487cba75c6eb5c35e2ae54fbcb48891cae4fc21d5c8732da2984da626c639b1704cd72d74860892837e526241aed7a3
7
+ data.tar.gz: 38658b9c6a4bc97c54f79355b49c36e1cb4a6329077554320f4376ed4170d4db3e84763178d989bbb8b7a6999f44425c653a55a27b4f9e564915183b74bbfb71
@@ -24,6 +24,8 @@ LineLength:
24
24
  Max: 100
25
25
  MethodLength:
26
26
  Enabled: false
27
+ NestedMethodDefinition:
28
+ Enabled: false
27
29
  NonNilCheck:
28
30
  Enabled: false
29
31
  ParameterLists:
@@ -1,9 +1,17 @@
1
1
  language: ruby
2
+ sudo: false
2
3
  cache: bundler
3
4
  rvm:
4
5
  - 2.0
5
6
  - 2.1
6
7
  - 2.2
8
+ - jruby-9.0.0.0
9
+ - rbx-2
10
+ matrix:
11
+ allow_failures:
12
+ - rvm: jruby-9.0.0.0
13
+ - rvm: rbx-2
14
+ fast_finish: true
7
15
  script: bundle exec rake
8
16
  before_install:
9
17
  - gem update --system
@@ -13,6 +21,7 @@ branches:
13
21
  except:
14
22
  - /^v[0-9]/
15
23
  notifications:
24
+ email: false
16
25
  webhooks:
17
26
  urls:
18
27
  - https://lita-freenode.herokuapp.com/travis
@@ -9,7 +9,7 @@ module Lita
9
9
  end
10
10
 
11
11
  # A Struct representing a chat route defined by a handler.
12
- class Route < Struct.new(
12
+ Route = Struct.new(
13
13
  :pattern,
14
14
  :callback,
15
15
  :command,
@@ -17,6 +17,8 @@ module Lita
17
17
  :help,
18
18
  :extensions
19
19
  )
20
+
21
+ class Route
20
22
  alias_method :command?, :command
21
23
  end
22
24
 
@@ -70,6 +72,13 @@ module Lita
70
72
  routes.map do |route|
71
73
  next unless route_applies?(route, message, robot)
72
74
  log_dispatch(route)
75
+ robot.trigger(
76
+ :message_dispatched,
77
+ handler: self,
78
+ route: route,
79
+ message: message,
80
+ robot: robot
81
+ )
73
82
  dispatch_to_route(route, robot, message)
74
83
  true
75
84
  end.any?
@@ -104,10 +104,34 @@ module Lita
104
104
  Lita.logger
105
105
  end
106
106
 
107
+ # Render an ERB template to a string, with any provided variables made available to the
108
+ # template.
109
+ # @param template_name [String] The name of the ERB template file.
110
+ # @param variables [Hash] An optional hash of variables to make available within the
111
+ # template. Hash keys become instance variable names with the hash values as the instance
112
+ # variables' values.
113
+ # @return [String] The rendered template.
114
+ # @since 4.2.0
107
115
  def render_template(template_name, variables = {})
108
116
  Template.from_file(file_for_template(template_name)).render(variables)
109
117
  end
110
118
 
119
+ # Renders an ERB template to a string, like {#render_template}, but also takes an array of
120
+ # modules with helper methods to be made available to the template.
121
+ # @param template_name [String] The name of the ERB template file.
122
+ # @param helpers [Array<Module>] An array of modules whose methods should be added to the
123
+ # template evaluation context.
124
+ # @param variables [Hash] An optional hash of variables to make available within the
125
+ # template. Hash keys become instance variable names with the hash values as the instance
126
+ # variables' values.
127
+ # @return [String] The rendered template.
128
+ # @since 4.5.0
129
+ def render_template_with_helpers(template_name, helpers, variables = {})
130
+ template = Template.from_file(file_for_template(template_name))
131
+ helpers.each { |helper| template.add_helper(helper) }
132
+ template.render(variables)
133
+ end
134
+
111
135
  # @see .translate
112
136
  def translate(*args)
113
137
  self.class.translate(*args)
@@ -1,17 +1,3 @@
1
- # Primary class from the +http_router+ gem.
2
- # @todo Remove this monkey patch as soon as a gem is released with this pull request merged:
3
- # https://github.com/joshbuddy/http_router/pull/40
4
- class HttpRouter
5
- # An individual HTTP route.
6
- class Route
7
- # Sets a name for the route. Monkey patched due to a bug.
8
- def name=(name)
9
- @name = name
10
- router.named_routes[name] << self if router
11
- end
12
- end
13
- end
14
-
15
1
  module Lita
16
2
  # Handlers use this class to define HTTP routes for the built-in web
17
3
  # server.
@@ -12,10 +12,20 @@ module Lita
12
12
  attr_reader :source
13
13
 
14
14
  # @!method user
15
- # The user who sent the message.
16
- # @return [Lita::User] The user.
17
- # @see Lita::Source#user
18
- def_delegators :source, :user
15
+ # The user who sent the message.
16
+ # @return [Lita::User] The user.
17
+ # @see Lita::Source#user
18
+ # @!method room_object
19
+ # The room where the message came from.
20
+ # @return [Lita::Room] The room.
21
+ # @see Lita::Source#room_object
22
+ # @since 4.5.0
23
+ # @!method private_message?
24
+ # Flag indicating that the message was sent to the robot privately.
25
+ # @return [Boolean] The boolean flag.
26
+ # @see Lita::Source#private_message?
27
+ # @since 4.5.0
28
+ def_delegators :source, :user, :room_object, :private_message?
19
29
 
20
30
  # @param robot [Lita::Robot] The currently running robot.
21
31
  # @param body [String] The body of the message.
@@ -25,10 +35,15 @@ module Lita
25
35
  @body = body
26
36
  @source = source
27
37
 
28
- name_pattern = Regexp.escape(@robot.mention_name)
29
- name_pattern = "#{name_pattern}|#{Regexp.escape(@robot.alias)}" if @robot.alias
38
+ name_pattern = "@?#{Regexp.escape(@robot.mention_name)}[:,]?\\s+"
39
+ alias_pattern = "#{Regexp.escape(@robot.alias)}\\s*" if @robot.alias
40
+ command_regex = if alias_pattern
41
+ /^\s*(?:#{name_pattern}|#{alias_pattern})/i
42
+ else
43
+ /^\s*#{name_pattern}/i
44
+ end
30
45
 
31
- @command = !!@body.sub!(/^\s*@?(?:#{name_pattern})[:,]?\s*/i, "")
46
+ @command = !!@body.sub!(command_regex, "")
32
47
  end
33
48
 
34
49
  # An array of arguments created by shellsplitting the message body, as if
@@ -4,7 +4,7 @@ module Lita
4
4
  # @api private
5
5
  class MiddlewareRegistry
6
6
  # A Rack middleware and its initialization arguments.
7
- class MiddlewareWrapper < Struct.new(:middleware, :args, :block); end
7
+ MiddlewareWrapper = Struct.new(:middleware, :args, :block)
8
8
 
9
9
  extend Forwardable
10
10
 
@@ -42,6 +42,12 @@ module Lita
42
42
  router.call(env)
43
43
  end
44
44
 
45
+ # Overrides the default inspect implementation to make output less verbose and more readable.
46
+ def inspect
47
+ hex_address = (object_id << 1).to_s(16).rjust(14, "0")
48
+ "#<Lita::RackApp:0x#{hex_address}>"
49
+ end
50
+
45
51
  # Finds the first route that matches the request environment, if any. Does not trigger the
46
52
  # route.
47
53
  # @param env [Hash] A Rack environment.
@@ -27,8 +27,16 @@ module Lita
27
27
  # @see Lita::Message#reply_with_mention
28
28
  # @!method user
29
29
  # @see Lita::Message#user
30
+ # @!method private_message?
31
+ # @see Lita::Message#private_message?
32
+ # @since 4.5.0
30
33
  def_delegators :message, :args, :reply, :reply_privately,
31
- :reply_with_mention, :user, :command?
34
+ :reply_with_mention, :user, :private_message?, :command?
35
+
36
+ # @!method room
37
+ # @see Lita::Message#room_object
38
+ # @since 4.5.0
39
+ def_delegator :message, :room_object, :room
32
40
 
33
41
  # @param message [Lita::Message] The incoming message.
34
42
  # @param pattern [Regexp] The pattern the incoming message matched.
@@ -31,7 +31,15 @@ module Lita
31
31
  return unless command_satisfied?(route, message)
32
32
  return if from_self?(message, robot)
33
33
  return unless matches_pattern?(route, message)
34
- return unless authorized?(robot, message.user, route.required_groups)
34
+ unless authorized?(robot, message.user, route.required_groups)
35
+ robot.trigger(
36
+ :route_authorization_failed,
37
+ message: message,
38
+ robot: robot,
39
+ route: route,
40
+ )
41
+ return
42
+ end
35
43
  return unless passes_route_hooks?(route, message, robot)
36
44
 
37
45
  true
@@ -10,6 +10,7 @@ module Lita
10
10
  include Matchers::ChatRouteMatcher
11
11
  include Matchers::HTTPRouteMatcher
12
12
  include Matchers::EventRouteMatcher
13
+ include Matchers::DeprecatedMethods
13
14
 
14
15
  class << self
15
16
  # Sets up the RSpec environment to easily test Lita handlers.
@@ -78,13 +79,10 @@ module Lita
78
79
  # Sends a message to the robot.
79
80
  # @param body [String] The message to send.
80
81
  # @param as [Lita::User] The user sending the message.
82
+ # @param from [Lita::Room] The room where the message is received from.
81
83
  # @return [void]
82
- def send_message(body, as: user)
83
- message = if as == user
84
- Message.new(robot, body, source)
85
- else
86
- Message.new(robot, body, Source.new(user: as))
87
- end
84
+ def send_message(body, as: user, from: nil)
85
+ message = Message.new(robot, body, Source.new(user: as, room: from))
88
86
 
89
87
  robot.receive(message)
90
88
  end
@@ -92,9 +90,10 @@ module Lita
92
90
  # Sends a "command" message to the robot.
93
91
  # @param body [String] The message to send.
94
92
  # @param as [Lita::User] The user sending the message.
93
+ # @param from [Lita::Room] The room where the message is received from.
95
94
  # @return [void]
96
- def send_command(body, as: user)
97
- send_message("#{robot.mention_name}: #{body}", as: as)
95
+ def send_command(body, as: user, from: nil)
96
+ send_message("#{robot.mention_name}: #{body}", as: as, from: from)
98
97
  end
99
98
 
100
99
  # Returns a Faraday connection hooked up to the currently running robot's Rack app.
@@ -109,138 +108,6 @@ module Lita
109
108
 
110
109
  Faraday::Connection.new { |c| c.adapter(:rack, robot.app) }
111
110
  end
112
-
113
- # Starts a chat routing test chain, asserting that a message should
114
- # trigger a route.
115
- # @param message [String] The message that should trigger the route.
116
- # @return [Matchers::Deprecated] A {Matchers::Deprecated} that should have +to+
117
- # called on it to complete the test.
118
- # @deprecated Will be removed in Lita 5.0. Use +is_expected.to route+ instead.
119
- def routes(message)
120
- STDERR.puts I18n.t(
121
- "lita.rspec.matcher_deprecated",
122
- old_method: "routes",
123
- new_method: "is_expected.to route",
124
- )
125
- Matchers::Deprecated.new(self, :route, true, message)
126
- end
127
-
128
- # Starts a chat routing test chain, asserting that a message should not
129
- # trigger a route.
130
- # @param message [String] The message that should not trigger the route.
131
- # @return [Matchers::Deprecated] A {Matchers::Deprecated} that should have +to+
132
- # called on it to complete the test.
133
- # @deprecated Will be removed in Lita 5.0. Use +is_expected.not_to route+ instead.
134
- def does_not_route(message)
135
- STDERR.puts I18n.t(
136
- "lita.rspec.matcher_deprecated",
137
- old_method: "does_not_route",
138
- new_method: "is_expected.not_to route",
139
- )
140
- Matchers::Deprecated.new(self, :route, false, message)
141
- end
142
- alias_method :doesnt_route, :does_not_route
143
-
144
- # Starts a chat routing test chain, asserting that a "command" message
145
- # should trigger a route.
146
- # @param message [String] The message that should trigger the route.
147
- # @return [Matchers::Deprecated] A {Matchers::Deprecated} that should have +to+
148
- # called on it to complete the test.
149
- # @deprecated Will be removed in Lita 5.0. Use +is_expected.to route_command+ instead.
150
- def routes_command(message)
151
- STDERR.puts I18n.t(
152
- "lita.rspec.matcher_deprecated",
153
- old_method: "routes_command",
154
- new_method: "is_expected.to route_command",
155
- )
156
- Matchers::Deprecated.new(self, :route_command, true, message)
157
- end
158
-
159
- # Starts a chat routing test chain, asserting that a "command" message
160
- # should not trigger a route.
161
- # @param message [String] The message that should not trigger the route.
162
- # @return [Matchers::Deprecated] A {Matchers::Deprecated} that should have +to+
163
- # called on it to complete the test.
164
- # @deprecated Will be removed in Lita 5.0. Use +is_expected.not_to route_command+ instead.
165
- def does_not_route_command(message)
166
- STDERR.puts I18n.t(
167
- "lita.rspec.matcher_deprecated",
168
- old_method: "does_not_route_command",
169
- new_method: "is_expected.not_to route_command",
170
- )
171
- Matchers::Deprecated.new(self, :route_command, false, message)
172
- end
173
- alias_method :doesnt_route_command, :does_not_route_command
174
-
175
- # Starts an HTTP routing test chain, asserting that a request to the given
176
- # path with the given HTTP request method will trigger a route.
177
- # @param http_method [Symbol] The HTTP request method that should trigger
178
- # the route.
179
- # @param path [String] The path URL component that should trigger the
180
- # route.
181
- # @return [Matchers::Deprecated] A {Matchers::Deprecated} that should
182
- # have +to+ called on it to complete the test.
183
- # @deprecated Will be removed in Lita 5.0. Use +is_expected.to route_http+ instead.
184
- def routes_http(http_method, path)
185
- STDERR.puts I18n.t(
186
- "lita.rspec.matcher_deprecated",
187
- old_method: "routes_http",
188
- new_method: "is_expected.to route_http",
189
- )
190
- Matchers::Deprecated.new(self, :route_http, true, http_method, path)
191
- end
192
-
193
- # Starts an HTTP routing test chain, asserting that a request to the given
194
- # path with the given HTTP request method will not trigger a route.
195
- # @param http_method [Symbol] The HTTP request method that should not
196
- # trigger the route.
197
- # @param path [String] The path URL component that should not trigger the
198
- # route.
199
- # @return [Matchers::Deprecated] A {Matchers::Deprecated} that should
200
- # have +to+ called on it to complete the test.
201
- # @deprecated Will be removed in Lita 5.0. Use +is_expected.not_to route_http+ instead.
202
- def does_not_route_http(http_method, path)
203
- STDERR.puts I18n.t(
204
- "lita.rspec.matcher_deprecated",
205
- old_method: "does_not_route_http",
206
- new_method: "is_expected.not_to route_http",
207
- )
208
- Matchers::Deprecated.new(self, :route_http, false, http_method, path)
209
- end
210
- alias_method :doesnt_route_http, :does_not_route_http
211
-
212
- # Starts an event subscription test chain, asserting that an event should
213
- # trigger the target method.
214
- # @param event_name [String, Symbol] The name of the event that should
215
- # be triggered.
216
- # @return [Matchers::Deprecated] A {Matchers::Deprecated} that
217
- # should have +to+ called on it to complete the test.
218
- # @deprecated Will be removed in Lita 5.0. Use +is_expected.to route_event+ instead.
219
- def routes_event(event_name)
220
- STDERR.puts I18n.t(
221
- "lita.rspec.matcher_deprecated",
222
- old_method: "routes_event",
223
- new_method: "is_expected.to route_event",
224
- )
225
- Matchers::Deprecated.new(self, :route_event, true, event_name)
226
- end
227
-
228
- # Starts an event subscription test chain, asserting that an event should
229
- # not trigger the target method.
230
- # @param event_name [String, Symbol] The name of the event that should
231
- # not be triggered.
232
- # @return [Matchers::Deprecated] A {Matchers::Deprecated} that
233
- # should have +to+ called on it to complete the test.
234
- # @deprecated Will be removed in Lita 5.0. Use +is_expected.not_to route_event+ instead.
235
- def does_not_route_event(event_name)
236
- STDERR.puts I18n.t(
237
- "lita.rspec.matcher_deprecated",
238
- old_method: "does_not_route_event",
239
- new_method: "is_expected.not_to route_event",
240
- )
241
- Matchers::Deprecated.new(self, :route_event, false, event_name)
242
- end
243
- alias_method :doesnt_route_event, :does_not_route_event
244
111
  end
245
112
  end
246
113
  end
@@ -1,6 +1,140 @@
1
1
  module Lita
2
2
  module RSpec
3
3
  module Matchers
4
+ module DeprecatedMethods
5
+ # Starts a chat routing test chain, asserting that a message should
6
+ # trigger a route.
7
+ # @param message [String] The message that should trigger the route.
8
+ # @return [Deprecated] A {Deprecated} that should have +to+
9
+ # called on it to complete the test.
10
+ # @deprecated Will be removed in Lita 5.0. Use +is_expected.to route+ instead.
11
+ def routes(message)
12
+ STDERR.puts I18n.t(
13
+ "lita.rspec.matcher_deprecated",
14
+ old_method: "routes",
15
+ new_method: "is_expected.to route",
16
+ )
17
+ Deprecated.new(self, :route, true, message)
18
+ end
19
+
20
+ # Starts a chat routing test chain, asserting that a message should not
21
+ # trigger a route.
22
+ # @param message [String] The message that should not trigger the route.
23
+ # @return [Deprecated] A {Deprecated} that should have +to+
24
+ # called on it to complete the test.
25
+ # @deprecated Will be removed in Lita 5.0. Use +is_expected.not_to route+ instead.
26
+ def does_not_route(message)
27
+ STDERR.puts I18n.t(
28
+ "lita.rspec.matcher_deprecated",
29
+ old_method: "does_not_route",
30
+ new_method: "is_expected.not_to route",
31
+ )
32
+ Deprecated.new(self, :route, false, message)
33
+ end
34
+ alias_method :doesnt_route, :does_not_route
35
+
36
+ # Starts a chat routing test chain, asserting that a "command" message
37
+ # should trigger a route.
38
+ # @param message [String] The message that should trigger the route.
39
+ # @return [Deprecated] A {Deprecated} that should have +to+
40
+ # called on it to complete the test.
41
+ # @deprecated Will be removed in Lita 5.0. Use +is_expected.to route_command+ instead.
42
+ def routes_command(message)
43
+ STDERR.puts I18n.t(
44
+ "lita.rspec.matcher_deprecated",
45
+ old_method: "routes_command",
46
+ new_method: "is_expected.to route_command",
47
+ )
48
+ Deprecated.new(self, :route_command, true, message)
49
+ end
50
+
51
+ # Starts a chat routing test chain, asserting that a "command" message
52
+ # should not trigger a route.
53
+ # @param message [String] The message that should not trigger the route.
54
+ # @return [Deprecated] A {Deprecated} that should have +to+
55
+ # called on it to complete the test.
56
+ # @deprecated Will be removed in Lita 5.0. Use +is_expected.not_to route_command+ instead.
57
+ def does_not_route_command(message)
58
+ STDERR.puts I18n.t(
59
+ "lita.rspec.matcher_deprecated",
60
+ old_method: "does_not_route_command",
61
+ new_method: "is_expected.not_to route_command",
62
+ )
63
+ Deprecated.new(self, :route_command, false, message)
64
+ end
65
+ alias_method :doesnt_route_command, :does_not_route_command
66
+
67
+ # Starts an HTTP routing test chain, asserting that a request to the given
68
+ # path with the given HTTP request method will trigger a route.
69
+ # @param http_method [Symbol] The HTTP request method that should trigger
70
+ # the route.
71
+ # @param path [String] The path URL component that should trigger the
72
+ # route.
73
+ # @return [Deprecated] A {Deprecated} that should
74
+ # have +to+ called on it to complete the test.
75
+ # @deprecated Will be removed in Lita 5.0. Use +is_expected.to route_http+ instead.
76
+ def routes_http(http_method, path)
77
+ STDERR.puts I18n.t(
78
+ "lita.rspec.matcher_deprecated",
79
+ old_method: "routes_http",
80
+ new_method: "is_expected.to route_http",
81
+ )
82
+ Deprecated.new(self, :route_http, true, http_method, path)
83
+ end
84
+
85
+ # Starts an HTTP routing test chain, asserting that a request to the given
86
+ # path with the given HTTP request method will not trigger a route.
87
+ # @param http_method [Symbol] The HTTP request method that should not
88
+ # trigger the route.
89
+ # @param path [String] The path URL component that should not trigger the
90
+ # route.
91
+ # @return [Deprecated] A {Deprecated} that should
92
+ # have +to+ called on it to complete the test.
93
+ # @deprecated Will be removed in Lita 5.0. Use +is_expected.not_to route_http+ instead.
94
+ def does_not_route_http(http_method, path)
95
+ STDERR.puts I18n.t(
96
+ "lita.rspec.matcher_deprecated",
97
+ old_method: "does_not_route_http",
98
+ new_method: "is_expected.not_to route_http",
99
+ )
100
+ Deprecated.new(self, :route_http, false, http_method, path)
101
+ end
102
+ alias_method :doesnt_route_http, :does_not_route_http
103
+
104
+ # Starts an event subscription test chain, asserting that an event should
105
+ # trigger the target method.
106
+ # @param event_name [String, Symbol] The name of the event that should
107
+ # be triggered.
108
+ # @return [Deprecated] A {Deprecated} that
109
+ # should have +to+ called on it to complete the test.
110
+ # @deprecated Will be removed in Lita 5.0. Use +is_expected.to route_event+ instead.
111
+ def routes_event(event_name)
112
+ STDERR.puts I18n.t(
113
+ "lita.rspec.matcher_deprecated",
114
+ old_method: "routes_event",
115
+ new_method: "is_expected.to route_event",
116
+ )
117
+ Deprecated.new(self, :route_event, true, event_name)
118
+ end
119
+
120
+ # Starts an event subscription test chain, asserting that an event should
121
+ # not trigger the target method.
122
+ # @param event_name [String, Symbol] The name of the event that should
123
+ # not be triggered.
124
+ # @return [Deprecated] A {Deprecated} that
125
+ # should have +to+ called on it to complete the test.
126
+ # @deprecated Will be removed in Lita 5.0. Use +is_expected.not_to route_event+ instead.
127
+ def does_not_route_event(event_name)
128
+ STDERR.puts I18n.t(
129
+ "lita.rspec.matcher_deprecated",
130
+ old_method: "does_not_route_event",
131
+ new_method: "is_expected.not_to route_event",
132
+ )
133
+ Deprecated.new(self, :route_event, false, event_name)
134
+ end
135
+ alias_method :doesnt_route_event, :does_not_route_event
136
+ end
137
+
4
138
  # Lita 3 versions of the routing matchers.
5
139
  # @deprecated Will be removed in Lita 5.0. Use the +is_expected+ forms instead.
6
140
  class Deprecated
@@ -24,6 +24,15 @@ module Lita
24
24
  # @param source [String] A string to use as the template's content.
25
25
  def initialize(source)
26
26
  @erb = ERB.new(source, $SAFE, "<>")
27
+ self.helpers = Set.new
28
+ end
29
+
30
+ # Add a module of helpers methods to be added to the template evalutation context.
31
+ # @param helper [Module] The module to extend onto the template evalutation context.
32
+ # @return [void]
33
+ # @since 4.5.0
34
+ def add_helper(helper)
35
+ helpers << helper
27
36
  end
28
37
 
29
38
  # Render the template with the provided variables.
@@ -36,10 +45,14 @@ module Lita
36
45
 
37
46
  private
38
47
 
48
+ attr_accessor :helpers
49
+
39
50
  # Create an empty object to use as the ERB context and set any provided variables in it.
40
51
  def context_binding(variables)
41
52
  context = TemplateEvaluationContext.new
42
53
 
54
+ helpers.each { |helper| context.extend(helper) }
55
+
43
56
  variables.each do |k, v|
44
57
  context.instance_variable_set("@#{k}", v)
45
58
  end
@@ -1,4 +1,4 @@
1
1
  module Lita
2
2
  # The current version of Lita.
3
- VERSION = "4.4.3"
3
+ VERSION = "4.5.0"
4
4
  end
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
 
23
23
  spec.add_runtime_dependency "bundler", ">= 1.3"
24
24
  spec.add_runtime_dependency "faraday", ">= 0.8.7"
25
- spec.add_runtime_dependency "http_router", ">= 0.11.1"
25
+ spec.add_runtime_dependency "http_router", ">= 0.11.2"
26
26
  spec.add_runtime_dependency "ice_nine", ">= 0.11.0"
27
27
  spec.add_runtime_dependency "i18n", ">= 0.6.9"
28
28
  spec.add_runtime_dependency "multi_json", ">= 1.7.7"
@@ -38,5 +38,5 @@ Gem::Specification.new do |spec|
38
38
  spec.add_development_dependency "simplecov"
39
39
  spec.add_development_dependency "coveralls"
40
40
  spec.add_development_dependency "pry"
41
- spec.add_development_dependency "rubocop", "~> 0.28.0"
41
+ spec.add_development_dependency "rubocop", "~> 0.33.0"
42
42
  end
@@ -81,6 +81,12 @@ describe handler, lita_handler: true do
81
81
  expect(replies).to be_empty
82
82
  end
83
83
 
84
+ it "triggers a :route_authorization_failed event when a user is not authorized" do
85
+ allow(robot).to receive(:trigger)
86
+ expect(robot).to receive(:trigger).with(:route_authorization_failed, anything)
87
+ send_message("admin")
88
+ end
89
+
84
90
  it "ignores messages from itself" do
85
91
  allow(user).to receive(:name).and_return(robot.name)
86
92
  send_message("message")
@@ -104,6 +110,11 @@ describe handler, lita_handler: true do
104
110
  end
105
111
  end
106
112
 
113
+ it "triggers a message_dispatched event" do
114
+ expect(robot).to receive(:trigger).with(:message_dispatched, anything)
115
+ send_message("message")
116
+ end
117
+
107
118
  it "raises exceptions in test mode" do
108
119
  expect { send_message("error") }.to raise_error(RuntimeError)
109
120
  end
@@ -181,8 +192,8 @@ describe handler, lita_handler: true do
181
192
 
182
193
  context "with another handler registered" do
183
194
  before do
184
- registry.register_handler(:test_2) do
185
- route(/three/) { |response| response.reply "got three" }
195
+ registry.register_handler(:test_2) do
196
+ route(/three/) { |response| response.reply "got three" }
186
197
  end
187
198
  end
188
199
 
@@ -80,7 +80,7 @@ describe Lita::Handler::Common, lita: true do
80
80
 
81
81
  it "raises an exception if the handler doesn't have a name to derive the namespace from" do
82
82
  handler = Class.new { include Lita::Handler::Common }
83
- expect { handler.namespace }.to raise_error
83
+ expect { handler.namespace }.to raise_error(RuntimeError, /must set a namespace/)
84
84
  end
85
85
  end
86
86
 
@@ -198,6 +198,29 @@ describe Lita::Handler::Common, lita: true do
198
198
  end
199
199
  end
200
200
 
201
+ describe "#render_template_with_helpers" do
202
+ before do
203
+ handler.template_root(File.expand_path(File.join("..", "..", "..", "templates"), __FILE__))
204
+ end
205
+
206
+ it "extends custom helpers into the template evaluation context" do
207
+ helpers = Module.new do
208
+ def reverse_name(first, last)
209
+ "#{last}, #{first}"
210
+ end
211
+ end
212
+
213
+ result = subject.render_template_with_helpers(
214
+ "helpers",
215
+ [helpers],
216
+ first: "Carl",
217
+ last: "Pug",
218
+ )
219
+
220
+ expect(result).to eq("Pug, Carl")
221
+ end
222
+ end
223
+
201
224
  describe "timer methods" do
202
225
  let(:queue) { Queue.new }
203
226
 
@@ -1,8 +1,10 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Lita::Message do
4
+ let(:mention_name) { "LitaBot" }
5
+
4
6
  let(:robot) do
5
- instance_double("Lita::Robot", name: "Lita", mention_name: "LitaBot", alias: ".")
7
+ instance_double("Lita::Robot", name: "Lita", mention_name: mention_name, alias: ".")
6
8
  end
7
9
 
8
10
  let(:source) { instance_double("Lita::Source") }
@@ -39,31 +41,66 @@ describe Lita::Message do
39
41
  end
40
42
 
41
43
  describe "#command?" do
42
- it "is true when the message is addressed to the Robot" do
43
- subject = described_class.new(
44
- robot,
45
- "#{robot.mention_name}: hello",
46
- source
47
- )
48
- expect(subject).to be_a_command
44
+ context "when the message is addressed to the robot" do
45
+ subject { described_class.new(robot, "#{robot.mention_name}: hello", source) }
46
+
47
+ it "is true" do
48
+ expect(subject).to be_a_command
49
+ end
49
50
  end
50
51
 
51
- it "is true when the Robot's name is capitalized differently" do
52
- subject = described_class.new(
53
- robot,
54
- "#{robot.mention_name.upcase}: hello",
55
- source
56
- )
57
- expect(subject).to be_a_command
52
+ context "when the message is addressed to the robot with different capitalization" do
53
+ subject { described_class.new(robot, "#{robot.mention_name.upcase}: hello", source) }
54
+
55
+ it "is true" do
56
+ expect(subject).to be_a_command
57
+ end
58
58
  end
59
59
 
60
- it "is true when the Robot's alias is used" do
61
- subject = described_class.new(
62
- robot,
63
- "#{robot.alias}hello",
64
- source
65
- )
66
- expect(subject).to be_a_command
60
+ context "when the message is addressed to the robot with a comma" do
61
+ subject { described_class.new(robot, "#{robot.mention_name.upcase}, hello", source) }
62
+
63
+ it "is true" do
64
+ expect(subject).to be_a_command
65
+ end
66
+ end
67
+
68
+ context "when the message is addressed to the robot with no trailing punctuation" do
69
+ subject { described_class.new(robot, "#{robot.mention_name.upcase} hello", source) }
70
+
71
+ it "is true" do
72
+ expect(subject).to be_a_command
73
+ end
74
+ end
75
+
76
+ context "when the message is addressed to the bot via alias with no space after it" do
77
+ subject { described_class.new(robot, "#{robot.alias}hello", source) }
78
+
79
+ it "is true" do
80
+ expect(subject).to be_a_command
81
+ end
82
+ end
83
+
84
+ context "when the message is addressed to the bot via alias with space after it" do
85
+ subject { described_class.new(robot, "#{robot.alias} hello", source) }
86
+
87
+ it "is true" do
88
+ expect(subject).to be_a_command
89
+ end
90
+ end
91
+
92
+ context "when the message incidentally starts with the mention name" do
93
+ let(:mention_name) { "sa" }
94
+
95
+ subject { described_class.new(robot, "salmon", source) }
96
+
97
+ it "is false" do
98
+ expect(subject).not_to be_a_command
99
+ end
100
+
101
+ it "does not affect the message body" do
102
+ expect(subject.body).to eq("salmon")
103
+ end
67
104
  end
68
105
 
69
106
  it "is false when the message is not addressed to the Robot" do
@@ -78,6 +115,20 @@ describe Lita::Message do
78
115
  end
79
116
  end
80
117
 
118
+ describe "#room_object" do
119
+ it "delegates to #source" do
120
+ expect(subject.source).to receive(:room_object)
121
+ subject.room_object
122
+ end
123
+ end
124
+
125
+ describe "#private_message?" do
126
+ it "delegates to #source" do
127
+ expect(subject.source).to receive(:private_message?)
128
+ subject.private_message?
129
+ end
130
+ end
131
+
81
132
  describe "#reply" do
82
133
  it "sends strings back to the source through the robot" do
83
134
  expect(robot).to receive(:send_messages).with(source, "foo", "bar")
@@ -36,4 +36,25 @@ describe Lita::Response do
36
36
  expect(subject.extensions[:foo]).to eq(:bar)
37
37
  end
38
38
  end
39
+
40
+ describe "#user" do
41
+ it "delegates to #message" do
42
+ expect(subject.message).to receive(:user)
43
+ subject.user
44
+ end
45
+ end
46
+
47
+ describe "#room" do
48
+ it "delegates to #message" do
49
+ expect(subject.message).to receive(:room_object)
50
+ subject.room
51
+ end
52
+ end
53
+
54
+ describe "#private_message?" do
55
+ it "delegates to #message" do
56
+ expect(subject.message).to receive(:private_message?)
57
+ subject.private_message?
58
+ end
59
+ end
39
60
  end
@@ -2,6 +2,7 @@ require "spec_helper"
2
2
 
3
3
  handler_class = Class.new(Lita::Handler) do
4
4
  route(/^message$/, :message)
5
+ route(/^channel$/, :channel)
5
6
  route(/^command$/, :command, command: true)
6
7
  route("restricted", :restricted, restrict_to: :some_group)
7
8
  route("admins only", :admins_only, restrict_to: :admins)
@@ -14,6 +15,15 @@ handler_class = Class.new(Lita::Handler) do
14
15
  response.reply(response.user.name)
15
16
  end
16
17
 
18
+ def channel(response)
19
+ if (room = response.message.source.room_object)
20
+ response.reply(room.id)
21
+ response.reply(room.name)
22
+ else
23
+ response.reply("No room")
24
+ end
25
+ end
26
+
17
27
  def command(response)
18
28
  response.reply("a", "command")
19
29
  end
@@ -39,6 +49,12 @@ describe handler_class, lita_handler: true do
39
49
  it { is_expected.not_to route("message").to(:not_a_message) }
40
50
  end
41
51
 
52
+ describe "routing channels" do
53
+ it { is_expected.to route("channel") }
54
+ it { is_expected.to route("channel").to(:channel) }
55
+ it { is_expected.not_to route("channel").to(:not_a_channel) }
56
+ end
57
+
42
58
  describe "routing commands" do
43
59
  it { is_expected.to route_command("command") }
44
60
  it { is_expected.not_to route("command") }
@@ -94,6 +110,18 @@ describe handler_class, lita_handler: true do
94
110
  end
95
111
  end
96
112
 
113
+ describe "#channel" do
114
+ it "replies with channel id if sent from room" do
115
+ room = Lita::Room.create_or_update(1, name: "Room")
116
+ send_message("channel", from: room)
117
+ expect(replies).to eq(%w(1 Room))
118
+ end
119
+ it "replies with no channel if not sent from room" do
120
+ send_message("channel")
121
+ expect(replies).to eq(["No room"])
122
+ end
123
+ end
124
+
97
125
  describe "#command" do
98
126
  it "replies with two strings" do
99
127
  send_command("command")
@@ -13,6 +13,23 @@ describe Lita::Template do
13
13
  end
14
14
  end
15
15
 
16
+ describe "#add_helper" do
17
+ subject { described_class.new("<%= reverse_name(@first, @last) %>") }
18
+ let(:helper) do
19
+ Module.new do
20
+ def reverse_name(first, last)
21
+ "#{last}, #{first}"
22
+ end
23
+ end
24
+ end
25
+
26
+ it "adds the helper to the evaluation context" do
27
+ subject.add_helper(helper)
28
+
29
+ expect(subject.render(first: "Carl", last: "Pug")).to eq("Pug, Carl")
30
+ end
31
+ end
32
+
16
33
  describe "#render" do
17
34
  context "with a static source template" do
18
35
  subject { described_class.new("Hello, Lita!") }
@@ -158,9 +158,9 @@ describe Lita do
158
158
 
159
159
  before do
160
160
  allow_any_instance_of(Lita::Robot).to receive(:run)
161
- allow(Lita::ConfigurationValidator).to receive(:new).with(described_class).and_return(
162
- validator
163
- )
161
+ allow(
162
+ Lita::ConfigurationValidator
163
+ ).to receive(:new).with(described_class).and_return(validator)
164
164
  end
165
165
 
166
166
  after { described_class.reset }
@@ -0,0 +1 @@
1
+ <%= reverse_name(@first, @last) %>
@@ -1,16 +1,17 @@
1
1
  module Lita
2
2
  module <%= config[:constant_namespace] %>
3
3
  class <%= config[:constant_name] %><% unless config[:plugin_type] == "extension" %> < <%= config[:plugin_type].capitalize %><% end %>
4
- end
4
+ # insert <%= config[:plugin_type] %> code here
5
5
 
6
- <%- if config[:plugin_type] == "adapter" -%>
7
- Lita.register_adapter(:<%= config[:name] %>, <%= config[:constant_name] %>)
8
- <%- elsif config[:plugin_type] == "handler" -%>
9
- Lita.register_handler(<%= config[:constant_name] %>)
10
- <%- else -%>
11
- # If your extension needs to register with a Lita hook, uncomment the
12
- # following line and change the hook name to the appropriate value:
13
- # Lita.register_hook(:hook_name, <%= config[:constant_name] %>)
14
- <%- end -%>
6
+ <%- if config[:plugin_type] == "adapter" -%>
7
+ Lita.register_adapter(:<%= config[:name] %>, self)
8
+ <%- elsif config[:plugin_type] == "handler" -%>
9
+ Lita.register_handler(self)
10
+ <%- else -%>
11
+ # If your extension needs to register with a Lita hook, uncomment the
12
+ # following line and change the hook name to the appropriate value:
13
+ # Lita.register_hook(:hook_name, self)
14
+ <%- end -%>
15
+ end
15
16
  end
16
17
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lita
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.3
4
+ version: 4.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jimmy Cuadra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-12 00:00:00.000000000 Z
11
+ date: 2015-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 0.11.1
47
+ version: 0.11.2
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
- version: 0.11.1
54
+ version: 0.11.2
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: ice_nine
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -254,14 +254,14 @@ dependencies:
254
254
  requirements:
255
255
  - - "~>"
256
256
  - !ruby/object:Gem::Version
257
- version: 0.28.0
257
+ version: 0.33.0
258
258
  type: :development
259
259
  prerelease: false
260
260
  version_requirements: !ruby/object:Gem::Requirement
261
261
  requirements:
262
262
  - - "~>"
263
263
  - !ruby/object:Gem::Version
264
- version: 0.28.0
264
+ version: 0.33.0
265
265
  description: ChatOps for Ruby.
266
266
  email:
267
267
  - jimmy@jimmycuadra.com
@@ -368,6 +368,7 @@ files:
368
368
  - spec/spec_helper.rb
369
369
  - spec/templates/basic.erb
370
370
  - spec/templates/basic.irc.erb
371
+ - spec/templates/helpers.erb
371
372
  - spec/templates/interpolated.erb
372
373
  - templates/locales/en.yml
373
374
  - templates/plugin/Gemfile
@@ -404,7 +405,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
404
405
  version: '0'
405
406
  requirements: []
406
407
  rubyforge_project:
407
- rubygems_version: 2.4.5
408
+ rubygems_version: 2.4.5.1
408
409
  signing_key:
409
410
  specification_version: 4
410
411
  summary: ChatOps framework for Ruby. Lita is a robot companion for your chat room.
@@ -446,5 +447,5 @@ test_files:
446
447
  - spec/spec_helper.rb
447
448
  - spec/templates/basic.erb
448
449
  - spec/templates/basic.irc.erb
450
+ - spec/templates/helpers.erb
449
451
  - spec/templates/interpolated.erb
450
- has_rdoc: