lita 4.5.0 → 4.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b05600a1b35088abb38dbb5f4bf68e3f97f3758e
4
- data.tar.gz: d67724a6e50664c074e71729ca0cda9a389fcaa6
3
+ metadata.gz: 411c330d69cc62203d31374e506722511a8582aa
4
+ data.tar.gz: 36b57d4429140175ab4baa79a322dc13beac79c0
5
5
  SHA512:
6
- metadata.gz: 425041c5ed45f464f8374053f45f85ce0487cba75c6eb5c35e2ae54fbcb48891cae4fc21d5c8732da2984da626c639b1704cd72d74860892837e526241aed7a3
7
- data.tar.gz: 38658b9c6a4bc97c54f79355b49c36e1cb4a6329077554320f4376ed4170d4db3e84763178d989bbb8b7a6999f44425c653a55a27b4f9e564915183b74bbfb71
6
+ metadata.gz: 287c23415f235842e613290b117557624affe4e1357430e873128066f719d6a7d79fd1847a52a97c30b91d40d8a7a1cf6287c2044a05f619749d023bee55fd78
7
+ data.tar.gz: 4a44d63d33e8420f474a48ef63311f4f324f272da4dedf60399e86ee3f69b7a1c9f29d61adb092a18759e1b1341ede9fe31b57026666d1f118668e138fbe3b5e
@@ -115,6 +115,7 @@ require_relative "lita/timer"
115
115
  require_relative "lita/robot"
116
116
  require_relative "lita/adapter"
117
117
  require_relative "lita/adapters/shell"
118
+ require_relative "lita/adapters/test"
118
119
  require_relative "lita/plugin_builder"
119
120
  require_relative "lita/route_validator"
120
121
  require_relative "lita/handlers/authorization"
@@ -4,6 +4,7 @@ module Lita
4
4
  # The names of methods that should be implemented by an adapter.
5
5
  # @since 4.4.0
6
6
  REQUIRED_METHODS = %i(
7
+ chat_service
7
8
  join
8
9
  part
9
10
  roster
@@ -65,6 +66,12 @@ module Lita
65
66
  robot.config.adapters.public_send(self.class.namespace)
66
67
  end
67
68
 
69
+ # @!method chat_service
70
+ # May return an object exposing chat-service-specific APIs.
71
+ # @return [Object, nil] The chat service API object, if any.
72
+ # @abstract This should be implemented by the adapter.
73
+ # @since 4.6.0
74
+
68
75
  # @!method join(room_id)
69
76
  # Joins the room with the specified ID.
70
77
  # @param room_id [String] The ID of the room.
@@ -0,0 +1,43 @@
1
+ module Lita
2
+ # A namespace to hold all subclasses of {Adapter}.
3
+ module Adapters
4
+ # An adapter for testing Lita and Lita plugins.
5
+ # @since 4.6.0
6
+ class Test < Adapter
7
+ # Adapter-specific methods exposed through {Robot}.
8
+ class ChatService
9
+ def initialize(sent_messages)
10
+ @sent_messages = sent_messages
11
+ end
12
+
13
+ # An array of recorded outgoing messages.
14
+ def sent_messages
15
+ @sent_messages.dup
16
+ end
17
+ end
18
+
19
+ def initialize(robot)
20
+ super
21
+
22
+ self.sent_messages = []
23
+ end
24
+
25
+ # Adapter-specific methods available via {Robot#chat_service}.
26
+ def chat_service
27
+ ChatService.new(sent_messages)
28
+ end
29
+
30
+ # Records outgoing messages.
31
+ def send_messages(_target, strings)
32
+ sent_messages.concat(strings)
33
+ end
34
+
35
+ private
36
+
37
+ # An array of recorded outgoing messages.
38
+ attr_accessor :sent_messages
39
+ end
40
+
41
+ Lita.register_adapter(:test, Test)
42
+ end
43
+ end
@@ -95,10 +95,8 @@ module Lita
95
95
  robot.hooks[:trigger_route].each { |hook| hook.call(response: response, route: route) }
96
96
  handler = new(robot)
97
97
  route.callback.call(handler, response)
98
- rescue Exception => e
99
- log_dispatch_error(e)
100
- robot.config.robot.error_handler.call(e)
101
- raise e if Lita.test_mode?
98
+ rescue => error
99
+ log_error(robot, error)
102
100
  end
103
101
 
104
102
  private
@@ -125,16 +123,6 @@ module Lita
125
123
  method: route.callback.method_name || "(block)"
126
124
  )
127
125
  end
128
-
129
- # Logs an error encountered during dispatch.
130
- def log_dispatch_error(e)
131
- Lita.logger.error I18n.t(
132
- "lita.handler.exception",
133
- handler: name,
134
- message: e.message,
135
- backtrace: e.backtrace.join("\n")
136
- )
137
- end
138
126
  end
139
127
  end
140
128
  end
@@ -37,6 +37,18 @@ module Lita
37
37
  end
38
38
 
39
39
  alias_method :t, :translate
40
+
41
+ # Logs an error raised by a plugin.
42
+ def log_error(robot, error)
43
+ robot.config.robot.error_handler.call(error)
44
+ Lita.logger.error I18n.t(
45
+ "lita.handler.exception",
46
+ handler: name,
47
+ message: error.message,
48
+ backtrace: error.backtrace.join("\n")
49
+ )
50
+ raise error if Lita.test_mode?
51
+ end
40
52
  end
41
53
 
42
54
  # A Redis::Namespace scoped to the handler.
@@ -57,7 +57,11 @@ module Lita
57
57
  # @return [Boolean] Whether or not the event triggered any callbacks.
58
58
  def trigger(robot, event_name, payload = {})
59
59
  event_subscriptions_for(event_name).map do |callback|
60
- callback.call(new(robot), payload)
60
+ begin
61
+ callback.call(new(robot), payload)
62
+ rescue => error
63
+ log_error(robot, error)
64
+ end
61
65
  end.any?
62
66
  end
63
67
 
@@ -36,13 +36,16 @@ module Lita
36
36
 
37
37
  def_delegators :registry, :config, :adapters, :handlers, :hooks
38
38
 
39
+ # @!method chat_service
40
+ # @see Lita::Adapter#chat_service
41
+ # @since 4.6.0
39
42
  # @!method mention_format(name)
40
43
  # @see Lita::Adapter#mention_format
41
44
  # @since 4.4.0
42
45
  # @!method roster(room)
43
46
  # @see Lita::Adapter#roster
44
47
  # @since 4.4.1
45
- def_delegators :adapter, :mention_format, :roster
48
+ def_delegators :adapter, :chat_service, :mention_format, :roster
46
49
 
47
50
  # @param registry [Lita::Registry] The registry for the robot's configuration and plugins.
48
51
  def initialize(registry = Lita)
@@ -18,13 +18,27 @@ module Lita
18
18
  base.send(:include, Lita::RSpec)
19
19
 
20
20
  prepare_handlers(base)
21
+ prepare_adapter(base)
21
22
  prepare_let_blocks(base)
22
23
  prepare_subject(base)
23
- prepare_robot(base)
24
24
  end
25
25
 
26
26
  private
27
27
 
28
+ # Stub Lita.adapters
29
+ def prepare_adapter(base)
30
+ base.class_eval do
31
+ before do
32
+ if Lita.version_3_compatibility_mode?
33
+ Lita.config.robot.adapter = :test
34
+ else
35
+ registry.register_adapter(:test, Lita::Adapters::Test)
36
+ registry.config.robot.adapter = :test
37
+ end
38
+ end
39
+ end
40
+ end
41
+
28
42
  # Stub Lita.handlers.
29
43
  def prepare_handlers(base)
30
44
  base.class_eval do
@@ -50,20 +64,7 @@ module Lita
50
64
  let(:robot) { Robot.new(registry) }
51
65
  let(:source) { Source.new(user: user) }
52
66
  let(:user) { User.create("1", name: "Test User") }
53
- let(:replies) { [] }
54
- end
55
- end
56
-
57
- # Stub Lita::Robot#send_messages.
58
- def prepare_robot(base)
59
- base.class_eval do
60
- before do
61
- [:send_messages, :send_message].each do |message|
62
- allow(robot).to receive(message) do |_target, *strings|
63
- replies.concat(strings)
64
- end
65
- end
66
- end
67
+ let(:replies) { robot.chat_service.sent_messages }
67
68
  end
68
69
  end
69
70
 
@@ -71,7 +72,6 @@ module Lita
71
72
  def prepare_subject(base)
72
73
  base.class_eval do
73
74
  subject { described_class.new(robot) }
74
- before { allow(described_class).to receive(:new).and_return(subject) }
75
75
  end
76
76
  end
77
77
  end
@@ -81,8 +81,12 @@ module Lita
81
81
  # @param as [Lita::User] The user sending the message.
82
82
  # @param from [Lita::Room] The room where the message is received from.
83
83
  # @return [void]
84
- def send_message(body, as: user, from: nil)
85
- message = Message.new(robot, body, Source.new(user: as, room: from))
84
+ def send_message(body, as: user, from: nil, privately: false)
85
+ message = Message.new(
86
+ robot,
87
+ body,
88
+ Source.new(user: as, room: from, private_message: privately)
89
+ )
86
90
 
87
91
  robot.receive(message)
88
92
  end
@@ -92,8 +96,8 @@ module Lita
92
96
  # @param as [Lita::User] The user sending the message.
93
97
  # @param from [Lita::Room] The room where the message is received from.
94
98
  # @return [void]
95
- def send_command(body, as: user, from: nil)
96
- send_message("#{robot.mention_name}: #{body}", as: as, from: from)
99
+ def send_command(body, as: user, from: nil, privately: false)
100
+ send_message("#{robot.mention_name}: #{body}", as: as, from: from, privately: privately)
97
101
  end
98
102
 
99
103
  # Returns a Faraday connection hooked up to the currently running robot's Rack app.
@@ -1,4 +1,4 @@
1
1
  module Lita
2
2
  # The current version of Lita.
3
- VERSION = "4.5.0"
3
+ VERSION = "4.6.0"
4
4
  end
@@ -1,7 +1,7 @@
1
1
  require "spec_helper"
2
2
 
3
- describe Lita::Handler::EventRouter do
4
- let(:robot) { instance_double("Lita::Robot", name: "Lita") }
3
+ describe Lita::Handler::EventRouter, lita: true do
4
+ let(:robot) { Lita::Robot.new(registry) }
5
5
 
6
6
  subject do
7
7
  Class.new do
@@ -27,6 +27,16 @@ describe Lita::Handler::EventRouter do
27
27
 
28
28
  on(:multiple_callbacks) { robot.send_message("first callback") }
29
29
  on(:multiple_callbacks) { robot.send_message("second callback") }
30
+
31
+ on(:multiple_errors) do
32
+ robot.send_message("first error")
33
+ raise ArgumentError, "first"
34
+ end
35
+
36
+ on(:multiple_errors) do
37
+ robot.send_message("second error")
38
+ raise ArgumentError, "second"
39
+ end
30
40
  end
31
41
  end
32
42
 
@@ -61,5 +71,47 @@ describe Lita::Handler::EventRouter do
61
71
  subject.trigger(robot, "connected")
62
72
  subject.trigger(robot, " ConNected ")
63
73
  end
74
+
75
+ context "not in test mode" do
76
+ around do |example|
77
+ test_mode = Lita.test_mode?
78
+ Lita.test_mode = false
79
+ begin
80
+ example.run
81
+ ensure
82
+ Lita.test_mode = test_mode
83
+ end
84
+ end
85
+
86
+ it "doesn't stop triggering callbacks after an exception is raised" do
87
+ expect(robot).to receive(:send_message).with("first error").once
88
+ expect(robot).to receive(:send_message).with("second error").once
89
+ subject.trigger(robot, :multiple_errors)
90
+ end
91
+
92
+ it "reports callback exceptions to the error handler" do
93
+ allow(robot).to receive(:send_message)
94
+ expect(registry.config.robot.error_handler).to receive(:call).twice
95
+ subject.trigger(robot, :multiple_errors)
96
+ end
97
+ end
98
+
99
+ context "in test mode" do
100
+ around do |example|
101
+ test_mode = Lita.test_mode?
102
+ Lita.test_mode = true
103
+ begin
104
+ example.run
105
+ ensure
106
+ Lita.test_mode = test_mode
107
+ end
108
+ end
109
+
110
+ it "re-raises callback exceptions immediately" do
111
+ allow(robot).to receive(:send_message)
112
+ expect(registry.config.robot.error_handler).to receive(:call).once
113
+ expect { subject.trigger(robot, :multiple_errors) }.to raise_error(ArgumentError, "first")
114
+ end
115
+ end
64
116
  end
65
117
  end
@@ -39,7 +39,7 @@ describe Lita::Handlers::Info, lita_handler: true do
39
39
 
40
40
  it "includes the adapter being used" do
41
41
  subject.web(request, response)
42
- expect(json).to include("adapter" => Lita.config.robot.adapter.to_s)
42
+ expect(json).to include("adapter" => registry.config.robot.adapter.to_s)
43
43
  end
44
44
 
45
45
  it "includes the robot's name" do
@@ -44,6 +44,10 @@ describe Lita::Robot, lita: true do
44
44
  subject.roster(instance_double("Lita::Room"))
45
45
  end
46
46
 
47
+ it "exposes Adapter#chat_service" do
48
+ expect { subject.chat_service }.not_to raise_error
49
+ end
50
+
47
51
  context "with registered handlers" do
48
52
  let(:handler1) { Class.new(Lita::Handler) { namespace :test } }
49
53
  let(:handler2) { Class.new(Lita::Handler) { namespace :test } }
@@ -3,6 +3,7 @@ require "spec_helper"
3
3
  handler_class = Class.new(Lita::Handler) do
4
4
  route(/^message$/, :message)
5
5
  route(/^channel$/, :channel)
6
+ route(/^private message$/, :private_message)
6
7
  route(/^command$/, :command, command: true)
7
8
  route("restricted", :restricted, restrict_to: :some_group)
8
9
  route("admins only", :admins_only, restrict_to: :admins)
@@ -24,6 +25,14 @@ handler_class = Class.new(Lita::Handler) do
24
25
  end
25
26
  end
26
27
 
28
+ def private_message(response)
29
+ if response.private_message?
30
+ response.reply("Private")
31
+ else
32
+ response.reply("Public")
33
+ end
34
+ end
35
+
27
36
  def command(response)
28
37
  response.reply("a", "command")
29
38
  end
@@ -116,12 +125,40 @@ describe handler_class, lita_handler: true do
116
125
  send_message("channel", from: room)
117
126
  expect(replies).to eq(%w(1 Room))
118
127
  end
128
+
119
129
  it "replies with no channel if not sent from room" do
120
130
  send_message("channel")
121
131
  expect(replies).to eq(["No room"])
122
132
  end
123
133
  end
124
134
 
135
+ describe "#private_message" do
136
+ let(:another_user) do
137
+ Lita::User.create(2, name: "Another User")
138
+ end
139
+
140
+ let(:room) do
141
+ Lita::Room.create_or_update(1, name: "Room")
142
+ end
143
+
144
+ it "replies with Private in response to a private message" do
145
+ send_message("private message", as: another_user, privately: true)
146
+ expect(source).to be_a_private_message
147
+ expect(replies.last).to eq("Private")
148
+ end
149
+
150
+ it "replies with Private in response to a private command" do
151
+ send_command("private message", as: another_user, privately: true)
152
+ expect(source).to be_a_private_message
153
+ expect(replies.last).to eq("Private")
154
+ end
155
+
156
+ it "replies with Public in response to a public message" do
157
+ send_message("private message", as: another_user, from: room)
158
+ expect(replies.last).to eq("Public")
159
+ end
160
+ end
161
+
125
162
  describe "#command" do
126
163
  it "replies with two strings" do
127
164
  send_command("command")
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.5.0
4
+ version: 4.6.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-08-21 00:00:00.000000000 Z
11
+ date: 2015-08-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -282,6 +282,7 @@ files:
282
282
  - lib/lita.rb
283
283
  - lib/lita/adapter.rb
284
284
  - lib/lita/adapters/shell.rb
285
+ - lib/lita/adapters/test.rb
285
286
  - lib/lita/authorization.rb
286
287
  - lib/lita/callback.rb
287
288
  - lib/lita/cli.rb
@@ -449,3 +450,4 @@ test_files:
449
450
  - spec/templates/basic.irc.erb
450
451
  - spec/templates/helpers.erb
451
452
  - spec/templates/interpolated.erb
453
+ has_rdoc: