lita-karma 1.2.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -0
- data/README.md +24 -11
- data/lib/lita/handlers/karma.rb +200 -79
- data/lita-karma.gemspec +2 -2
- data/spec/lita/handlers/karma_spec.rb +108 -21
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 970fdc7b7a7dd713d5aaa779ee54a03f4b7b11f9
|
4
|
+
data.tar.gz: 1cf49139dc0e119127dcc8625dbff430bc5c93b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1af6f6ad8bb1afebb17ec8d591cb56ecbcce7411d6160faa678c524d654ff0a0f263727a01e93331a67936be40a371e21f5b3b58503c47d7180edc1b764a44b1
|
7
|
+
data.tar.gz: e1b5d78d0a2e76213dba98c55c8002822e3f10932a53606ae685f3d6b5862dc5defcbfe97d15771eafcc5df9961e3bb24fc8182b7521491ce0c596f1dbaf844d
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# lita-karma
|
2
2
|
|
3
|
-
[![Build Status](https://travis-ci.org/jimmycuadra/lita-karma.png)](https://travis-ci.org/jimmycuadra/lita-karma)
|
3
|
+
[![Build Status](https://travis-ci.org/jimmycuadra/lita-karma.png?branch=master)](https://travis-ci.org/jimmycuadra/lita-karma)
|
4
4
|
[![Code Climate](https://codeclimate.com/github/jimmycuadra/lita-karma.png)](https://codeclimate.com/github/jimmycuadra/lita-karma)
|
5
5
|
[![Coverage Status](https://coveralls.io/repos/jimmycuadra/lita-karma/badge.png)](https://coveralls.io/r/jimmycuadra/lita-karma)
|
6
6
|
|
@@ -16,11 +16,24 @@ gem "lita-karma"
|
|
16
16
|
|
17
17
|
## Configuration
|
18
18
|
|
19
|
-
|
19
|
+
### Optional attributes
|
20
20
|
|
21
|
-
|
21
|
+
* `cooldown` (Integer, nil) - Controls how long a user must wait after modifying a term before they can modify it again. The value should be an integer number of seconds. Set it to `nil` to disable rate limiting. Default: `300` (5 minutes.
|
22
|
+
* `term_pattern` (Regexp) - Determines what Lita will recognize as a valid term for tracking karma. Default: `//[\[\]\w\._|\{\}]{2,}/`.
|
23
|
+
* `term_normalizer` (Proc) - A custom callable that determines how each term will be normalized before being stored in Redis. The proc should take one argument, the term as matched via regular expression, and return one value, the normalized version of the term.
|
24
|
+
|
25
|
+
|
26
|
+
### Example
|
27
|
+
|
28
|
+
This example configuration sets the cooldown to 10 minutes and changes the term pattern and normalization to allow multi-word terms bounded by `<>` or `:`, as previous versions of lita-karma did by default.
|
29
|
+
|
30
|
+
``` ruby
|
22
31
|
Lita.configure do |config|
|
23
32
|
config.handlers.karma.cooldown = 600
|
33
|
+
config.handlers.karma.term_pattern = /[<:][^>:]+[>:]/
|
34
|
+
config.handlers.karma.term_normalizer = lambda do |term|
|
35
|
+
term.to_s.downcase.strip.sub(/[<:]([^>:]+)[>:]/, '\1')
|
36
|
+
end
|
24
37
|
end
|
25
38
|
```
|
26
39
|
|
@@ -32,14 +45,6 @@ Lita will add a karma point whenever it hears a term upvoted:
|
|
32
45
|
term++
|
33
46
|
```
|
34
47
|
|
35
|
-
You can also give karma to multi-worded terms or terms with symbols by bounding them with `<>` or `::`:
|
36
|
-
|
37
|
-
```
|
38
|
-
:Linus Torvalds:++
|
39
|
-
|
40
|
-
<C++>++
|
41
|
-
```
|
42
|
-
|
43
48
|
It will subtract a karma point whenever it hears a term downvoted:
|
44
49
|
|
45
50
|
```
|
@@ -97,6 +102,14 @@ foo~~
|
|
97
102
|
|
98
103
|
When a term is linked, the total karma score is displayed first, followed by the score of the term without its linked terms in parentheses.
|
99
104
|
|
105
|
+
To permanently delete a term and all its links:
|
106
|
+
|
107
|
+
```
|
108
|
+
Lita: karma delete TERM
|
109
|
+
```
|
110
|
+
|
111
|
+
Note that when deleting a term, the term will be matched exactly as typed, including leading whitespace (the single space after the word "delete" is not counted) and other patterns which would not normally match as a valid term. This can be useful if you decide to change the term pattern or normalization and want to clean up previous data that is no longer valid. Deleting a term requires the user to be a member of the `:karma_admins` authorization group.
|
112
|
+
|
100
113
|
## License
|
101
114
|
|
102
115
|
[MIT](http://opensource.org/licenses/MIT)
|
data/lib/lita/handlers/karma.rb
CHANGED
@@ -2,61 +2,40 @@ require "lita"
|
|
2
2
|
|
3
3
|
module Lita
|
4
4
|
module Handlers
|
5
|
+
# Tracks karma points for arbitrary terms.
|
5
6
|
class Karma < Handler
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
route %r{(#{TERM_REGEX.source})~~}, :check, help: {
|
15
|
-
"TERM~~" => "Shows the current karma of TERM."
|
16
|
-
}
|
17
|
-
route %r{^karma\s+worst}, :list_worst, command: true, help: {
|
18
|
-
"karma worst [N]" => <<-HELP.chomp
|
19
|
-
Lists the bottom N terms by karma. N defaults to 5.
|
20
|
-
HELP
|
21
|
-
}
|
22
|
-
route %r{^karma\s+best}, :list_best, command: true, help: {
|
23
|
-
"karma best [N]" => <<-HELP.chomp
|
24
|
-
Lists the top N terms by karma. N defaults to 5.
|
25
|
-
HELP
|
26
|
-
}
|
27
|
-
route %r{^karma\s+modified}, :modified, command: true, help: {
|
28
|
-
"karma modified TERM" => <<-HELP.chomp
|
29
|
-
Lists the names of users who have upvoted or downvoted TERM.
|
30
|
-
HELP
|
31
|
-
}
|
32
|
-
route %r{^karma\s*$}, :list_best, command: true
|
33
|
-
route(
|
34
|
-
%r{^(#{TERM_REGEX.source})\s*\+=\s*(#{TERM_REGEX.source})},
|
35
|
-
:link,
|
36
|
-
command: true,
|
37
|
-
help: {
|
38
|
-
"TERM1 += TERM2" => <<-HELP.chomp
|
39
|
-
Links TERM2 to TERM1. TERM1's karma will then be displayed as the sum of its \
|
40
|
-
own and TERM2's karma.
|
41
|
-
HELP
|
42
|
-
}
|
43
|
-
)
|
44
|
-
route(
|
45
|
-
%r{^(#{TERM_REGEX.source})\s*-=\s*(#{TERM_REGEX.source})},
|
46
|
-
:unlink,
|
47
|
-
command: true,
|
48
|
-
help: {
|
49
|
-
"TERM1 -= TERM2" => <<-HELP.chomp
|
50
|
-
Unlinks TERM2 from TERM1. TERM1's karma will no longer be displayed as the sum \
|
51
|
-
of its own and TERM2's karma.
|
52
|
-
HELP
|
53
|
-
}
|
54
|
-
)
|
7
|
+
TERM_PATTERN = /[\[\]\w\._|\{\}]{2,}/
|
8
|
+
|
9
|
+
class << self
|
10
|
+
attr_accessor :term_pattern
|
11
|
+
end
|
12
|
+
|
13
|
+
on :loaded, :upgrade_data
|
14
|
+
on :loaded, :define_routes
|
55
15
|
|
56
16
|
def self.default_config(config)
|
57
17
|
config.cooldown = 300
|
58
18
|
end
|
59
19
|
|
20
|
+
def upgrade_data(payload)
|
21
|
+
return if redis.exists("support:reverse_links")
|
22
|
+
redis.keys("links:*").each do |key|
|
23
|
+
term = key.sub(/^links:/, "")
|
24
|
+
redis.smembers(key).each do |link|
|
25
|
+
redis.sadd("linked_to:#{link}", term)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
redis.incr("support:reverse_links")
|
29
|
+
end
|
30
|
+
|
31
|
+
def define_routes(payload)
|
32
|
+
self.class.term_pattern =
|
33
|
+
Lita.config.handlers.karma.term_pattern || TERM_PATTERN
|
34
|
+
|
35
|
+
define_static_routes
|
36
|
+
define_dynamic_routes(term_pattern.source)
|
37
|
+
end
|
38
|
+
|
60
39
|
def increment(response)
|
61
40
|
modify(response, 1)
|
62
41
|
end
|
@@ -70,18 +49,11 @@ HELP
|
|
70
49
|
|
71
50
|
response.matches.each do |match|
|
72
51
|
term = normalize_term(match[0])
|
73
|
-
own_score
|
74
|
-
links = []
|
75
|
-
redis.smembers("links:#{term}").each do |link|
|
76
|
-
link_score = redis.zscore("terms", link).to_i
|
77
|
-
links << "#{link}: #{link_score}"
|
78
|
-
score += link_score
|
79
|
-
end
|
52
|
+
total_score, own_score, links = scores_for(term)
|
80
53
|
|
81
|
-
string = "#{term}: #{
|
54
|
+
string = "#{term}: #{total_score}"
|
82
55
|
unless links.empty?
|
83
|
-
string << " (#{own_score}), linked to: "
|
84
|
-
string << links.join(", ")
|
56
|
+
string << " (#{own_score}), linked to: #{links.join(", ")}"
|
85
57
|
end
|
86
58
|
output << string
|
87
59
|
end
|
@@ -102,6 +74,7 @@ HELP
|
|
102
74
|
term1, term2 = normalize_term(match[0]), normalize_term(match[1])
|
103
75
|
|
104
76
|
if redis.sadd("links:#{term1}", term2)
|
77
|
+
redis.sadd("linked_to:#{term2}", term1)
|
105
78
|
response.reply "#{term2} has been linked to #{term1}."
|
106
79
|
else
|
107
80
|
response.reply "#{term2} is already linked to #{term1}."
|
@@ -114,6 +87,7 @@ HELP
|
|
114
87
|
term1, term2 = normalize_term(match[0]), normalize_term(match[1])
|
115
88
|
|
116
89
|
if redis.srem("links:#{term1}", term2)
|
90
|
+
redis.srem("linked_to:#{term2}", term1)
|
117
91
|
response.reply "#{term2} has been unlinked from #{term1}."
|
118
92
|
else
|
119
93
|
response.reply "#{term2} is not linked to #{term1}."
|
@@ -141,38 +115,156 @@ HELP
|
|
141
115
|
end
|
142
116
|
end
|
143
117
|
|
118
|
+
def delete(response)
|
119
|
+
term = response.message.body.sub(/^karma delete /, "")
|
120
|
+
|
121
|
+
redis.del("modified:#{term}")
|
122
|
+
redis.del("links:#{term}")
|
123
|
+
redis.smembers("linked_to:#{term}").each do |key|
|
124
|
+
redis.srem("links:#{key}", term)
|
125
|
+
end
|
126
|
+
redis.del("linked_to:#{term}")
|
127
|
+
|
128
|
+
if redis.zrem("terms", term)
|
129
|
+
response.reply("#{term} has been deleted.")
|
130
|
+
else
|
131
|
+
response.reply("#{term} does not exist.")
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
144
135
|
private
|
145
136
|
|
137
|
+
def cooling_down?(term, user_id, response)
|
138
|
+
ttl = redis.ttl("cooldown:#{user_id}:#{term}")
|
139
|
+
|
140
|
+
if ttl >= 0
|
141
|
+
cooldown_message =
|
142
|
+
"You cannot modify #{term} for another #{ttl} second"
|
143
|
+
cooldown_message << (ttl == 1 ? "." : "s.")
|
144
|
+
response.reply cooldown_message
|
145
|
+
return true
|
146
|
+
else
|
147
|
+
return false
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def define_dynamic_routes(pattern)
|
152
|
+
self.class.route(
|
153
|
+
%r{(#{pattern})\+\+},
|
154
|
+
:increment,
|
155
|
+
help: { "TERM++" => "Increments TERM by one." }
|
156
|
+
)
|
157
|
+
|
158
|
+
self.class.route(
|
159
|
+
%r{(#{pattern})\-\-},
|
160
|
+
:decrement,
|
161
|
+
help: { "TERM--" => "Decrements TERM by one." }
|
162
|
+
)
|
163
|
+
|
164
|
+
self.class.route(
|
165
|
+
%r{(#{pattern})~~},
|
166
|
+
:check,
|
167
|
+
help: { "TERM~~" => "Shows the current karma of TERM." }
|
168
|
+
)
|
169
|
+
|
170
|
+
self.class.route(
|
171
|
+
%r{^(#{pattern})\s*\+=\s*(#{pattern})},
|
172
|
+
:link,
|
173
|
+
command: true,
|
174
|
+
help: {
|
175
|
+
"TERM1 += TERM2" => <<-HELP.chomp
|
176
|
+
Links TERM2 to TERM1. TERM1's karma will then be displayed as the sum of its \
|
177
|
+
own and TERM2's karma.
|
178
|
+
HELP
|
179
|
+
}
|
180
|
+
)
|
181
|
+
|
182
|
+
self.class.route(
|
183
|
+
%r{^(#{pattern})\s*-=\s*(#{pattern})},
|
184
|
+
:unlink,
|
185
|
+
command: true,
|
186
|
+
help: {
|
187
|
+
"TERM1 -= TERM2" => <<-HELP.chomp
|
188
|
+
Unlinks TERM2 from TERM1. TERM1's karma will no longer be displayed as the sum \
|
189
|
+
of its own and TERM2's karma.
|
190
|
+
HELP
|
191
|
+
}
|
192
|
+
)
|
193
|
+
end
|
194
|
+
|
195
|
+
def define_static_routes
|
196
|
+
self.class.route(
|
197
|
+
%r{^karma\s+worst},
|
198
|
+
:list_worst,
|
199
|
+
command: true,
|
200
|
+
help: {
|
201
|
+
"karma worst [N]" => <<-HELP.chomp
|
202
|
+
Lists the bottom N terms by karma. N defaults to 5.
|
203
|
+
HELP
|
204
|
+
}
|
205
|
+
)
|
206
|
+
|
207
|
+
self.class.route(
|
208
|
+
%r{^karma\s+best},
|
209
|
+
:list_best,
|
210
|
+
command: true,
|
211
|
+
help: {
|
212
|
+
"karma best [N]" => <<-HELP.chomp
|
213
|
+
Lists the top N terms by karma. N defaults to 5.
|
214
|
+
HELP
|
215
|
+
}
|
216
|
+
)
|
217
|
+
|
218
|
+
self.class.route(
|
219
|
+
%r{^karma\s+modified},
|
220
|
+
:modified,
|
221
|
+
command: true,
|
222
|
+
help: {
|
223
|
+
"karma modified TERM" => <<-HELP.chomp
|
224
|
+
Lists the names of users who have upvoted or downvoted TERM.
|
225
|
+
HELP
|
226
|
+
}
|
227
|
+
)
|
228
|
+
|
229
|
+
self.class.route(
|
230
|
+
%r{^karma\s+delete},
|
231
|
+
:delete,
|
232
|
+
command: true,
|
233
|
+
restrict_to: :karma_admins,
|
234
|
+
help: {
|
235
|
+
"karma delete TERM" => <<-HELP.chomp
|
236
|
+
Permanently removes TERM and all its links. TERM is matched exactly as typed \
|
237
|
+
and does not adhere to the usual pattern for terms.
|
238
|
+
HELP
|
239
|
+
}
|
240
|
+
)
|
241
|
+
|
242
|
+
self.class.route(%r{^karma\s*$}, :list_best, command: true)
|
243
|
+
end
|
244
|
+
|
146
245
|
def modify(response, delta)
|
147
246
|
response.matches.each do |match|
|
148
247
|
term = normalize_term(match[0])
|
248
|
+
user_id = response.user.id
|
149
249
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
response.reply cooldown_message
|
156
|
-
return
|
157
|
-
else
|
158
|
-
redis.zincrby("terms", delta, term)
|
159
|
-
redis.sadd("modified:#{term}", response.user.id)
|
160
|
-
cooldown = Lita.config.handlers.karma.cooldown
|
161
|
-
if cooldown
|
162
|
-
redis.setex(
|
163
|
-
"cooldown:#{response.user.id}:#{term}",
|
164
|
-
cooldown.to_i,
|
165
|
-
1
|
166
|
-
)
|
167
|
-
end
|
168
|
-
end
|
250
|
+
return if cooling_down?(term, user_id, response)
|
251
|
+
|
252
|
+
redis.zincrby("terms", delta, term)
|
253
|
+
redis.sadd("modified:#{term}", user_id)
|
254
|
+
set_cooldown(term, response.user.id)
|
169
255
|
end
|
170
256
|
|
171
257
|
check(response)
|
172
258
|
end
|
173
259
|
|
174
260
|
def normalize_term(term)
|
175
|
-
|
261
|
+
term_normalizer = Lita.config.handlers.karma.term_normalizer
|
262
|
+
|
263
|
+
if term_normalizer.respond_to?(:call)
|
264
|
+
term_normalizer.call(term)
|
265
|
+
else
|
266
|
+
term.to_s.downcase.strip
|
267
|
+
end
|
176
268
|
end
|
177
269
|
|
178
270
|
def list(response, redis_command)
|
@@ -192,6 +284,35 @@ HELP
|
|
192
284
|
response.reply output
|
193
285
|
end
|
194
286
|
end
|
287
|
+
|
288
|
+
def scores_for(term)
|
289
|
+
own_score = total_score = redis.zscore("terms", term).to_i
|
290
|
+
links = []
|
291
|
+
|
292
|
+
redis.smembers("links:#{term}").each do |link|
|
293
|
+
link_score = redis.zscore("terms", link).to_i
|
294
|
+
links << "#{link}: #{link_score}"
|
295
|
+
total_score += link_score
|
296
|
+
end
|
297
|
+
|
298
|
+
[total_score, own_score, links]
|
299
|
+
end
|
300
|
+
|
301
|
+
def set_cooldown(term, user_id)
|
302
|
+
cooldown = Lita.config.handlers.karma.cooldown
|
303
|
+
|
304
|
+
if cooldown
|
305
|
+
redis.setex(
|
306
|
+
"cooldown:#{user_id}:#{term}",
|
307
|
+
cooldown.to_i,
|
308
|
+
1
|
309
|
+
)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
def term_pattern
|
314
|
+
self.class.term_pattern
|
315
|
+
end
|
195
316
|
end
|
196
317
|
|
197
318
|
Lita.register_handler(Karma)
|
data/lita-karma.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = "lita-karma"
|
3
|
-
spec.version = "
|
3
|
+
spec.version = "2.0.0"
|
4
4
|
spec.authors = ["Jimmy Cuadra"]
|
5
5
|
spec.email = ["jimmy@jimmycuadra.com"]
|
6
6
|
spec.description = %q{A Lita handler for tracking karma points for arbitrary terms.}
|
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
14
14
|
spec.require_paths = ["lib"]
|
15
15
|
|
16
|
-
spec.add_runtime_dependency "lita", "~> 2.
|
16
|
+
spec.add_runtime_dependency "lita", "~> 2.6"
|
17
17
|
|
18
18
|
spec.add_development_dependency "bundler", "~> 1.3"
|
19
19
|
spec.add_development_dependency "rake"
|
@@ -1,7 +1,13 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Lita::Handlers::Karma, lita_handler: true do
|
4
|
-
|
4
|
+
let(:payload) { double("payload") }
|
5
|
+
|
6
|
+
before do
|
7
|
+
Lita.config.handlers.karma.cooldown = nil
|
8
|
+
described_class.routes.clear
|
9
|
+
subject.define_routes(payload)
|
10
|
+
end
|
5
11
|
|
6
12
|
it { routes("foo++").to(:increment) }
|
7
13
|
it { routes("foo--").to(:decrement) }
|
@@ -9,10 +15,29 @@ describe Lita::Handlers::Karma, lita_handler: true do
|
|
9
15
|
it { routes_command("karma best").to(:list_best) }
|
10
16
|
it { routes_command("karma worst").to(:list_worst) }
|
11
17
|
it { routes_command("karma modified").to(:modified) }
|
18
|
+
it { routes_command("karma delete").to(:delete) }
|
12
19
|
it { routes_command("karma").to(:list_best) }
|
13
20
|
it { routes_command("foo += bar").to(:link) }
|
14
21
|
it { routes_command("foo -= bar").to(:unlink) }
|
15
22
|
it { doesnt_route("+++++").to(:increment) }
|
23
|
+
it { doesnt_route("-----").to(:decrement) }
|
24
|
+
|
25
|
+
describe "#update_data" do
|
26
|
+
before { subject.redis.flushdb }
|
27
|
+
|
28
|
+
it "adds reverse link data for all linked terms" do
|
29
|
+
subject.redis.sadd("links:foo", ["bar", "baz"])
|
30
|
+
subject.upgrade_data(payload)
|
31
|
+
expect(subject.redis.sismember("linked_to:bar", "foo")).to be_true
|
32
|
+
expect(subject.redis.sismember("linked_to:baz", "foo")).to be_true
|
33
|
+
end
|
34
|
+
|
35
|
+
it "skips the update if it's already been done" do
|
36
|
+
expect(subject.redis).to receive(:keys).once.and_return([])
|
37
|
+
subject.upgrade_data(payload)
|
38
|
+
subject.upgrade_data(payload)
|
39
|
+
end
|
40
|
+
end
|
16
41
|
|
17
42
|
describe "#increment" do
|
18
43
|
it "increases the term's score by one and says the new score" do
|
@@ -43,16 +68,6 @@ describe Lita::Handlers::Karma, lita_handler: true do
|
|
43
68
|
send_message("FOO++")
|
44
69
|
expect(replies.last).to eq("foo: 2")
|
45
70
|
end
|
46
|
-
|
47
|
-
it "matches multi-word terms bounded by delimeters" do
|
48
|
-
send_message(":Some Thing:++")
|
49
|
-
expect(replies.last).to eq("some thing: 1")
|
50
|
-
end
|
51
|
-
|
52
|
-
it "matches terms with symbols that are bounded by delimeters" do
|
53
|
-
send_message("<C++>++")
|
54
|
-
expect(replies.last).to eq("c++: 1")
|
55
|
-
end
|
56
71
|
end
|
57
72
|
|
58
73
|
describe "#decrement" do
|
@@ -78,11 +93,6 @@ describe Lita::Handlers::Karma, lita_handler: true do
|
|
78
93
|
send_message("foo--")
|
79
94
|
expect(replies.last).to match(/cannot modify foo/)
|
80
95
|
end
|
81
|
-
|
82
|
-
it "matches multi-word terms bounded by delimeters" do
|
83
|
-
send_message(":Some Thing:--")
|
84
|
-
expect(replies.last).to eq("some thing: -1")
|
85
|
-
end
|
86
96
|
end
|
87
97
|
|
88
98
|
describe "#check" do
|
@@ -95,11 +105,6 @@ describe Lita::Handlers::Karma, lita_handler: true do
|
|
95
105
|
send_message("foo~~ bar~~")
|
96
106
|
expect(replies).to eq(["foo: 0", "bar: 0"])
|
97
107
|
end
|
98
|
-
|
99
|
-
it "matches multi-word terms bounded by delimeters" do
|
100
|
-
send_message(":Some Thing:~~")
|
101
|
-
expect(replies.last).to eq("some thing: 0")
|
102
|
-
end
|
103
108
|
end
|
104
109
|
|
105
110
|
describe "#list" do
|
@@ -214,4 +219,86 @@ MSG
|
|
214
219
|
expect(replies.last).to eq(user.name)
|
215
220
|
end
|
216
221
|
end
|
222
|
+
|
223
|
+
describe "#delete" do
|
224
|
+
before do
|
225
|
+
allow(Lita::Authorization).to receive(:user_in_group?).and_return(true)
|
226
|
+
end
|
227
|
+
|
228
|
+
it "deletes the term" do
|
229
|
+
send_message("foo++")
|
230
|
+
send_command("karma delete foo")
|
231
|
+
expect(replies.last).to eq("foo has been deleted.")
|
232
|
+
send_message("foo~~")
|
233
|
+
expect(replies.last).to eq("foo: 0")
|
234
|
+
end
|
235
|
+
|
236
|
+
it "replies with a warning if the term doesn't exist" do
|
237
|
+
send_command("karma delete foo")
|
238
|
+
expect(replies.last).to eq("foo does not exist.")
|
239
|
+
end
|
240
|
+
|
241
|
+
it "matches terms exactly, including leading whitespace" do
|
242
|
+
term = " 'foo bar* 'baz''/ :"
|
243
|
+
subject.redis.zincrby("terms", 1, term)
|
244
|
+
send_command("karma delete #{term}")
|
245
|
+
expect(replies.last).to include("has been deleted")
|
246
|
+
end
|
247
|
+
|
248
|
+
it "clears the modification list" do
|
249
|
+
send_message("foo++")
|
250
|
+
send_command("karma delete foo")
|
251
|
+
send_command("karma modified foo")
|
252
|
+
expect(replies.last).to eq("foo has never been modified.")
|
253
|
+
end
|
254
|
+
|
255
|
+
it "clears the deleted term's links" do
|
256
|
+
send_command("foo += bar")
|
257
|
+
send_command("foo += baz")
|
258
|
+
send_command("karma delete foo")
|
259
|
+
send_message("foo++")
|
260
|
+
expect(replies.last).to eq("foo: 1")
|
261
|
+
end
|
262
|
+
|
263
|
+
it "clears links from other terms connected to the deleted term" do
|
264
|
+
send_command("bar += foo")
|
265
|
+
send_command("baz += foo")
|
266
|
+
send_command("karma delete foo")
|
267
|
+
send_message("bar++")
|
268
|
+
expect(replies.last).to eq("bar: 1")
|
269
|
+
send_message("baz++")
|
270
|
+
expect(replies.last).to eq("baz: 1")
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
describe "custom term patterns and normalization" do
|
275
|
+
before do
|
276
|
+
Lita.config.handlers.karma.term_pattern = /[<:]([^>:]+)[>:]/
|
277
|
+
Lita.config.handlers.karma.term_normalizer = lambda do |term|
|
278
|
+
term.to_s.downcase.strip.sub(/[<:]([^>:]+)[>:]/, '\1')
|
279
|
+
end
|
280
|
+
described_class.routes.clear
|
281
|
+
subject.define_routes(payload)
|
282
|
+
end
|
283
|
+
|
284
|
+
it "increments multi-word terms bounded by delimeters" do
|
285
|
+
send_message(":Some Thing:++")
|
286
|
+
expect(replies.last).to eq("some thing: 1")
|
287
|
+
end
|
288
|
+
|
289
|
+
it "increments terms with symbols that are bounded by delimeters" do
|
290
|
+
send_message("<C++>++")
|
291
|
+
expect(replies.last).to eq("c++: 1")
|
292
|
+
end
|
293
|
+
|
294
|
+
it "decrements multi-word terms bounded by delimeters" do
|
295
|
+
send_message(":Some Thing:--")
|
296
|
+
expect(replies.last).to eq("some thing: -1")
|
297
|
+
end
|
298
|
+
|
299
|
+
it "checks multi-word terms bounded by delimeters" do
|
300
|
+
send_message(":Some Thing:~~")
|
301
|
+
expect(replies.last).to eq("some thing: 0")
|
302
|
+
end
|
303
|
+
end
|
217
304
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lita-karma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.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: 2013-
|
11
|
+
date: 2013-10-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: lita
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '2.
|
19
|
+
version: '2.6'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '2.
|
26
|
+
version: '2.6'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -132,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
132
132
|
version: '0'
|
133
133
|
requirements: []
|
134
134
|
rubyforge_project:
|
135
|
-
rubygems_version: 2.
|
135
|
+
rubygems_version: 2.1.3
|
136
136
|
signing_key:
|
137
137
|
specification_version: 4
|
138
138
|
summary: A Lita handler for tracking karma points for arbitrary terms.
|