lita 4.3.2 → 4.4.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: 1bdd0419bd6701e21efff584a64c111fc1459f61
4
- data.tar.gz: b5344ba16def3e3f64436bbc8530de08874cc5c7
3
+ metadata.gz: f9215364634b3989e49830b555b053790f05cea4
4
+ data.tar.gz: beb555742378d6644ae0f0f907d16e44051441ff
5
5
  SHA512:
6
- metadata.gz: 09897b35e777fd74d4f9a340dd08a079795458e6ac5f2ddb0f6886003a449a0144b461c312e7108a9bf2919b935106bd463a99a877ce962af38a04e4cfbe953e
7
- data.tar.gz: 48dbf19395304d6fbee73486ce28992bb8bc4b2c16b6a728f342c3c0035438a0bb98c9dc2637605f5ca9f08e05e56dde34acb0c713a4f4e9d082e702f9d1f7ac
6
+ metadata.gz: c5f9eff256a23b5e9888427f2f91cedc37e2560948db164b103a118da49cf8232f17dc1c8b0c96d05d9156da2af57a8bb040fa2c0ed9b57475b36e05007891da
7
+ data.tar.gz: a1258925bedd819e2af1e6742abb3b555b23e596829e7cfa4df5baa4bd6253488be406704054d24cc54d113b360a22cb9f21bf903e52bd9454a6eb7bc5ecd455
@@ -1,6 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 2.0.0
4
+ - 2.1.6
5
+ - 2.2.2
4
6
  script: bundle exec rake
5
7
  before_install:
6
8
  - gem update --system
@@ -40,7 +40,7 @@ module Lita
40
40
  # The global Logger object.
41
41
  # @return [::Logger] The global Logger object.
42
42
  def logger
43
- @logger ||= Logger.get_logger(config.robot.log_level)
43
+ @logger ||= Logger.get_logger(config.robot.log_level, config.robot.log_formatter)
44
44
  end
45
45
 
46
46
  # The root Redis object.
@@ -103,6 +103,7 @@ require_relative "lita/handler/http_router"
103
103
  require_relative "lita/handler/event_router"
104
104
  require_relative "lita/handler"
105
105
  require_relative "lita/user"
106
+ require_relative "lita/room"
106
107
  require_relative "lita/source"
107
108
  require_relative "lita/authorization"
108
109
  require_relative "lita/message"
@@ -1,6 +1,18 @@
1
1
  module Lita
2
2
  # Adapters are the glue between Lita's API and a chat service.
3
3
  class Adapter
4
+ # The names of methods that should be implemented by an adapter.
5
+ # @since 4.4.0
6
+ REQUIRED_METHODS = %i(
7
+ join
8
+ part
9
+ roster
10
+ run
11
+ send_messages
12
+ set_topic
13
+ shut_down
14
+ ).freeze
15
+
4
16
  extend Namespace
5
17
  extend Configurable
6
18
 
@@ -53,20 +65,27 @@ module Lita
53
65
  robot.config.adapters.public_send(self.class.namespace)
54
66
  end
55
67
 
56
- # @!method join
68
+ # @!method join(room_id)
57
69
  # Joins the room with the specified ID.
58
70
  # @param room_id [String] The ID of the room.
59
71
  # @return [void]
60
72
  # @abstract This should be implemented by the adapter.
61
73
  # @since 3.0.0
62
74
 
63
- # @!method part
75
+ # @!method part(room_id)
64
76
  # Parts from the room with the specified ID.
65
77
  # @param room_id [String] The ID of the room.
66
78
  # @return [void]
67
79
  # @abstract This should be implemented by the adapter.
68
80
  # @since 3.0.0
69
81
 
82
+ # @!method roster(room)
83
+ # Get a list of users that are online in the given room.
84
+ # @param room [Lita::Room] The room to return a roster for.
85
+ # @return [Array<Lita::Roster>] An array of users.
86
+ # @abstract This should be implemented by the adapter.
87
+ # @since 4.4.0
88
+
70
89
  # @!method run
71
90
  # The main loop. Should connect to the chat service, listen for incoming
72
91
  # messages, create {Lita::Message} objects from them, and dispatch them to
@@ -92,7 +111,7 @@ module Lita
92
111
  # Performs any clean up necessary when disconnecting from the chat service.
93
112
  # @return [void]
94
113
  # @abstract This should be implemented by the adapter.
95
- [:join, :part, :run, :send_messages, :set_topic, :shut_down].each do |method|
114
+ REQUIRED_METHODS.each do |method|
96
115
  define_method(method) do |*_args|
97
116
  Lita.logger.warn(I18n.t("lita.adapter.method_not_implemented", method: method))
98
117
  end
@@ -5,11 +5,27 @@ module Lita
5
5
  class Shell < Adapter
6
6
  config :private_chat, default: false
7
7
 
8
- # Creates a "Shell User" and then loops a prompt and input, passing the
9
- # incoming messages to the robot.
8
+ def initialize(robot)
9
+ super
10
+
11
+ self.user = User.create(1, name: "Shell User")
12
+ end
13
+
14
+ # rubocop:disable Lint/UnusedMethodArgument
15
+
16
+ # Returns the users in the room, which is only ever the "Shell User."
17
+ # @param room [Lita::Room] The room to return a roster for. Not used in this adapter.
18
+ # @return [Array<Lita::User>] The users in the room.
19
+ # @since 4.4.0
20
+ def roster(room)
21
+ [user]
22
+ end
23
+
24
+ # rubocop:enable Lint/UnusedMethodArgument
25
+
26
+ # Displays a prompt and requests input in a loop, passing the incoming messages to the robot.
10
27
  # @return [void]
11
28
  def run
12
- user = User.create(1, name: "Shell User")
13
29
  room = robot.config.adapters.shell.private_chat ? nil : "shell"
14
30
  @source = Source.new(user: user, room: room)
15
31
  puts t("startup_message")
@@ -40,6 +56,8 @@ module Lita
40
56
 
41
57
  private
42
58
 
59
+ attr_accessor :user
60
+
43
61
  def build_message(input, source)
44
62
  message = Message.new(robot, input, source)
45
63
  message.command! if robot.config.adapters.shell.private_chat
@@ -45,6 +45,7 @@ module Lita
45
45
  config.robot.locale = I18n.locale
46
46
  config.robot.log_level = :info
47
47
  config.robot.admins = nil
48
+ config.robot.log_formatter = nil
48
49
  end
49
50
  end
50
51
 
@@ -138,6 +138,9 @@ module Lita
138
138
  end
139
139
  end
140
140
  end
141
+ config :log_formatter, type: Proc, default: (lambda do |severity, datetime, _progname, msg|
142
+ "[#{datetime.utc}] #{severity}: #{msg}\n"
143
+ end)
141
144
  config :admins
142
145
  config :error_handler, default: -> (_error) {} do
143
146
  validate do |value|
@@ -6,12 +6,10 @@ module Lita
6
6
  # severity level and a custom format.
7
7
  # @param level [Symbol, String] The name of the log level to use.
8
8
  # @return [::Logger] The {::Logger} object.
9
- def get_logger(level)
9
+ def get_logger(level, formatter = Lita.config.robot.log_formatter)
10
10
  logger = ::Logger.new(STDERR)
11
11
  logger.level = get_level_constant(level)
12
- logger.formatter = proc do |severity, datetime, _progname, msg|
13
- "[#{datetime.utc}] #{severity}: #{msg}\n"
14
- end
12
+ logger.formatter = formatter
15
13
  logger
16
14
  end
17
15
 
@@ -19,11 +19,11 @@ module Lita
19
19
 
20
20
  # @!method args
21
21
  # @see Lita::Message#args
22
- # @!method reply
22
+ # @!method reply(*strings)
23
23
  # @see Lita::Message#reply
24
- # @!method reply_privately
24
+ # @!method reply_privately(*strings)
25
25
  # @see Lita::Message#reply_privately
26
- # @!method reply_with_mention
26
+ # @!method reply_with_mention(*strings)
27
27
  # @see Lita::Message#reply_with_mention
28
28
  # @!method user
29
29
  # @see Lita::Message#user
@@ -36,6 +36,11 @@ module Lita
36
36
 
37
37
  def_delegators :registry, :config, :adapters, :handlers, :hooks
38
38
 
39
+ # @!method mention_format(name)
40
+ # @see Lita::Adapter#mention_format
41
+ # @since 4.4.0
42
+ def_delegators :adapter, :mention_format
43
+
39
44
  # @param registry [Lita::Registry] The registry for the robot's configuration and plugins.
40
45
  def initialize(registry = Lita)
41
46
  @registry = registry
@@ -44,7 +49,7 @@ module Lita
44
49
  @alias = config.robot.alias
45
50
  @app = RackApp.build(self)
46
51
  @auth = Authorization.new(config)
47
- trigger(:loaded)
52
+ trigger(:loaded, room_ids: persisted_rooms)
48
53
  end
49
54
 
50
55
  # The primary entry point from the adapter for an incoming message.
@@ -76,6 +81,7 @@ module Lita
76
81
  # @return [void]
77
82
  # @since 3.0.0
78
83
  def join(room_id)
84
+ Lita.redis.sadd("persisted_rooms", room_id)
79
85
  adapter.join(room_id)
80
86
  end
81
87
 
@@ -84,6 +90,7 @@ module Lita
84
90
  # @return [void]
85
91
  # @since 3.0.0
86
92
  def part(room_id)
93
+ Lita.redis.srem("persisted_rooms", room_id)
87
94
  adapter.part(room_id)
88
95
  end
89
96
 
@@ -172,6 +179,11 @@ module Lita
172
179
  adapter_class.new(self)
173
180
  end
174
181
 
182
+ # A list of room IDs the robot should join.
183
+ def persisted_rooms
184
+ Lita.redis.smembers("persisted_rooms").sort
185
+ end
186
+
175
187
  # Starts the web server.
176
188
  def run_app
177
189
  http_config = config.http
@@ -0,0 +1,113 @@
1
+ module Lita
2
+ # A room in the chat service. Persisted in Redis.
3
+ # @since 4.4.0
4
+ class Room
5
+ class << self
6
+ # Creates a new room with the given ID, or merges and saves supplied
7
+ # metadata to a room with the given ID.
8
+ # @param id [Integer, String] A unique identifier for the room.
9
+ # @param metadata [Hash] An optional hash of metadata about the room.
10
+ # @option metadata [String] name (id) The display name of the room.
11
+ # @return [Lita::Room] The room.
12
+ def create_or_update(id, metadata = {})
13
+ existing_room = find_by_id(id)
14
+ metadata = Util.stringify_keys(metadata)
15
+ metadata = existing_room.metadata.merge(metadata) if existing_room
16
+ room = new(id, metadata)
17
+ room.save
18
+ room
19
+ end
20
+
21
+ # Finds a room by ID.
22
+ # @param id [Integer, String] The room's unique ID.
23
+ # @return [Lita::Room, nil] The room or +nil+ if no such room is known.
24
+ def find_by_id(id)
25
+ metadata = redis.hgetall("id:#{id}")
26
+ new(id, metadata) if metadata.key?("name")
27
+ end
28
+
29
+ # Finds a room by display name.
30
+ # @param name [String] The room's name.
31
+ # @return [Lita::Room, nil] The room or +nil+ if no such room is known.
32
+ def find_by_name(name)
33
+ id = redis.get("name:#{name}")
34
+ find_by_id(id) if id
35
+ end
36
+
37
+ # Finds a room by ID or name
38
+ # @param identifier [Integer, String] The room's ID or name.
39
+ # @return [Lita::Room, nil] The room or +nil+ if no room was found.
40
+ def fuzzy_find(identifier)
41
+ find_by_id(identifier) || find_by_name(identifier)
42
+ end
43
+
44
+ # The +Redis::Namespace+ for room persistence.
45
+ # @return [Redis::Namespace] The Redis connection.
46
+ def redis
47
+ @redis ||= Redis::Namespace.new("rooms", redis: Lita.redis)
48
+ end
49
+ end
50
+
51
+ # The room's unique ID.
52
+ # @return [String] The room's ID.
53
+ attr_reader :id
54
+
55
+ # A hash of arbitrary metadata about the room.
56
+ # @return [Hash] The room's metadata.
57
+ attr_reader :metadata
58
+
59
+ # The room's name as displayed in a standard user interface.
60
+ # @return [String] The room's name.
61
+ attr_reader :name
62
+
63
+ # @param id [Integer, String] The room's unique ID.
64
+ # @param metadata [Hash] Arbitrary room metadata.
65
+ # @option metadata [String] name (id) The room's display name.
66
+ def initialize(id, metadata = {})
67
+ @id = id.to_s
68
+ @metadata = Util.stringify_keys(metadata)
69
+ @name = @metadata["name"] || @id
70
+ end
71
+
72
+ # Compares the room against another room object to determine equality. Rooms
73
+ # are considered equal if they have the same ID.
74
+ # @param other (Lita::Room) The room to compare against.
75
+ # @return [Boolean] True if rooms are equal, false otherwise.
76
+ def ==(other)
77
+ other.respond_to?(:id) && id == other.id
78
+ end
79
+ alias_method :eql?, :==
80
+
81
+ # Generates a +Fixnum+ hash value for this user object. Implemented to support equality.
82
+ # @return [Fixnum] The hash value.
83
+ # @see Object#hash
84
+ def hash
85
+ id.hash
86
+ end
87
+
88
+ # Saves the room record to Redis, overwriting any previous data for the current ID.
89
+ # @return [void]
90
+ def save
91
+ ensure_name_metadata_set
92
+
93
+ redis.pipelined do
94
+ redis.hmset("id:#{id}", *metadata.to_a.flatten)
95
+ redis.set("name:#{name}", id)
96
+ end
97
+ end
98
+
99
+ private
100
+
101
+ # Ensure the room's metadata contains its name, to ensure their Redis hash contains at least
102
+ # one value. It's not possible to store an empty hash key in Redis.
103
+ def ensure_name_metadata_set
104
+ room_name = metadata.delete("name")
105
+ metadata["name"] = room_name || id
106
+ end
107
+
108
+ # The Redis connection for room persistence.
109
+ def redis
110
+ self.class.redis
111
+ end
112
+ end
113
+ end
@@ -12,24 +12,38 @@ module Lita
12
12
  attr_reader :private_message
13
13
  alias_method :private_message?, :private_message
14
14
 
15
- # The room the message came from or should be sent to.
16
- # @return [String] A string uniquely identifying the room.
15
+ # The room the message came from or should be sent to, as a string.
16
+ # @return [String, NilClass] A string uniquely identifying the room.
17
17
  attr_reader :room
18
18
 
19
+ # The room the message came from or should be sent to, as a {Lita::Room} object.
20
+ # @return [Lita::Room, NilClass] The room.
21
+ # @since 4.4.0
22
+ attr_reader :room_object
23
+
19
24
  # The user who sent the message or should receive the outgoing message.
20
- # @return [Lita::User] The user.
25
+ # @return [Lita::User, NilClass] The user.
21
26
  attr_reader :user
22
27
 
23
28
  # @param user [Lita::User] The user who sent the message or should receive
24
29
  # the outgoing message.
25
- # @param room [String] A string uniquely identifying the room the user sent
26
- # the message from, or the room where a reply should go. The format of
27
- # this string will differ depending on the chat service.
30
+ # @param room [Lita::Room, String] A string or {Lita::Room} uniquely identifying the room
31
+ # the user sent the message from, or the room where a reply should go. The format of this
32
+ # string (or the ID of the {Lita::Room} object) will differ depending on the chat service.
28
33
  # @param private_message [Boolean] A flag indicating whether or not the
29
34
  # message was sent privately.
30
35
  def initialize(user: nil, room: nil, private_message: false)
31
36
  @user = user
32
- @room = room
37
+
38
+ case room
39
+ when String
40
+ @room = room
41
+ @room_object = Room.new(room)
42
+ when Room
43
+ @room = room.id
44
+ @room_object = room
45
+ end
46
+
33
47
  @private_message = private_message
34
48
 
35
49
  raise ArgumentError, I18n.t("lita.source.user_or_room_required") if user.nil? && room.nil?
@@ -14,7 +14,7 @@ module Lita
14
14
 
15
15
  # Returns the adapter-specific template, falling back to a generic template.
16
16
  # @return [String] The path of the template to use.
17
- # @raises [MissingTemplateError] If no templates with the given name exist.
17
+ # @raise [MissingTemplateError] If no templates with the given name exist.
18
18
  def resolve
19
19
  return adapter_template if File.exist?(adapter_template)
20
20
  return generic_template if File.exist?(generic_template)
@@ -100,7 +100,7 @@ module Lita
100
100
  metadata["mention_name"] || name
101
101
  end
102
102
 
103
- # Saves the user record to Redis, overwriting an previous data for the
103
+ # Saves the user record to Redis, overwriting any previous data for the
104
104
  # current ID and user name.
105
105
  # @return [void]
106
106
  def save
@@ -122,9 +122,11 @@ module Lita
122
122
  end
123
123
  alias_method :eql?, :==
124
124
 
125
+ # Generates a +Fixnum+ hash value for this user object. Implemented to support equality.
126
+ # @return [Fixnum] The hash value.
127
+ # @see Object#hash
125
128
  def hash
126
- id.hash ^
127
- name.hash
129
+ id.hash ^ name.hash
128
130
  end
129
131
 
130
132
  private
@@ -1,4 +1,4 @@
1
1
  module Lita
2
2
  # The current version of Lita.
3
- VERSION = "4.3.2"
3
+ VERSION = "4.4.0"
4
4
  end
@@ -3,7 +3,7 @@ require "spec_helper"
3
3
  describe Lita::Adapter, lita: true do
4
4
  let(:robot) { Lita::Robot.new(registry) }
5
5
 
6
- let(:required_methods) { [:join, :part, :run, :send_messages, :set_topic, :shut_down] }
6
+ let(:required_methods) { described_class::REQUIRED_METHODS }
7
7
 
8
8
  subject { described_class.new(robot) }
9
9
 
@@ -13,6 +13,14 @@ describe Lita::Adapters::Shell, lita: true do
13
13
 
14
14
  subject { described_class.new(robot) }
15
15
 
16
+ describe "#roster" do
17
+ let(:room) { instance_double("Lita::Room") }
18
+
19
+ it "returns the shell user" do
20
+ expect(subject.roster(room).first.name).to eq("Shell User")
21
+ end
22
+ end
23
+
16
24
  describe "#run" do
17
25
  let(:user) { Lita::User.create(1, name: "Shell User") }
18
26
 
@@ -6,10 +6,22 @@ describe Lita::Robot, lita: true do
6
6
  before { registry.register_adapter(:shell, Lita::Adapters::Shell) }
7
7
 
8
8
  it "triggers a loaded event after initialization" do
9
- expect_any_instance_of(described_class).to receive(:trigger).with(:loaded)
9
+ expect_any_instance_of(described_class).to receive(:trigger).with(:loaded, room_ids: [])
10
10
  subject
11
11
  end
12
12
 
13
+ context "when there are previously persisted rooms" do
14
+ before { %w(#foo #bar).each { |id| Lita.redis.sadd("persisted_rooms", id) } }
15
+
16
+ it "receives the room_ids in the payload" do
17
+ expect_any_instance_of(described_class).to receive(:trigger).with(
18
+ :loaded,
19
+ room_ids: %w(#foo #bar).sort,
20
+ )
21
+ subject
22
+ end
23
+ end
24
+
13
25
  it "can have its name changed" do
14
26
  subject.name = "Bongo"
15
27
 
@@ -22,6 +34,10 @@ describe Lita::Robot, lita: true do
22
34
  expect(subject.mention_name).to eq("wongo")
23
35
  end
24
36
 
37
+ it "exposes Adapter#mention_format" do
38
+ expect(subject.mention_format(subject.mention_name)).to eq("Lita:")
39
+ end
40
+
25
41
  context "with registered handlers" do
26
42
  let(:handler1) { Class.new(Lita::Handler) { namespace :test } }
27
43
  let(:handler2) { Class.new(Lita::Handler) { namespace :test } }
@@ -102,17 +118,40 @@ describe Lita::Robot, lita: true do
102
118
  end
103
119
 
104
120
  describe "#join" do
121
+ before do
122
+ allow_any_instance_of(Lita::Adapters::Shell).to receive(:join)
123
+ end
124
+
105
125
  it "delegates to the adapter" do
106
126
  expect_any_instance_of(Lita::Adapters::Shell).to receive(:join).with("#lita.io")
107
127
  subject.join("#lita.io")
108
128
  end
129
+
130
+ it "adds the room ID to the persisted list" do
131
+ subject.join("#lita.io")
132
+
133
+ expect(Lita.redis.smembers("persisted_rooms")).to include("#lita.io")
134
+ end
109
135
  end
110
136
 
111
137
  describe "#part" do
138
+ before do
139
+ allow_any_instance_of(Lita::Adapters::Shell).to receive(:join)
140
+ allow_any_instance_of(Lita::Adapters::Shell).to receive(:part)
141
+ end
142
+
112
143
  it "delegates to the adapter" do
113
144
  expect_any_instance_of(Lita::Adapters::Shell).to receive(:part).with("#lita.io")
114
145
  subject.part("#lita.io")
115
146
  end
147
+
148
+ it "removes the room ID from the persisted list" do
149
+ subject.join("#lita.io")
150
+
151
+ subject.part("#lita.io")
152
+
153
+ expect(Lita.redis.smembers("persisted_rooms")).not_to include("#lita.io")
154
+ end
116
155
  end
117
156
 
118
157
  describe "#send_message" do
@@ -0,0 +1,134 @@
1
+ require "spec_helper"
2
+
3
+ describe Lita::Room, lita: true do
4
+ describe ".create_or_update" do
5
+ subject { described_class.find_by_id(1) }
6
+
7
+ context "when no room with the given ID already exists" do
8
+ it "creates the room" do
9
+ described_class.create_or_update(1, name: "foo")
10
+
11
+ expect(subject.name).to eq("foo")
12
+ end
13
+ end
14
+
15
+ context "when a room with the given ID already exists" do
16
+ before { described_class.create_or_update(1, name: "foo") }
17
+
18
+ it "merges in new metadata" do
19
+ described_class.create_or_update(1, foo: "bar")
20
+
21
+ expect(subject.name).to eq("foo")
22
+ expect(subject.metadata["foo"]).to eq("bar")
23
+ end
24
+ end
25
+ end
26
+
27
+ describe ".find_by_id" do
28
+ context "when a matching room exists" do
29
+ before { described_class.new(1).save }
30
+
31
+ it "is found by ID" do
32
+ expect(described_class.find_by_id(1).id).to eq("1")
33
+ end
34
+ end
35
+
36
+ context "when no matching room exists" do
37
+ it "is not found" do
38
+ expect(described_class.find_by_id(1)).to be_nil
39
+ end
40
+ end
41
+ end
42
+
43
+ describe ".find_by_name" do
44
+ context "when a matching room exists" do
45
+ before { described_class.new(1, name: "foo").save }
46
+
47
+ it "is found by name" do
48
+ expect(described_class.find_by_name("foo").id).to eq("1")
49
+ end
50
+ end
51
+
52
+ context "when no matching room exists" do
53
+ it "is not found" do
54
+ expect(described_class.find_by_name("foo")).to be_nil
55
+ end
56
+ end
57
+ end
58
+
59
+ describe ".fuzzy_find" do
60
+ context "when a matching room exists" do
61
+ before { described_class.new(1, name: "foo").save }
62
+
63
+ it "is found by ID" do
64
+ expect(described_class.fuzzy_find(1).id).to eq("1")
65
+ end
66
+
67
+ it "is found by name" do
68
+ expect(described_class.fuzzy_find("foo").id).to eq("1")
69
+ end
70
+ end
71
+
72
+ context "when no matching room exists" do
73
+ it "is not found by ID" do
74
+ expect(described_class.fuzzy_find(1)).to be_nil
75
+ end
76
+
77
+ it "is not found by name" do
78
+ expect(described_class.fuzzy_find("foo")).to be_nil
79
+ end
80
+ end
81
+ end
82
+
83
+ context "with only an ID" do
84
+ subject { described_class.new(1) }
85
+
86
+ it "has a string ID" do
87
+ expect(subject.id).to eq("1")
88
+ end
89
+
90
+ it "is named with its ID" do
91
+ expect(subject.name).to eq("1")
92
+ end
93
+ end
94
+
95
+ context "with metadata" do
96
+ subject { described_class.new(1, foo: :bar) }
97
+
98
+ it "stores the metadata with string keys" do
99
+ expect(subject.metadata["foo"]).to eq(:bar)
100
+ end
101
+ end
102
+
103
+ describe "#==" do
104
+ subject { described_class.new(1) }
105
+
106
+ context "when the other room has the same ID" do
107
+ let(:other) { described_class.new(1) }
108
+
109
+ it "is equal" do
110
+ expect(subject).to eq(other)
111
+ end
112
+ end
113
+
114
+ context "when the other room has a different ID" do
115
+ let(:other) { described_class.new(2) }
116
+
117
+ it "is not equal" do
118
+ expect(subject).not_to eq(other)
119
+ end
120
+ end
121
+ end
122
+
123
+ describe "#save" do
124
+ context "with metadata not including name" do
125
+ subject { described_class.new(1, {}) }
126
+
127
+ it "adds the name to the metadata" do
128
+ subject.save
129
+
130
+ expect(subject.metadata["name"]).to eq("1")
131
+ end
132
+ end
133
+ end
134
+ end
@@ -1,27 +1,56 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Lita::Source do
4
- it "has a user" do
5
- subject = described_class.new(user: "Carl")
6
- expect(subject.user).to eq("Carl")
4
+ subject { described_class.new(user: user, room: room, private_message: pm) }
5
+
6
+ let(:pm) { false }
7
+ let(:room) { Lita::Room.new(1) }
8
+ let(:user) { Lita::User.new(1) }
9
+
10
+ describe "#room" do
11
+ it "returns the room as a string" do
12
+ expect(subject.room).to eq("1")
13
+ end
7
14
  end
8
15
 
9
- it "has a room" do
10
- subject = described_class.new(room: "#litabot")
11
- expect(subject.room).to eq("#litabot")
16
+ describe "#room_object" do
17
+ it "returns the room as a Lita::Room" do
18
+ expect(subject.room_object).to eq(room)
19
+ end
12
20
  end
13
21
 
14
- it "has a private message flag" do
15
- subject = described_class.new(user: "Carl", private_message: true)
16
- expect(subject).to be_a_private_message
22
+ describe "#user" do
23
+ it "returns the user object" do
24
+ expect(subject.user).to eq(user)
25
+ end
26
+ end
27
+
28
+ context "when the private_message argument is true" do
29
+ let(:pm) { true }
30
+
31
+ it "is marked as a private message" do
32
+ expect(subject).to be_a_private_message
33
+ end
17
34
  end
18
35
 
19
36
  it "can be manually marked as private" do
20
- subject = described_class.new(user: "Carl", room: "#litabot")
21
37
  subject.private_message!
38
+
22
39
  expect(subject).to be_a_private_message
23
40
  end
24
41
 
42
+ context "with a string for the room argument" do
43
+ let(:room) { "#channel" }
44
+
45
+ it "sets #room to the string" do
46
+ expect(subject.room).to eq(room)
47
+ end
48
+
49
+ it "sets #room_object to a Lita::Room with the string as its ID" do
50
+ expect(subject.room_object).to eq(Lita::Room.new(room))
51
+ end
52
+ end
53
+
25
54
  it "requires either a user or a room" do
26
55
  expect { described_class.new }.to raise_error(ArgumentError)
27
56
  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.3.2
4
+ version: 4.4.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-04-03 00:00:00.000000000 Z
11
+ date: 2015-06-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -315,6 +315,7 @@ files:
315
315
  - lib/lita/registry.rb
316
316
  - lib/lita/response.rb
317
317
  - lib/lita/robot.rb
318
+ - lib/lita/room.rb
318
319
  - lib/lita/route_validator.rb
319
320
  - lib/lita/rspec.rb
320
321
  - lib/lita/rspec/handler.rb
@@ -354,6 +355,7 @@ files:
354
355
  - spec/lita/plugin_builder_spec.rb
355
356
  - spec/lita/response_spec.rb
356
357
  - spec/lita/robot_spec.rb
358
+ - spec/lita/room_spec.rb
357
359
  - spec/lita/rspec/handler_spec.rb
358
360
  - spec/lita/rspec_spec.rb
359
361
  - spec/lita/source_spec.rb
@@ -431,6 +433,7 @@ test_files:
431
433
  - spec/lita/plugin_builder_spec.rb
432
434
  - spec/lita/response_spec.rb
433
435
  - spec/lita/robot_spec.rb
436
+ - spec/lita/room_spec.rb
434
437
  - spec/lita/rspec/handler_spec.rb
435
438
  - spec/lita/rspec_spec.rb
436
439
  - spec/lita/source_spec.rb