lita 4.3.2 → 4.4.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: 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