lita 3.3.1 → 4.0.0.rc1

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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.travis.yml +3 -0
  4. data/lib/lita.rb +45 -97
  5. data/lib/lita/adapter.rb +38 -17
  6. data/lib/lita/adapters/shell.rb +5 -3
  7. data/lib/lita/authorization.rb +109 -60
  8. data/lib/lita/builder.rb +38 -0
  9. data/lib/lita/callback.rb +37 -0
  10. data/lib/lita/cli.rb +2 -0
  11. data/lib/lita/config.rb +1 -18
  12. data/lib/lita/configurable.rb +29 -0
  13. data/lib/lita/configuration.rb +179 -0
  14. data/lib/lita/configuration_validator.rb +66 -0
  15. data/lib/lita/daemon.rb +4 -11
  16. data/lib/lita/default_configuration.rb +146 -0
  17. data/lib/lita/errors.rb +9 -0
  18. data/lib/lita/handler.rb +5 -264
  19. data/lib/lita/handler/chat_router.rb +130 -0
  20. data/lib/lita/handler/common.rb +114 -0
  21. data/lib/lita/handler/event_router.rb +77 -0
  22. data/lib/lita/handler/http_router.rb +26 -0
  23. data/lib/lita/handlers/authorization.rb +13 -18
  24. data/lib/lita/handlers/deprecation_check.rb +24 -0
  25. data/lib/lita/handlers/help.rb +5 -3
  26. data/lib/lita/handlers/info.rb +2 -2
  27. data/lib/lita/http_callback.rb +29 -0
  28. data/lib/lita/http_route.rb +41 -26
  29. data/lib/lita/namespace.rb +23 -0
  30. data/lib/lita/rack_app.rb +29 -2
  31. data/lib/lita/registry.rb +133 -0
  32. data/lib/lita/robot.rb +58 -20
  33. data/lib/lita/route_validator.rb +12 -4
  34. data/lib/lita/rspec.rb +23 -14
  35. data/lib/lita/rspec/handler.rb +93 -23
  36. data/lib/lita/rspec/matchers/chat_route_matcher.rb +48 -0
  37. data/lib/lita/rspec/matchers/deprecated.rb +36 -0
  38. data/lib/lita/rspec/matchers/event_route_matcher.rb +27 -0
  39. data/lib/lita/rspec/matchers/http_route_matcher.rb +18 -60
  40. data/lib/lita/user.rb +0 -6
  41. data/lib/lita/util.rb +1 -8
  42. data/lib/lita/version.rb +1 -1
  43. data/lita.gemspec +1 -0
  44. data/spec/lita/adapter_spec.rb +25 -7
  45. data/spec/lita/adapters/shell_spec.rb +24 -4
  46. data/spec/lita/authorization_spec.rb +57 -38
  47. data/spec/lita/builder_spec.rb +39 -0
  48. data/spec/lita/config_spec.rb +0 -24
  49. data/spec/lita/configuration_spec.rb +222 -0
  50. data/spec/lita/configuration_validator_spec.rb +112 -0
  51. data/spec/lita/daemon_spec.rb +2 -2
  52. data/spec/lita/default_configuration_spec.rb +254 -0
  53. data/spec/lita/handler/chat_router_spec.rb +192 -0
  54. data/spec/lita/handler/common_spec.rb +272 -0
  55. data/spec/lita/handler/event_router_spec.rb +54 -0
  56. data/spec/lita/handler/http_router_spec.rb +106 -0
  57. data/spec/lita/handler_spec.rb +20 -291
  58. data/spec/lita/handlers/authorization_spec.rb +9 -11
  59. data/spec/lita/handlers/deprecation_check_spec.rb +21 -0
  60. data/spec/lita/handlers/help_spec.rb +31 -9
  61. data/spec/lita/handlers/info_spec.rb +2 -2
  62. data/spec/lita/handlers/room_spec.rb +5 -3
  63. data/spec/lita/robot_spec.rb +30 -11
  64. data/spec/lita/rspec_spec.rb +71 -31
  65. data/spec/lita/user_spec.rb +2 -2
  66. data/spec/lita_spec.rb +62 -4
  67. data/spec/spec_helper.rb +7 -0
  68. data/templates/locales/en.yml +56 -4
  69. data/templates/plugin/gemspec.tt +1 -0
  70. data/templates/plugin/spec/spec_helper.tt +4 -0
  71. metadata +54 -8
  72. data/lib/lita/rspec/matchers/event_subscription_matcher.rb +0 -67
  73. data/lib/lita/rspec/matchers/route_matcher.rb +0 -69
  74. data/spec/lita/rack_app_spec.rb +0 -92
@@ -0,0 +1,39 @@
1
+ require "spec_helper"
2
+
3
+ describe Lita::Builder, lita: true do
4
+ let(:robot) { instance_double("Lita::Robot") }
5
+ subject { plugin.new(robot) }
6
+
7
+ describe "#build_adapter" do
8
+ let(:builder) do
9
+ described_class.new(:test_adapter) do
10
+ def run
11
+ self.class.namespace
12
+ end
13
+ end
14
+ end
15
+
16
+ let(:plugin) { builder.build_adapter }
17
+
18
+ it "builds an adapter" do
19
+ expect(subject.run).to eq("test_adapter")
20
+ end
21
+ end
22
+
23
+ describe "#build_handler" do
24
+ builder = described_class.new(:test_handler) do
25
+ route(/namespace/) { |response| response.reply(self.class.namespace) }
26
+ end
27
+
28
+ plugin = builder.build_handler
29
+
30
+ describe plugin, lita_handler: true do
31
+ before { registry.register_handler(plugin) }
32
+
33
+ it "builds a handler from a block" do
34
+ send_message("namespace")
35
+ expect(replies.last).to eq("test_handler")
36
+ end
37
+ end
38
+ end
39
+ end
@@ -37,30 +37,6 @@ describe Lita::Config do
37
37
  end
38
38
  end
39
39
 
40
- describe ".load_user_config" do
41
- it "loads and evals lita_config.rb" do
42
- allow(File).to receive(:exist?).and_return(true)
43
- allow(described_class).to receive(:load) do
44
- Lita.configure { |config| config.robot.name = "Not Lita" }
45
- end
46
- described_class.load_user_config
47
- expect(Lita.config.robot.name).to eq("Not Lita")
48
- end
49
-
50
- it "doesn't attempt to load lita_config.rb if it doesn't exist" do
51
- allow(File).to receive(:exist?).and_return(false)
52
- expect(described_class).not_to receive(:load)
53
- described_class.load_user_config
54
- end
55
-
56
- it "raises an exception if lita_config.rb raises an exception" do
57
- allow(File).to receive(:exist?).and_return(true)
58
- allow(described_class).to receive(:load) { Lita.non_existent_method }
59
- expect(Lita.logger).to receive(:fatal).with(/could not be processed/)
60
- expect { described_class.load_user_config }.to raise_error(SystemExit)
61
- end
62
- end
63
-
64
40
  describe "#finalize" do
65
41
  it "freezes the configuration" do
66
42
  subject.finalize
@@ -0,0 +1,222 @@
1
+ require "spec_helper"
2
+
3
+ describe Lita::Configuration do
4
+ let(:config) { subject.finalize }
5
+
6
+ describe ".load_user_config" do
7
+ it "loads and evals lita_config.rb" do
8
+ allow(File).to receive(:exist?).and_return(true)
9
+ allow(described_class).to receive(:load) do
10
+ Lita.configure { |c| c.robot.name = "Not Lita" }
11
+ end
12
+ described_class.load_user_config
13
+ expect(Lita.config.robot.name).to eq("Not Lita")
14
+ end
15
+
16
+ it "doesn't attempt to load lita_config.rb if it doesn't exist" do
17
+ allow(File).to receive(:exist?).and_return(false)
18
+ expect(described_class).not_to receive(:load)
19
+ described_class.load_user_config
20
+ end
21
+
22
+ it "raises an exception if lita_config.rb raises an exception" do
23
+ allow(File).to receive(:exist?).and_return(true)
24
+ allow(described_class).to receive(:load) { Lita.non_existent_method }
25
+ expect(Lita.logger).to receive(:fatal).with(/could not be processed/)
26
+ expect { described_class.load_user_config }.to raise_error(SystemExit)
27
+ end
28
+ end
29
+
30
+ describe "a simple attribute" do
31
+ before { subject.config :simple }
32
+
33
+ it "is nil by default" do
34
+ expect(config.simple).to be_nil
35
+ end
36
+
37
+ it "can be set to anything" do
38
+ config.simple = 1
39
+ expect(config.simple).to eq(1)
40
+ end
41
+ end
42
+
43
+ describe "a typed attribute" do
44
+ before { subject.config :simple, type: Symbol }
45
+
46
+ it "is nil by default" do
47
+ expect(config.simple).to be_nil
48
+ end
49
+
50
+ it "can be set to a value of the type" do
51
+ config.simple = :foo
52
+ expect(config.simple).to eq(:foo)
53
+ end
54
+
55
+ it "raises if set to a value of the wrong type" do
56
+ expect { config.simple = "foo" }.to raise_error(TypeError)
57
+ end
58
+ end
59
+
60
+ describe "a composite typed attribute" do
61
+ before { subject.config :simple, types: [Symbol, String] }
62
+
63
+ it "is nil by default" do
64
+ expect(config.simple).to be_nil
65
+ end
66
+
67
+ it "can be set to a value of the first type" do
68
+ config.simple = :foo
69
+ expect(config.simple).to eq(:foo)
70
+ end
71
+
72
+ it "can be set to a value of the second type" do
73
+ config.simple = "foo"
74
+ expect(config.simple).to eq("foo")
75
+ end
76
+
77
+ it "raises if set to a value of the wrong type" do
78
+ expect { config.simple = 1 }.to raise_error(TypeError)
79
+ end
80
+ end
81
+
82
+ describe "an attribute with a default value" do
83
+ before { subject.config :simple, default: :foo }
84
+
85
+ it "starts with the default value" do
86
+ expect(config.simple).to eq(:foo)
87
+ end
88
+
89
+ it "can be reassigned" do
90
+ config.simple = :bar
91
+ expect(config.simple).to eq(:bar)
92
+ end
93
+ end
94
+
95
+ describe "a typed attribute with a default value" do
96
+ it "starts with the default value" do
97
+ subject.config :simple, type: Symbol, default: :foo
98
+ expect(config.simple).to eq(:foo)
99
+ end
100
+
101
+ it "raises if the default is a value of the wrong type" do
102
+ expect { subject.config :simple, type: Symbol, default: "foo" }.to raise_error(TypeError)
103
+ end
104
+ end
105
+
106
+ describe "a validated attribute" do
107
+ before do
108
+ subject.config :simple do
109
+ validate { |value| "must be true" unless value }
110
+ end
111
+ end
112
+
113
+ it "can be set to a value that passes validation" do
114
+ config.simple = true
115
+ expect(config.simple).to be(true)
116
+ end
117
+
118
+ 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")
120
+ end
121
+ end
122
+
123
+ describe "a simple nested attribute" do
124
+ before do
125
+ subject.config :nested do
126
+ config :foo
127
+ end
128
+ end
129
+
130
+ it "is nil by default" do
131
+ expect(config.nested.foo).to be_nil
132
+ end
133
+
134
+ it "can be set to anything" do
135
+ config.nested.foo = :bar
136
+ expect(config.nested.foo).to eq(:bar)
137
+ end
138
+
139
+ it "prevents the parent from being assigned" do
140
+ expect { config.nested = "impossible" }.to raise_error(NoMethodError)
141
+ end
142
+ end
143
+
144
+ describe "an attribute with all the options, validation, and nested attributes" do
145
+ before do
146
+ subject.config :nested, type: Symbol, default: :foo do
147
+ validate { "validation error" }
148
+
149
+ config :foo
150
+ end
151
+ end
152
+
153
+ it "cannot be set" do
154
+ expect { config.nested = "impossible" }.to raise_error(NoMethodError)
155
+ end
156
+ end
157
+
158
+ describe "multiple nested attributes with options" do
159
+ before do
160
+ subject.config :nested do
161
+ config :foo, default: "foo" do
162
+ validate { |value| "must be bar" unless value == "bar" }
163
+ end
164
+
165
+ config :bar, type: Symbol
166
+ end
167
+ end
168
+
169
+ it "can get the first nested attribute" do
170
+ expect(config.nested.foo).to eq("foo")
171
+ end
172
+
173
+ it "can set the first nested attribute" do
174
+ config.nested.foo = "bar"
175
+ expect(config.nested.foo).to eq("bar")
176
+ end
177
+
178
+ it "has working validation" do
179
+ expect { config.nested.foo = "baz" }.to raise_error(Lita::ValidationError)
180
+ end
181
+
182
+ it "can get the second nested attribute" do
183
+ expect(config.nested.bar).to be_nil
184
+ end
185
+
186
+ it "can set the second nested attribute and options take effect" do
187
+ expect { config.nested.bar = "not a symbol" }.to raise_error(TypeError)
188
+ end
189
+ end
190
+
191
+ describe "#has_children?" do
192
+ it "is true when any attribute has been created" do
193
+ subject.config :foo
194
+
195
+ expect(subject.children?).to be_truthy
196
+ end
197
+
198
+ it "is false when no attributes have been created" do
199
+ expect(subject.children?).to be_falsy
200
+ end
201
+ end
202
+
203
+ describe "#combine" do
204
+ let(:config_2) do
205
+ config_2 = described_class.new
206
+ config_2.config(:bar)
207
+ config_2
208
+ end
209
+
210
+ it "sets the provided configuration as the value of the provided attribute" do
211
+ subject.combine(:foo, config_2)
212
+
213
+ expect(config.foo.bar).to be_nil
214
+ end
215
+
216
+ it "does not allow the combined configuration to be reassigned" do
217
+ subject.combine(:foo, config_2)
218
+
219
+ expect { config.foo = "bar" }.to raise_error(NoMethodError)
220
+ end
221
+ end
222
+ end
@@ -0,0 +1,112 @@
1
+ require "spec_helper"
2
+
3
+ describe Lita::ConfigurationValidator, lita: true do
4
+ subject { described_class.new(registry) }
5
+
6
+ describe "#call" do
7
+ it "has no effect if there are no plugins registered" do
8
+ expect { subject.call }.not_to raise_error
9
+ end
10
+
11
+ it "has no effect if all adapters have valid configuration" do
12
+ registry.register_adapter(:test) do
13
+ config :foo, required: true, default: :bar
14
+ end
15
+
16
+ expect { subject.call }.not_to raise_error
17
+ end
18
+
19
+ it "raises if a required adapter configuration attribute is missing" do
20
+ registry.register_adapter(:test) do
21
+ config :foo, required: true
22
+ end
23
+
24
+ expect { subject.call }.to raise_error(
25
+ Lita::ValidationError,
26
+ /Configuration attribute "foo" is required for "test" adapter/
27
+ )
28
+ end
29
+
30
+ it "has no effect if all adapters with nested configuration have valid configuration" do
31
+ registry.register_adapter(:test) do
32
+ config :foo do
33
+ config :bar, required: true, default: :baz
34
+ end
35
+ end
36
+
37
+ expect { subject.call }.not_to raise_error
38
+ end
39
+
40
+ it "raises if a required nested adapter configuration attribute is missing" do
41
+ registry.register_adapter(:test) do
42
+ config :foo do
43
+ config :bar, required: true
44
+ end
45
+ end
46
+
47
+ expect { subject.call }.to raise_error(
48
+ Lita::ValidationError,
49
+ /Configuration attribute "foo\.bar" is required for "test" adapter/
50
+ )
51
+ end
52
+
53
+ it "uses the right namespace for a nested attribute when a previous nesting has been visited" do
54
+ registry.register_adapter(:test) do
55
+ config :foo do
56
+ config :bar
57
+ end
58
+
59
+ config :one do
60
+ config :two, required: true
61
+ end
62
+ end
63
+
64
+ expect { subject.call }.to raise_error(
65
+ Lita::ValidationError,
66
+ /Configuration attribute "one\.two" is required for "test" adapter/
67
+ )
68
+ end
69
+
70
+ it "has no effect if all handlers have valid configuration" do
71
+ registry.register_handler(:test) do
72
+ config :foo, required: true, default: :bar
73
+ end
74
+
75
+ expect { subject.call }.not_to raise_error
76
+ end
77
+
78
+ it "raises if a required handler configuration attribute is missing" do
79
+ registry.register_handler(:test) do
80
+ config :foo, required: true
81
+ end
82
+
83
+ expect { subject.call }.to raise_error(
84
+ Lita::ValidationError,
85
+ /Configuration attribute "foo" is required for "test" handler/
86
+ )
87
+ end
88
+
89
+ it "has no effect if all handlers with nested configuration have valid configuration" do
90
+ registry.register_handler(:test) do
91
+ config :foo do
92
+ config :bar, required: true, default: :baz
93
+ end
94
+ end
95
+
96
+ expect { subject.call }.not_to raise_error
97
+ end
98
+
99
+ it "raises if a required nested handler configuration attribute is missing" do
100
+ registry.register_handler(:test) do
101
+ config :foo do
102
+ config :bar, required: true
103
+ end
104
+ end
105
+
106
+ expect { subject.call }.to raise_error(
107
+ Lita::ValidationError,
108
+ /Configuration attribute "foo\.bar" is required for "test" handler/
109
+ )
110
+ end
111
+ end
112
+ end
@@ -11,8 +11,8 @@ describe Lita::Daemon do
11
11
  allow(File).to receive(:new).and_return("log")
12
12
  allow(File).to receive(:open)
13
13
  allow(File).to receive(:read)
14
- allow_any_instance_of(described_class).to receive(:stdout).and_return(stdout)
15
- allow_any_instance_of(described_class).to receive(:stderr).and_return(stderr)
14
+ stub_const("STDOUT", stdout)
15
+ stub_const("STDERR", stderr)
16
16
  end
17
17
 
18
18
  subject { described_class.new("/tmp/lita_pid", "/tmp/lita_log", false) }
@@ -0,0 +1,254 @@
1
+ require "spec_helper"
2
+
3
+ describe Lita::DefaultConfiguration, lita: true do
4
+ subject { described_class.new(registry) }
5
+
6
+ let(:config) { subject.finalize }
7
+
8
+ describe "adapter config" do
9
+ it "is an old-style config object" do
10
+ config.adapter.foo = "bar"
11
+
12
+ expect(config.adapter.foo).to eq("bar")
13
+ end
14
+
15
+ it "prints a deprecation warning on access" do
16
+ expect(Lita.logger).to receive(:warn).with(/config\.adapter is deprecated/)
17
+
18
+ config.adapter.foo = "bar"
19
+ end
20
+
21
+ it "allows hash-style access" do
22
+ config.adapter[:foo] = :bar
23
+
24
+ expect(config.adapter["foo"]).to eq(:bar)
25
+ end
26
+
27
+ it "outputs one deprecation warning per hash-style access" do
28
+ expect(Lita.logger).to receive(:warn).once
29
+
30
+ config.adapter[:foo] = :bar
31
+ end
32
+ end
33
+
34
+ describe "adapters config" do
35
+ context "with no adapters with config attributes" do
36
+ it "has an adapters attribute" do
37
+ expect(config).to respond_to(:adapters)
38
+ end
39
+ end
40
+
41
+ context "with one adapter with no configuration" do
42
+ it "has an attribute for the adapter" do
43
+ registry.register_adapter(:foo) {}
44
+ expect(config.adapters).to respond_to(:foo)
45
+ end
46
+ end
47
+
48
+ context "with an adapter with configuration" do
49
+ it "has an attribute for the handler with its own attributes" do
50
+ registry.register_adapter(:foo) { config :bar, default: :baz }
51
+
52
+ expect(config.adapters.foo.bar).to eq(:baz)
53
+ end
54
+ end
55
+ end
56
+
57
+ describe "handlers config" do
58
+ context "with no handlers with config attributes" do
59
+ it "has a handlers attribute" do
60
+ expect(config).to respond_to(:handlers)
61
+ end
62
+ end
63
+
64
+ context "with one handler with no configuration" do
65
+ it "has an attribute for the handler" do
66
+ registry.register_handler(:foo) {}
67
+
68
+ expect(config.handlers).to respond_to(:foo)
69
+ end
70
+ end
71
+
72
+ context "with a handler with configuration" do
73
+ it "has an attribute for the handler with its own attributes" do
74
+ registry.register_handler(:foo) { config :bar, default: :baz }
75
+
76
+ expect(config.handlers.foo.bar).to eq(:baz)
77
+ end
78
+ end
79
+
80
+ context "with a handler defining default_config" do
81
+ before do
82
+ registry.register_handler(:foo) do
83
+ def self.default_config(old_config)
84
+ old_config.bar = :baz
85
+ end
86
+ end
87
+ end
88
+
89
+ it "has an attribute for the handler with its own attributes" do
90
+ expect(config.handlers.foo.bar).to eq(:baz)
91
+ end
92
+ end
93
+ end
94
+
95
+ describe "http config" do
96
+ it "has a default host" do
97
+ expect(config.http.host).to eq("0.0.0.0")
98
+ end
99
+
100
+ it "can set the host" do
101
+ config.http.host = "127.0.0.1"
102
+
103
+ expect(config.http.host).to eq("127.0.0.1")
104
+ end
105
+
106
+ it "has a default port" do
107
+ expect(config.http.port).to eq(8080)
108
+ end
109
+
110
+ it "can set the port" do
111
+ config.http.port = 80
112
+
113
+ expect(config.http.port).to eq(80)
114
+ end
115
+
116
+ it "has a default minimum thread count" do
117
+ expect(config.http.min_threads).to eq(0)
118
+ end
119
+
120
+ it "can set the minimum threads" do
121
+ config.http.min_threads = 4
122
+
123
+ expect(config.http.min_threads).to eq(4)
124
+ end
125
+
126
+ it "has a default maximum thread count" do
127
+ expect(config.http.max_threads).to eq(16)
128
+ end
129
+
130
+ it "can set the maximum threads" do
131
+ config.http.max_threads = 8
132
+
133
+ expect(config.http.max_threads).to eq(8)
134
+ end
135
+
136
+ it "has an empty middleware stack" do
137
+ expect(config.http.middleware).to be_empty
138
+ end
139
+
140
+ it "can add middleware to the stack" do
141
+ middleware = double("a rack middleware")
142
+
143
+ config.http.middleware.push(middleware)
144
+
145
+ expect(config.http.middleware).to include(middleware)
146
+ end
147
+ end
148
+
149
+ describe "redis config" do
150
+ it "has empty default options" do
151
+ expect(config.redis).to eq({})
152
+ end
153
+
154
+ it "can set options" do
155
+ options = { port: 1234, password: "secret" }
156
+
157
+ config.redis = options
158
+
159
+ expect(config.redis).to eq(options)
160
+ end
161
+
162
+ it "can set options with struct-style access" do
163
+ config.redis.port = 1234
164
+
165
+ expect(config.redis.port).to eq(1234)
166
+ end
167
+
168
+ it "prints a deprecation warning for struct-style access" do
169
+ expect(Lita.logger).to receive(:warn).with(/struct-style access/i)
170
+
171
+ config.redis.port = 1234
172
+ end
173
+ end
174
+
175
+ describe "robot config" do
176
+ it "has a default name" do
177
+ expect(config.robot.name).to eq("Lita")
178
+ end
179
+
180
+ it "can set a name" do
181
+ config.robot.name = "Not Lita"
182
+
183
+ expect(config.robot.name).to eq("Not Lita")
184
+ end
185
+
186
+ it "has no default mention name" do
187
+ expect(config.robot.mention_name).to be_nil
188
+ end
189
+
190
+ it "can set a mention name" do
191
+ config.robot.mention_name = "notlita"
192
+
193
+ expect(config.robot.mention_name).to eq("notlita")
194
+ end
195
+
196
+ it "has no default alias" do
197
+ expect(config.robot.alias).to be_nil
198
+ end
199
+
200
+ it "can set an alias" do
201
+ config.robot.alias = "/"
202
+
203
+ expect(config.robot.alias).to eq("/")
204
+ end
205
+
206
+ it "has a default adapter" do
207
+ expect(config.robot.adapter).to eq(:shell)
208
+ end
209
+
210
+ it "can set an adapter" do
211
+ config.robot.adapter = :hipchat
212
+
213
+ expect(config.robot.adapter).to eq(:hipchat)
214
+ end
215
+
216
+ it "has a default locale" do
217
+ expect(config.robot.locale).to eq(I18n.locale)
218
+ end
219
+
220
+ it "can set a locale" do
221
+ config.robot.locale = :es
222
+
223
+ expect(config.robot.locale).to eq(:es)
224
+ end
225
+
226
+ it "has a default log level" do
227
+ expect(config.robot.log_level).to eq(:info)
228
+ end
229
+
230
+ it "can set a log level" do
231
+ config.robot.log_level = :debug
232
+
233
+ expect(config.robot.log_level).to eq(:debug)
234
+ end
235
+
236
+ it "allows strings and mixed case as log levels" do
237
+ expect { config.robot.log_level = "dEbUg" }.not_to raise_error
238
+ end
239
+
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)
242
+ end
243
+
244
+ it "has no default admins" do
245
+ expect(config.robot.admins).to be_nil
246
+ end
247
+
248
+ it "can set admins" do
249
+ config.robot.admins = %w(1 2 3)
250
+
251
+ expect(config.robot.admins).to eq(%w(1 2 3))
252
+ end
253
+ end
254
+ end