lita 4.0.0.rc1 → 4.0.0.rc2

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: 6aba9ae845dbe0d8fcbeedca12735d4cde375b44
4
- data.tar.gz: 7afcedf903295c434f39390884c7f7fe8465c181
3
+ metadata.gz: a4833eb0b401c3fed770490aeea4e4658283b83a
4
+ data.tar.gz: ea7f7f1d2f9257719d5903f918ff11c191454d54
5
5
  SHA512:
6
- metadata.gz: 174c6be0c949ee3fd83753348d65c862b6313b5f77164b6c6b928946524e1913adbd07c886f352ce9daedc19e8243a5016bb623e352701e8bfdc369ac1f9aa26
7
- data.tar.gz: ce15b54ce11d9efcb90b6b6db82a246625d6b38154db75fdac127629ef1a60892e60e0a607d31d1853a539538d781285d89fbd22557ac1fef8d5dc67e623b823
6
+ metadata.gz: 6dadeb4bc8cdaa18443b15dc48b031562a427c5f1c542b049ba98c3dc73177704454145e6c1be9ac2f7f14a26bd9867495371787230f2c213d4dbf280f306146
7
+ data.tar.gz: 73e4d441468ab549074f5dbfdf8cc2b2c7b2c9edf81aa91d1907d8bb82587ea38057eec060e78a99b64e1d25216780470bbc46efdf414e1c12ac5b37fbe736b4
data/.rubocop.yml CHANGED
@@ -18,6 +18,8 @@ LineLength:
18
18
  Max: 100
19
19
  MethodLength:
20
20
  Enabled: false
21
+ NonNilCheck:
22
+ Enabled: false
21
23
  RegexpLiteral:
22
24
  Enabled: false
23
25
  RescueException:
data/lib/lita.rb CHANGED
@@ -68,8 +68,8 @@ module Lita
68
68
  # @return [void]
69
69
  def run(config_path = nil)
70
70
  hooks[:before_run].each { |hook| hook.call(config_path: config_path) }
71
- Configuration.load_user_config(config_path)
72
- Configuration.freeze_config(config)
71
+ ConfigurationBuilder.load_user_config(config_path)
72
+ ConfigurationBuilder.freeze_config(config)
73
73
  ConfigurationValidator.new(self).call
74
74
  self.locale = config.robot.locale
75
75
  Robot.new.run
@@ -81,7 +81,7 @@ require_relative "lita/version"
81
81
  require_relative "lita/common"
82
82
  require_relative "lita/errors"
83
83
  require_relative "lita/config"
84
- require_relative "lita/configuration"
84
+ require_relative "lita/configuration_builder"
85
85
  require_relative "lita/default_configuration"
86
86
  require_relative "lita/configuration_validator"
87
87
  require_relative "lita/util"
@@ -106,7 +106,7 @@ require_relative "lita/timer"
106
106
  require_relative "lita/robot"
107
107
  require_relative "lita/adapter"
108
108
  require_relative "lita/adapters/shell"
109
- require_relative "lita/builder"
109
+ require_relative "lita/plugin_builder"
110
110
  require_relative "lita/route_validator"
111
111
  require_relative "lita/handlers/authorization"
112
112
  require_relative "lita/handlers/help"
data/lib/lita/adapter.rb CHANGED
@@ -12,7 +12,7 @@ module Lita
12
12
  # @!attribute [r] required_configs
13
13
  # A list of configuration keys that are required for the adapter to boot.
14
14
  # @return [Array]
15
- # @deprecated Will be removed in Lita 5.0. Use {Lita::Adapter#configuration} instead.
15
+ # @deprecated Will be removed in Lita 5.0. Use {Lita::Adapter#configuration_builder} instead.
16
16
  def required_configs
17
17
  Lita.logger.warn(I18n.t("lita.adapter.required_configs_deprecated"))
18
18
  @required_configs
@@ -46,7 +46,7 @@ module Lita
46
46
  ensure_required_configs
47
47
  end
48
48
  #
49
- # The handler's config object.
49
+ # The adapter's configuration object.
50
50
  # @return [Lita::Configuration] The adapter's configuration object.
51
51
  # @since 4.0.0
52
52
  def config
@@ -117,7 +117,7 @@ module Lita
117
117
 
118
118
  private
119
119
 
120
- # Returns the object used for the adapter's config.
120
+ # Returns the object used as the adapter's configuration.
121
121
  def adapter_config
122
122
  if Lita.version_3_compatibility_mode?
123
123
  Lita.config.adapter
@@ -147,6 +147,7 @@ module Lita
147
147
  end
148
148
  end
149
149
 
150
+ # Access the required configs without triggering the deprecation warning.
150
151
  def required_configs
151
152
  self.class.instance_variable_get(:@required_configs)
152
153
  end
@@ -1,7 +1,7 @@
1
1
  module Lita
2
2
  # Methods for querying and manipulating authorization groups.
3
3
  class Authorization
4
- # @param config [Object] The finalized configuration object for the currently running robot.
4
+ # @param config [Lita::Configuration] The configuration object of the currently running robot.
5
5
  def initialize(config)
6
6
  @config = config
7
7
  end
data/lib/lita/config.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Lita
2
2
  # An object that stores various user settings that affect Lita's behavior.
3
- # @deprecated Will be removed in Lita 5.0. Use {Lita::Configuration} instead.
3
+ # @deprecated Will be removed in Lita 5.0. Use {Lita::ConfigurationBuilder} instead.
4
4
  class Config < Hash
5
5
  class << self
6
6
  # Initializes a new Config object with the default settings.
@@ -3,27 +3,27 @@ module Lita
3
3
  # @since 4.0.0
4
4
  # @api private
5
5
  module Configurable
6
- # The plugins's {Configuration} object.
7
- # @return [Lita::Configuration] The configuration object.
6
+ # The plugins's {Lita::ConfigurationBuilder} object.
7
+ # @return [Lita::ConfigurationBuilder] The configuration builder.
8
8
  # @since 4.0.0
9
- attr_accessor :configuration
9
+ attr_accessor :configuration_builder
10
10
 
11
11
  # Sets a configuration attribute on the plugin.
12
12
  # @return [void]
13
13
  # @since 4.0.0
14
- # @see Lita::Configuration#config
14
+ # @see Lita::ConfigurationBuilder#config
15
15
  def config(*args, **kwargs)
16
16
  if block_given?
17
- configuration.config(*args, **kwargs, &proc)
17
+ configuration_builder.config(*args, **kwargs, &proc)
18
18
  else
19
- configuration.config(*args, **kwargs)
19
+ configuration_builder.config(*args, **kwargs)
20
20
  end
21
21
  end
22
22
 
23
- # Initializes the configuration object for any inheriting classes.
23
+ # Initializes the configuration builder for any inheriting classes.
24
24
  def inherited(klass)
25
25
  super
26
- klass.configuration = Configuration.new
26
+ klass.configuration_builder = ConfigurationBuilder.new
27
27
  end
28
28
  end
29
29
  end
@@ -1,9 +1,13 @@
1
1
  module Lita
2
- # An object that stores various settings that affect Lita's behavior.
2
+ # An object that stores user settings to control Lita's behavior.
3
3
  # @since 4.0.0
4
- class Configuration
5
- # An array of any nested configuration objects.
6
- # @return [Array<Lita::Configuration>] The array of child configuration objects.
4
+ class Configuration; end
5
+
6
+ # Provides a DSL for building {Lita::Configuration} objects.
7
+ # @since 4.0.0
8
+ class ConfigurationBuilder
9
+ # An array of any nested configuration builders.
10
+ # @return [Array<Lita::ConfigurationBuilder>] The array of child configuration builders.
7
11
  attr_reader :children
8
12
 
9
13
  # An array of valid types for the attribute.
@@ -59,15 +63,30 @@ module Lita
59
63
  @name = :root
60
64
  end
61
65
 
66
+ # Builds a {Lita::Configuration} object from the attributes defined on the builder.
67
+ # @param object [Lita::Configuration] The empty configuration object that will be extended to
68
+ # create the final form.
69
+ # @return [Lita::Confirmation] The fully built configuration object.
70
+ def build(object = Configuration.new)
71
+ container = if children.empty?
72
+ build_leaf(object)
73
+ else
74
+ build_nested(object)
75
+ end
76
+
77
+ container.public_send(name)
78
+ end
79
+
62
80
  # Returns a boolean indicating whether or not the attribute has any child attributes.
63
81
  # @return [Boolean] Whether or not the attribute has any child attributes.
64
82
  def children?
65
83
  !children.empty?
66
84
  end
67
85
 
68
- # Merges two configuration objects by making one an attribute on the other.
86
+ # Merges two configuration builders by making one an attribute on the other.
69
87
  # @param name [String, Symbol] The name of the new attribute.
70
- # @param attribute [Lita::Configuration] The configuration object that should be its value.
88
+ # @param attribute [Lita::ConfigurationBuilder] The configuration builder that should be its
89
+ # value.
71
90
  # @return [void]
72
91
  def combine(name, attribute)
73
92
  attribute.name = name
@@ -82,7 +101,7 @@ module Lita
82
101
  # @param type [Object, Array<Object>] Optional: One or more types that the attribute's value
83
102
  # must be.
84
103
  # @param required [Boolean] Whether or not this attribute must be set. If required, and Lita
85
- # is run without it set, a {Lita::ValidationError} will be raised.
104
+ # is run without it set, Lita will abort on start up with a message about it.
86
105
  # @param default [Object] An optional default value for the attribute.
87
106
  # @yield A block to be evaluated in the context of the new attribute. Used for
88
107
  # defining nested configuration attributes and validators.
@@ -98,20 +117,6 @@ module Lita
98
117
  children << attribute
99
118
  end
100
119
 
101
- # Extracts the finalized configuration object as it will be interacted with by the user.
102
- # @param object [Object] The bare object that will be extended to create the final form.
103
- # @return [Object] A bare object with only the methods that were declared via the
104
- # {Lita::Configuration} DSL.
105
- def finalize(object = Object.new)
106
- container = if children.empty?
107
- finalize_simple(object)
108
- else
109
- finalize_nested(object)
110
- end
111
-
112
- container.public_send(name)
113
- end
114
-
115
120
  # Sets the valid types for the configuration attribute.
116
121
  # @param types [Object, Array<Object>] One or more valid types.
117
122
  # @return [void]
@@ -125,6 +130,13 @@ module Lita
125
130
  # @yield The code that performs validation.
126
131
  # @return [void]
127
132
  def validate
133
+ validator = proc
134
+
135
+ unless value.nil?
136
+ error = validator.call(value)
137
+ raise ValidationError, error if error
138
+ end
139
+
128
140
  @validator = proc
129
141
  end
130
142
 
@@ -133,47 +145,71 @@ module Lita
133
145
  # @return [void]
134
146
  # @raise [TypeError] If the new value is not among the declared valid types.
135
147
  def value=(value)
136
- if value && types && types.none? { |type| type === value }
137
- raise TypeError, "#{name} must be one of: #{types.inspect}"
138
- end
148
+ ensure_valid_default_value(value)
139
149
 
140
150
  @value = value
141
151
  end
142
152
 
143
153
  private
144
154
 
145
- # Finalize the root object.
146
- def finalize_nested(object)
155
+ # Finalize a nested object.
156
+ def build_leaf(object)
147
157
  this = self
158
+ run_validator = method(:run_validator)
159
+ check_types = method(:check_types)
148
160
 
149
- nested_object = Object.new
150
- children.each { |child| child.finalize(nested_object) }
151
- object.instance_exec { define_singleton_method(this.name) { nested_object } }
161
+ object.instance_exec do
162
+ define_singleton_method(this.name) { this.value }
163
+ define_singleton_method("#{this.name}=") do |value|
164
+ run_validator.call(value)
165
+ check_types.call(value)
166
+ this.value = value
167
+ end
168
+ end
152
169
 
153
170
  object
154
171
  end
155
172
 
156
- # Finalize a nested object.
157
- def finalize_simple(object)
173
+ # Finalize the root builder or any builder with children.
174
+ def build_nested(object)
158
175
  this = self
159
176
 
160
- object.instance_exec do
161
- define_singleton_method(this.name) { this.value }
162
- define_singleton_method("#{this.name}=") do |value|
163
- if this.validator
164
- error = this.validator.call(value)
165
- raise ValidationError, error if error
166
- end
177
+ nested_object = Configuration.new
178
+ children.each { |child| child.build(nested_object) }
179
+ object.instance_exec { define_singleton_method(this.name) { nested_object } }
180
+
181
+ object
182
+ end
167
183
 
168
- if this.types && this.types.none? { |type| type === value }
169
- raise TypeError, "#{this.name} must be one of: #{this.types.inspect}"
170
- end
184
+ # Check's the value's type from inside the finalized object.
185
+ def check_types(value)
186
+ if types && types.none? { |type| type === value }
187
+ Lita.logger.fatal(
188
+ I18n.t("lita.config.type_error", attribute: name, types: types.join(", "))
189
+ )
190
+ abort
191
+ end
192
+ end
171
193
 
172
- this.value = value
173
- end
194
+ # Raise if value is non-nil and isn't one of the specified types.
195
+ def ensure_valid_default_value(value)
196
+ if !value.nil? && types && types.none? { |type| type === value }
197
+ raise TypeError, I18n.t("lita.config.type_error", attribute: name, types: types.join(", "))
174
198
  end
199
+ end
175
200
 
176
- object
201
+ # Runs the validator from inside the build configuration object.
202
+ def run_validator(value)
203
+ return unless validator
204
+
205
+ error = validator.call(value)
206
+
207
+ if error
208
+ Lita.logger.fatal(
209
+ I18n.t("lita.config.validation_error", attribute: name, message: error)
210
+ )
211
+ abort
212
+ end
177
213
  end
178
214
  end
179
215
  end
@@ -8,9 +8,9 @@ module Lita
8
8
  @registry = registry
9
9
  end
10
10
 
11
- # Validates adapter and handler configuration.
11
+ # Validates adapter and handler configuration. Logs a fatal warning and aborts if any required
12
+ # configuration attributes are missing.
12
13
  # @return [void]
13
- # @raise [Lita::ValidationError] If any required configuration attributes are missing.
14
14
  def call
15
15
  validate_adapters
16
16
  validate_handlers
@@ -25,7 +25,7 @@ module Lita
25
25
 
26
26
  # All a plugin's top-level configuration attributes.
27
27
  def children_for(plugin)
28
- plugin.configuration.children
28
+ plugin.configuration_builder.children
29
29
  end
30
30
 
31
31
  # Generates the fully qualified name of a configuration attribute.
@@ -54,11 +54,12 @@ module Lita
54
54
  if attribute.children?
55
55
  validate(type, plugin, attribute.children, attribute_namespace.clone.push(attribute.name))
56
56
  elsif attribute.required? && attribute.value.nil?
57
- raise ValidationError, I18n.t(
57
+ Lita.logger.fatal I18n.t(
58
58
  "lita.config.missing_required_#{type}_attribute",
59
59
  type => plugin.namespace,
60
60
  attribute: full_attribute_name(attribute_namespace, attribute.name)
61
61
  )
62
+ abort
62
63
  end
63
64
  end
64
65
  end
@@ -10,14 +10,14 @@ module Lita
10
10
  # @return [Lita::Registry] The registry.
11
11
  attr_reader :registry
12
12
 
13
- # The top-level {Configuration} attribute.
13
+ # The top-level {Lita::ConfigurationBuilder} attribute.
14
14
  # @return [Lita::Configuration] The root attribute.
15
15
  attr_reader :root
16
16
 
17
17
  # @param registry [Lita::Registry] The registry to build a default configuration object from.
18
18
  def initialize(registry)
19
19
  @registry = registry
20
- @root = Configuration.new
20
+ @root = ConfigurationBuilder.new
21
21
 
22
22
  adapters_config
23
23
  handlers_config
@@ -26,11 +26,10 @@ module Lita
26
26
  robot_config
27
27
  end
28
28
 
29
- # Processes the {Configuration} object to return a raw object with only the appropriate methods.
30
- # This is the value that's actually stored in {Lita::Registry#config}.
31
- # @return [Object] The final form of the configuration object.
32
- def finalize
33
- final_config = root.finalize
29
+ # Processes the {Lita::ConfigurationBuilder} object to return a {Lita:Configuration}.
30
+ # @return [Lita::Configuration] The built configuration object.
31
+ def build
32
+ final_config = root.build
34
33
  add_adapter_attribute(final_config)
35
34
  add_struct_access_to_redis(final_config.redis)
36
35
  final_config
@@ -44,7 +43,7 @@ module Lita
44
43
 
45
44
  root.config :adapters do
46
45
  adapters.each do |key, adapter|
47
- combine(key, adapter.configuration)
46
+ combine(key, adapter.configuration_builder)
48
47
  end
49
48
  end
50
49
  end
@@ -97,8 +96,8 @@ module Lita
97
96
 
98
97
  root.config :handlers do
99
98
  handlers.each do |handler|
100
- if handler.configuration.children?
101
- combine(handler.namespace, handler.configuration)
99
+ if handler.configuration_builder.children?
100
+ combine(handler.namespace, handler.configuration_builder)
102
101
  else
103
102
  old_config = Config.new
104
103
  handler.default_config(old_config) if handler.respond_to?(:default_config)
@@ -112,9 +111,9 @@ module Lita
112
111
  def http_config
113
112
  root.config :http do
114
113
  config :host, type: String, default: "0.0.0.0"
115
- config :port, type: Integer, default: 8080
116
- config :min_threads, type: Integer, default: 0
117
- config :max_threads, type: Integer, default: 16
114
+ config :port, type: [Integer, String], default: 8080
115
+ config :min_threads, type: [Integer, String], default: 0
116
+ config :max_threads, type: [Integer, String], default: 16
118
117
  config :middleware, type: Array, default: []
119
118
  end
120
119
  end
@@ -135,7 +134,7 @@ module Lita
135
134
  config :log_level, types: [String, Symbol], default: :info do
136
135
  validate do |value|
137
136
  unless LOG_LEVELS.include?(value.to_s.downcase.strip)
138
- "log_level must be one of: #{LOG_LEVELS.join(", ")}"
137
+ "must be one of: #{LOG_LEVELS.join(", ")}"
139
138
  end
140
139
  end
141
140
  end
data/lib/lita/errors.rb CHANGED
@@ -3,7 +3,8 @@ module Lita
3
3
  # @since 4.0.0
4
4
  class Error < StandardError; end
5
5
 
6
- # An exception raised when a configuration attribute is invalid.
6
+ # An exception raised when a custom validation is set on a configuration attribute that is
7
+ # violated by the default value of the attribute.
7
8
  # @since 4.0.0
8
9
  class ValidationError < Error; end
9
10
  end
@@ -3,12 +3,12 @@ module Lita
3
3
  # Methods included in any class that includes at least one type of router.
4
4
  # @since 4.0.0
5
5
  module Common
6
- # Adds common functionality to the class and initializes the handler's configuration.
6
+ # Adds common functionality to the class and initializes the handler's configuration builder.
7
7
  def self.included(klass)
8
8
  klass.extend(ClassMethods)
9
9
  klass.extend(Namespace)
10
10
  klass.extend(Configurable)
11
- klass.configuration = Configuration.new
11
+ klass.configuration_builder = ConfigurationBuilder.new
12
12
  end
13
13
 
14
14
  # Common class-level methods for all handlers.
@@ -48,8 +48,8 @@ module Lita
48
48
  Thread.new { Timer.new(interval: interval, &block).start }
49
49
  end
50
50
 
51
- # The handler's config object.
52
- # @return [Object, Lita::Config] The handler's configuration object.
51
+ # The handler's configuration object.
52
+ # @return [Lita::Configuration, Lita::Config] The handler's configuration object.
53
53
  # @since 3.2.0
54
54
  def config
55
55
  if robot.config.handlers.respond_to?(self.class.namespace)
@@ -56,9 +56,9 @@ module Lita
56
56
  # @param payload [Hash] An optional hash of arbitrary data.
57
57
  # @return [Boolean] Whether or not the event triggered any callbacks.
58
58
  def trigger(robot, event_name, payload = {})
59
- event_subscriptions_for(event_name).any? do |callback|
59
+ event_subscriptions_for(event_name).map do |callback|
60
60
  callback.call(new(robot), payload)
61
- end
61
+ end.any?
62
62
  end
63
63
 
64
64
  private
@@ -2,7 +2,7 @@ module Lita
2
2
  # Constructs a Lita plugin from a block.
3
3
  # @since 4.0.0
4
4
  # @api private
5
- class Builder
5
+ class PluginBuilder
6
6
  # @param namespace [String, Symbol] The Redis namespace to use for the plugin.
7
7
  # @yield The class body of the plugin.
8
8
  def initialize(namespace, &block)
data/lib/lita/registry.rb CHANGED
@@ -5,13 +5,13 @@ module Lita
5
5
  # Allows a registry to be added to another object.
6
6
  module Mixins
7
7
  # The primary configuration object. Provides user settings for the robot.
8
- # @return [Object] The configuration object.
8
+ # @return [Lita::Configuration] The configuration object.
9
9
  def config
10
- @config ||= DefaultConfiguration.new(self).finalize
10
+ @config ||= DefaultConfiguration.new(self).build
11
11
  end
12
12
 
13
13
  # Yields the configuration object. Called by the user in a +lita_config.rb+ file.
14
- # @yieldparam [Object] config The configuration object.
14
+ # @yieldparam [Lita::Configuration] config The configuration object.
15
15
  # @return [void]
16
16
  def configure
17
17
  yield config
@@ -48,7 +48,7 @@ module Lita
48
48
  # @return [void]
49
49
  # @since 4.0.0
50
50
  def register_adapter(key, adapter = nil)
51
- adapter = Builder.new(key, &proc).build_adapter if block_given?
51
+ adapter = PluginBuilder.new(key, &proc).build_adapter if block_given?
52
52
 
53
53
  unless adapter.is_a?(Class)
54
54
  raise ArgumentError, I18n.t("lita.core.register_adapter.block_or_class_required")
@@ -69,7 +69,7 @@ module Lita
69
69
  # @since 4.0.0
70
70
  def register_handler(handler_or_key)
71
71
  if block_given?
72
- handler = Builder.new(handler_or_key, &proc).build_handler
72
+ handler = PluginBuilder.new(handler_or_key, &proc).build_handler
73
73
  else
74
74
  handler = handler_or_key
75
75
 
data/lib/lita/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Lita
2
2
  # The current version of Lita.
3
- VERSION = "4.0.0.rc1"
3
+ VERSION = "4.0.0.rc2"
4
4
  end
@@ -1,7 +1,7 @@
1
1
  require "spec_helper"
2
2
 
3
- describe Lita::Configuration do
4
- let(:config) { subject.finalize }
3
+ describe Lita::ConfigurationBuilder do
4
+ let(:config) { subject.build }
5
5
 
6
6
  describe ".load_user_config" do
7
7
  it "loads and evals lita_config.rb" do
@@ -53,7 +53,10 @@ describe Lita::Configuration do
53
53
  end
54
54
 
55
55
  it "raises if set to a value of the wrong type" do
56
- expect { config.simple = "foo" }.to raise_error(TypeError)
56
+ expect(Lita.logger).to receive(:fatal).with(
57
+ /Configuration type error: "simple" must be one of: Symbol/
58
+ )
59
+ expect { config.simple = "foo" }.to raise_error(SystemExit)
57
60
  end
58
61
  end
59
62
 
@@ -75,7 +78,10 @@ describe Lita::Configuration do
75
78
  end
76
79
 
77
80
  it "raises if set to a value of the wrong type" do
78
- expect { config.simple = 1 }.to raise_error(TypeError)
81
+ expect(Lita.logger).to receive(:fatal).with(
82
+ /Configuration type error: "simple" must be one of: Symbol, String/
83
+ )
84
+ expect { config.simple = 1 }.to raise_error(SystemExit)
79
85
  end
80
86
  end
81
87
 
@@ -116,7 +122,20 @@ describe Lita::Configuration do
116
122
  end
117
123
 
118
124
  it "raises if the validator raises due to an invalid value" do
119
- expect { config.simple = false }.to raise_error(Lita::ValidationError, "must be true")
125
+ expect(Lita.logger).to receive(:fatal).with(
126
+ /Validation error on attribute "simple": must be true/
127
+ )
128
+ expect { config.simple = false }.to raise_error(SystemExit)
129
+ end
130
+ end
131
+
132
+ describe "a validated attribute with a conflicting default value" do
133
+ it "raises a ValidationError" do
134
+ expect do
135
+ subject.config :simple, default: :foo do
136
+ validate { |value| "must be :bar" unless value == :bar }
137
+ end
138
+ end.to raise_error(Lita::ValidationError, /must be :bar/)
120
139
  end
121
140
  end
122
141
 
@@ -141,11 +160,9 @@ describe Lita::Configuration do
141
160
  end
142
161
  end
143
162
 
144
- describe "an attribute with all the options, validation, and nested attributes" do
163
+ describe "an attribute with all the options and nested attributes" do
145
164
  before do
146
165
  subject.config :nested, type: Symbol, default: :foo do
147
- validate { "validation error" }
148
-
149
166
  config :foo
150
167
  end
151
168
  end
@@ -158,8 +175,8 @@ describe Lita::Configuration do
158
175
  describe "multiple nested attributes with options" do
159
176
  before do
160
177
  subject.config :nested do
161
- config :foo, default: "foo" do
162
- validate { |value| "must be bar" unless value == "bar" }
178
+ config :foo, default: "bar" do
179
+ validate { |value| "must include bar" unless value.include?("bar") }
163
180
  end
164
181
 
165
182
  config :bar, type: Symbol
@@ -167,16 +184,19 @@ describe Lita::Configuration do
167
184
  end
168
185
 
169
186
  it "can get the first nested attribute" do
170
- expect(config.nested.foo).to eq("foo")
187
+ expect(config.nested.foo).to eq("bar")
171
188
  end
172
189
 
173
190
  it "can set the first nested attribute" do
174
- config.nested.foo = "bar"
175
- expect(config.nested.foo).to eq("bar")
191
+ config.nested.foo = "foo bar baz"
192
+ expect(config.nested.foo).to eq("foo bar baz")
176
193
  end
177
194
 
178
195
  it "has working validation" do
179
- expect { config.nested.foo = "baz" }.to raise_error(Lita::ValidationError)
196
+ expect(Lita.logger).to receive(:fatal).with(
197
+ /Validation error on attribute "foo": must include bar/
198
+ )
199
+ expect { config.nested.foo = "baz" }.to raise_error(SystemExit)
180
200
  end
181
201
 
182
202
  it "can get the second nested attribute" do
@@ -184,7 +204,10 @@ describe Lita::Configuration do
184
204
  end
185
205
 
186
206
  it "can set the second nested attribute and options take effect" do
187
- expect { config.nested.bar = "not a symbol" }.to raise_error(TypeError)
207
+ expect(Lita.logger).to receive(:fatal).with(
208
+ /Configuration type error: "bar" must be one of: Symbol/
209
+ )
210
+ expect { config.nested.bar = "not a symbol" }.to raise_error(SystemExit)
188
211
  end
189
212
  end
190
213
 
@@ -21,10 +21,10 @@ describe Lita::ConfigurationValidator, lita: true do
21
21
  config :foo, required: true
22
22
  end
23
23
 
24
- expect { subject.call }.to raise_error(
25
- Lita::ValidationError,
24
+ expect(Lita.logger).to receive(:fatal).with(
26
25
  /Configuration attribute "foo" is required for "test" adapter/
27
26
  )
27
+ expect { subject.call }.to raise_error(SystemExit)
28
28
  end
29
29
 
30
30
  it "has no effect if all adapters with nested configuration have valid configuration" do
@@ -44,10 +44,10 @@ describe Lita::ConfigurationValidator, lita: true do
44
44
  end
45
45
  end
46
46
 
47
- expect { subject.call }.to raise_error(
48
- Lita::ValidationError,
47
+ expect(Lita.logger).to receive(:fatal).with(
49
48
  /Configuration attribute "foo\.bar" is required for "test" adapter/
50
49
  )
50
+ expect { subject.call }.to raise_error(SystemExit)
51
51
  end
52
52
 
53
53
  it "uses the right namespace for a nested attribute when a previous nesting has been visited" do
@@ -61,10 +61,10 @@ describe Lita::ConfigurationValidator, lita: true do
61
61
  end
62
62
  end
63
63
 
64
- expect { subject.call }.to raise_error(
65
- Lita::ValidationError,
64
+ expect(Lita.logger).to receive(:fatal).with(
66
65
  /Configuration attribute "one\.two" is required for "test" adapter/
67
66
  )
67
+ expect { subject.call }.to raise_error(SystemExit)
68
68
  end
69
69
 
70
70
  it "has no effect if all handlers have valid configuration" do
@@ -80,10 +80,10 @@ describe Lita::ConfigurationValidator, lita: true do
80
80
  config :foo, required: true
81
81
  end
82
82
 
83
- expect { subject.call }.to raise_error(
84
- Lita::ValidationError,
83
+ expect(Lita.logger).to receive(:fatal).with(
85
84
  /Configuration attribute "foo" is required for "test" handler/
86
85
  )
86
+ expect { subject.call }.to raise_error(SystemExit)
87
87
  end
88
88
 
89
89
  it "has no effect if all handlers with nested configuration have valid configuration" do
@@ -103,10 +103,10 @@ describe Lita::ConfigurationValidator, lita: true do
103
103
  end
104
104
  end
105
105
 
106
- expect { subject.call }.to raise_error(
107
- Lita::ValidationError,
106
+ expect(Lita.logger).to receive(:fatal).with(
108
107
  /Configuration attribute "foo\.bar" is required for "test" handler/
109
108
  )
109
+ expect { subject.call }.to raise_error(SystemExit)
110
110
  end
111
111
  end
112
112
  end
@@ -3,7 +3,7 @@ require "spec_helper"
3
3
  describe Lita::DefaultConfiguration, lita: true do
4
4
  subject { described_class.new(registry) }
5
5
 
6
- let(:config) { subject.finalize }
6
+ let(:config) { subject.build }
7
7
 
8
8
  describe "adapter config" do
9
9
  it "is an old-style config object" do
@@ -238,7 +238,10 @@ describe Lita::DefaultConfiguration, lita: true do
238
238
  end
239
239
 
240
240
  it "raises a validation error for invalid log levels" do
241
- expect { config.robot.log_level = :not_a_level }.to raise_error(Lita::ValidationError)
241
+ expect(Lita.logger).to receive(:fatal).with(
242
+ /Validation error on attribute "log_level": must be one of/
243
+ )
244
+ expect { config.robot.log_level = :not_a_level }.to raise_error(SystemExit)
242
245
  end
243
246
 
244
247
  it "has no default admins" do
@@ -17,7 +17,7 @@ describe Lita::Handler::Common, lita: true do
17
17
  it "sets configuration attributes" do
18
18
  handler.config :foo
19
19
 
20
- config = handler.configuration.finalize
20
+ config = handler.configuration_builder.build
21
21
 
22
22
  expect(config.foo).to be_nil
23
23
  config.foo = :bar
@@ -25,13 +25,13 @@ describe Lita::Handler::Common, lita: true do
25
25
  end
26
26
  end
27
27
 
28
- describe ".configuration" do
29
- it "returns a Configuration object" do
30
- expect(handler.configuration).to be_a(Lita::Configuration)
28
+ describe ".configuration_builder" do
29
+ it "returns a ConfigurationBuilder object" do
30
+ expect(handler.configuration_builder).to be_a(Lita::ConfigurationBuilder)
31
31
  end
32
32
 
33
33
  it "is memoized" do
34
- expect(handler.configuration).to equal(handler.configuration)
34
+ expect(handler.configuration_builder).to equal(handler.configuration_builder)
35
35
  end
36
36
  end
37
37
 
@@ -24,6 +24,9 @@ describe Lita::Handler::EventRouter do
24
24
  on :callable_test, lambda { |payload|
25
25
  robot.send_message("#{payload[:data]} received via callable!")
26
26
  }
27
+
28
+ on(:multiple_callbacks) { robot.send_message("first callback") }
29
+ on(:multiple_callbacks) { robot.send_message("second callback") }
27
30
  end
28
31
  end
29
32
 
@@ -45,6 +48,14 @@ describe Lita::Handler::EventRouter do
45
48
  subject.trigger(robot, :callable_test, data: "Data")
46
49
  end
47
50
 
51
+ it "doesn't stop triggering callbacks after the first is triggered" do
52
+ allow(robot).to receive(:send_message)
53
+
54
+ expect(robot).to receive(:send_message).with("second callback")
55
+
56
+ subject.trigger(robot, :multiple_callbacks)
57
+ end
58
+
48
59
  it "normalizes the event name" do
49
60
  expect(robot).to receive(:send_message).twice
50
61
  subject.trigger(robot, "connected")
@@ -1,6 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
- describe Lita::Builder, lita: true do
3
+ describe Lita::PluginBuilder, lita: true do
4
4
  let(:robot) { instance_double("Lita::Robot") }
5
5
  subject { plugin.new(robot) }
6
6
 
data/spec/lita_spec.rb CHANGED
@@ -3,7 +3,7 @@ require "spec_helper"
3
3
  describe Lita do
4
4
  before { described_class.register_adapter(:shell, Lita::Adapters::Shell) }
5
5
 
6
- it "memoizes a Config" do
6
+ it "memoizes a Configuration" do
7
7
  expect(described_class.config).to eql(described_class.config)
8
8
  end
9
9
 
@@ -15,7 +15,7 @@ describe Lita do
15
15
  end
16
16
 
17
17
  describe ".configure" do
18
- it "yields the Config object" do
18
+ it "yields the Configuration object" do
19
19
  described_class.configure { |c| c.robot.name = "Not Lita" }
20
20
  expect(described_class.config.robot.name).to eq("Not Lita")
21
21
  end
@@ -163,9 +163,9 @@ describe Lita do
163
163
  end
164
164
 
165
165
  it "raises if the configuration is not valid" do
166
- allow(validator).to receive(:call).and_raise(Lita::ValidationError)
166
+ allow(validator).to receive(:call).and_raise(SystemExit)
167
167
 
168
- expect { described_class.run }.to raise_error(Lita::ValidationError)
168
+ expect { described_class.run }.to raise_error(SystemExit)
169
169
  end
170
170
  end
171
171
  end
@@ -54,7 +54,7 @@ en:
54
54
  Use Lita::Adapter.config instead.
55
55
  required_configs_deprecated: >-
56
56
  Lita::Adapter.required_configs is deprecated and will be removed in Lita 5.0.
57
- Use Lita::Adapter.configuration instead.
57
+ Use Lita::Adapter.configuration_builder instead.
58
58
  cli:
59
59
  no_gemfile_warning: >-
60
60
  The default command "start" must be run inside a Lita project. Try running `lita new` to
@@ -83,6 +83,10 @@ en:
83
83
  Configuration attribute "%{attribute}" is required for "%{adapter}" adapter.
84
84
  missing_required_handler_attribute: >-
85
85
  Configuration attribute "%{attribute}" is required for "%{handler}" handler.
86
+ type_error: >-
87
+ Configuration type error: "%{attribute}" must be one of: %{types}.
88
+ validation_error: >-
89
+ Validation error on attribute "%{attribute}": %{message}
86
90
  daemon:
87
91
  pid_exists: >-
88
92
  PID file exists at %{path}. Lita may already be running. Kill the existing process or
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.0.0.rc1
4
+ version: 4.0.0.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jimmy Cuadra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-18 00:00:00.000000000 Z
11
+ date: 2014-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -283,13 +283,12 @@ files:
283
283
  - lib/lita/adapter.rb
284
284
  - lib/lita/adapters/shell.rb
285
285
  - lib/lita/authorization.rb
286
- - lib/lita/builder.rb
287
286
  - lib/lita/callback.rb
288
287
  - lib/lita/cli.rb
289
288
  - lib/lita/common.rb
290
289
  - lib/lita/config.rb
291
290
  - lib/lita/configurable.rb
292
- - lib/lita/configuration.rb
291
+ - lib/lita/configuration_builder.rb
293
292
  - lib/lita/configuration_validator.rb
294
293
  - lib/lita/daemon.rb
295
294
  - lib/lita/default_configuration.rb
@@ -309,6 +308,7 @@ files:
309
308
  - lib/lita/logger.rb
310
309
  - lib/lita/message.rb
311
310
  - lib/lita/namespace.rb
311
+ - lib/lita/plugin_builder.rb
312
312
  - lib/lita/rack_app.rb
313
313
  - lib/lita/registry.rb
314
314
  - lib/lita/response.rb
@@ -329,9 +329,8 @@ files:
329
329
  - spec/lita/adapter_spec.rb
330
330
  - spec/lita/adapters/shell_spec.rb
331
331
  - spec/lita/authorization_spec.rb
332
- - spec/lita/builder_spec.rb
333
332
  - spec/lita/config_spec.rb
334
- - spec/lita/configuration_spec.rb
333
+ - spec/lita/configuration_builder_spec.rb
335
334
  - spec/lita/configuration_validator_spec.rb
336
335
  - spec/lita/daemon_spec.rb
337
336
  - spec/lita/default_configuration_spec.rb
@@ -347,6 +346,7 @@ files:
347
346
  - spec/lita/handlers/room_spec.rb
348
347
  - spec/lita/logger_spec.rb
349
348
  - spec/lita/message_spec.rb
349
+ - spec/lita/plugin_builder_spec.rb
350
350
  - spec/lita/response_spec.rb
351
351
  - spec/lita/robot_spec.rb
352
352
  - spec/lita/rspec_spec.rb
@@ -399,9 +399,8 @@ test_files:
399
399
  - spec/lita/adapter_spec.rb
400
400
  - spec/lita/adapters/shell_spec.rb
401
401
  - spec/lita/authorization_spec.rb
402
- - spec/lita/builder_spec.rb
403
402
  - spec/lita/config_spec.rb
404
- - spec/lita/configuration_spec.rb
403
+ - spec/lita/configuration_builder_spec.rb
405
404
  - spec/lita/configuration_validator_spec.rb
406
405
  - spec/lita/daemon_spec.rb
407
406
  - spec/lita/default_configuration_spec.rb
@@ -417,6 +416,7 @@ test_files:
417
416
  - spec/lita/handlers/room_spec.rb
418
417
  - spec/lita/logger_spec.rb
419
418
  - spec/lita/message_spec.rb
419
+ - spec/lita/plugin_builder_spec.rb
420
420
  - spec/lita/response_spec.rb
421
421
  - spec/lita/robot_spec.rb
422
422
  - spec/lita/rspec_spec.rb