marvin 0.8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/marvin +33 -0
- data/handlers/debug_handler.rb +5 -0
- data/handlers/hello_world.rb +9 -0
- data/handlers/keiki_thwopper.rb +21 -0
- data/handlers/simple_logger.rb +24 -0
- data/handlers/tweet_tweet.rb +19 -0
- data/lib/marvin.rb +56 -0
- data/lib/marvin/abstract_client.rb +146 -0
- data/lib/marvin/abstract_parser.rb +29 -0
- data/lib/marvin/base.rb +195 -0
- data/lib/marvin/client/actions.rb +104 -0
- data/lib/marvin/client/default_handlers.rb +97 -0
- data/lib/marvin/command_handler.rb +91 -0
- data/lib/marvin/console.rb +50 -0
- data/lib/marvin/core_commands.rb +49 -0
- data/lib/marvin/distributed.rb +8 -0
- data/lib/marvin/distributed/client.rb +225 -0
- data/lib/marvin/distributed/handler.rb +85 -0
- data/lib/marvin/distributed/protocol.rb +88 -0
- data/lib/marvin/distributed/server.rb +154 -0
- data/lib/marvin/dsl.rb +103 -0
- data/lib/marvin/exception_tracker.rb +19 -0
- data/lib/marvin/exceptions.rb +11 -0
- data/lib/marvin/irc.rb +7 -0
- data/lib/marvin/irc/client.rb +168 -0
- data/lib/marvin/irc/event.rb +39 -0
- data/lib/marvin/irc/replies.rb +154 -0
- data/lib/marvin/logging_handler.rb +76 -0
- data/lib/marvin/middle_man.rb +103 -0
- data/lib/marvin/parsers.rb +9 -0
- data/lib/marvin/parsers/command.rb +107 -0
- data/lib/marvin/parsers/prefixes.rb +8 -0
- data/lib/marvin/parsers/prefixes/host_mask.rb +35 -0
- data/lib/marvin/parsers/prefixes/server.rb +24 -0
- data/lib/marvin/parsers/ragel_parser.rb +720 -0
- data/lib/marvin/parsers/ragel_parser.rl +143 -0
- data/lib/marvin/parsers/simple_parser.rb +35 -0
- data/lib/marvin/settings.rb +31 -0
- data/lib/marvin/test_client.rb +58 -0
- data/lib/marvin/util.rb +54 -0
- data/templates/boot.erb +3 -0
- data/templates/connections.yml.erb +10 -0
- data/templates/debug_handler.erb +5 -0
- data/templates/hello_world.erb +10 -0
- data/templates/rakefile.erb +15 -0
- data/templates/settings.yml.erb +8 -0
- data/templates/setup.erb +31 -0
- data/templates/test_helper.erb +17 -0
- data/test/abstract_client_test.rb +63 -0
- data/test/parser_comparison.rb +62 -0
- data/test/parser_test.rb +266 -0
- data/test/test_helper.rb +62 -0
- data/test/util_test.rb +57 -0
- metadata +136 -0
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
require File.join(File.dirname(__FILE__),'../lib/marvin')
|
3
|
+
|
4
|
+
LINES = [
|
5
|
+
":irc.darth.vpn.spork.in 366 testbot #testing :End of NAMES list",
|
6
|
+
":Helsinki.FI.EU.Undernet.org PONG Helsinki.FI.EU.Undernet.org :Helsinki.FI.EU.Undernet.org",
|
7
|
+
":testnick USER guest tolmoon tolsun :Ronnie Reagan",
|
8
|
+
"LIST #twilight_zone,#42",
|
9
|
+
":WiZ LINKS *.bu.edu *.edu",
|
10
|
+
":Angel PRIVMSG Wiz :Hello are you receiving this message ?",
|
11
|
+
":RelayBot!n=MarvinBo@203.161.81.201.static.amnet.net.au JOIN :#relayrelay",
|
12
|
+
":SuttoL!n=SuttoL@li6-47.members.linode.com PRIVMSG #relayrelay :testing...",
|
13
|
+
":wolfe.freenode.net 004 MarvinBot3000 wolfe.freenode.net hyperion-1.0.2b aAbBcCdDeEfFGhHiIjkKlLmMnNopPQrRsStTuUvVwWxXyYzZ01234569*@ bcdefFhiIklmnoPqstv"
|
14
|
+
]
|
15
|
+
PARSERS = [Marvin::Parsers::SimpleParser, Marvin::Parsers::RagelParser]
|
16
|
+
|
17
|
+
LINES.each do |line|
|
18
|
+
|
19
|
+
puts "Processing: #{line}"
|
20
|
+
puts ""
|
21
|
+
cmd = []
|
22
|
+
|
23
|
+
PARSERS.each do |p|
|
24
|
+
parser = p.new(line)
|
25
|
+
ev = parser.to_event
|
26
|
+
puts "Parser: #{p.name}"
|
27
|
+
if ev.nil?
|
28
|
+
puts "Unknown Event"
|
29
|
+
else
|
30
|
+
puts ev.to_hash.inspect
|
31
|
+
end
|
32
|
+
puts ""
|
33
|
+
end
|
34
|
+
puts ""
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
puts ""
|
39
|
+
puts ""
|
40
|
+
puts "==============="
|
41
|
+
puts "| SPEED TESTS |"
|
42
|
+
puts "==============="
|
43
|
+
puts ""
|
44
|
+
|
45
|
+
width = PARSERS.map { |p| p.name.length }.max + 2
|
46
|
+
|
47
|
+
ITERATIONS = 100
|
48
|
+
|
49
|
+
Benchmark.bm(width) do |b|
|
50
|
+
PARSERS.each do |parser|
|
51
|
+
b.report("#{parser.name}: ") do
|
52
|
+
LINES.each do |l|
|
53
|
+
ITERATIONS.times do
|
54
|
+
e = parser.new(l).to_event
|
55
|
+
unless e.nil?
|
56
|
+
e.to_hash # Get a hash
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/test/parser_test.rb
ADDED
@@ -0,0 +1,266 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
# In reality this tests several different classes:
|
4
|
+
# 1) The parser itself
|
5
|
+
# 2) The Command class
|
6
|
+
# 3) The two different types of prefixes
|
7
|
+
# 4) The Event class
|
8
|
+
class ParserTest < Test::Unit::TestCase
|
9
|
+
|
10
|
+
# The default parser
|
11
|
+
@@parser = Marvin::Settings.parser
|
12
|
+
|
13
|
+
context "When parsing a LIST" do
|
14
|
+
setup { @parsed = @@parser.new("LIST #twilight_zone,#42") }
|
15
|
+
|
16
|
+
should "not be nil" do
|
17
|
+
assert !@parsed.nil?
|
18
|
+
end
|
19
|
+
|
20
|
+
should "have a command" do
|
21
|
+
assert !@parsed.command.nil?
|
22
|
+
end
|
23
|
+
|
24
|
+
should "have not a prefix" do
|
25
|
+
assert @parsed.command.prefix.nil?
|
26
|
+
end
|
27
|
+
|
28
|
+
should "have a code of LIST" do
|
29
|
+
assert_equal "LIST", @parsed.command.code
|
30
|
+
end
|
31
|
+
|
32
|
+
should "have the correct arguments" do
|
33
|
+
assert_equal ["#twilight_zone,#42"], @parsed.command.params
|
34
|
+
end
|
35
|
+
|
36
|
+
should "be able to convert to an event" do
|
37
|
+
assert !@parsed.to_event.nil?
|
38
|
+
end
|
39
|
+
|
40
|
+
should "have the correct incoming event name" do
|
41
|
+
assert_equal :incoming_list, @parsed.to_event.to_incoming_event_name
|
42
|
+
end
|
43
|
+
|
44
|
+
should "have the correct outgoing event name" do
|
45
|
+
assert_equal :outgoing_list, @parsed.to_event.to_outgoing_event_name
|
46
|
+
end
|
47
|
+
|
48
|
+
should "convert to the correct hash" do
|
49
|
+
assert_equal({:channel => "#twilight_zone,#42", :target => ""}, @parsed.to_event.to_hash)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
context "When parsing a JOIN" do
|
55
|
+
setup { @parsed = @@parser.new(":RelayBot!n=MarvinBot@static.amnet.net.au JOIN :#relayrelay") }
|
56
|
+
|
57
|
+
should "not be nil" do
|
58
|
+
assert !@parsed.nil?
|
59
|
+
end
|
60
|
+
|
61
|
+
should "have a command" do
|
62
|
+
assert !@parsed.command.nil?
|
63
|
+
end
|
64
|
+
|
65
|
+
should "have a prefix" do
|
66
|
+
assert !@parsed.command.prefix.nil?
|
67
|
+
end
|
68
|
+
|
69
|
+
should "have a code of JOIN" do
|
70
|
+
assert_equal "JOIN", @parsed.command.code
|
71
|
+
end
|
72
|
+
|
73
|
+
should "have the correct arguments" do
|
74
|
+
assert_equal ["#relayrelay"], @parsed.command.params
|
75
|
+
end
|
76
|
+
|
77
|
+
should "have a host mask" do
|
78
|
+
assert @parsed.command.prefix.is_a?(Marvin::Parsers::Prefixes::HostMask)
|
79
|
+
end
|
80
|
+
|
81
|
+
should "have the correct nick" do
|
82
|
+
assert_equal "RelayBot", @parsed.command.prefix.nick
|
83
|
+
end
|
84
|
+
|
85
|
+
should "have the correct user" do
|
86
|
+
assert_equal "n=MarvinBot", @parsed.command.prefix.user
|
87
|
+
end
|
88
|
+
|
89
|
+
should "have the correct host" do
|
90
|
+
assert_equal "static.amnet.net.au", @parsed.command.prefix.host
|
91
|
+
end
|
92
|
+
|
93
|
+
should "be able to convert to an event" do
|
94
|
+
assert !@parsed.to_event.nil?
|
95
|
+
end
|
96
|
+
|
97
|
+
should "have the correct incoming event name" do
|
98
|
+
assert_equal :incoming_join, @parsed.to_event.to_incoming_event_name
|
99
|
+
end
|
100
|
+
|
101
|
+
should "have the correct outgoing event name" do
|
102
|
+
assert_equal :outgoing_join, @parsed.to_event.to_outgoing_event_name
|
103
|
+
end
|
104
|
+
|
105
|
+
should "convert to the correct hash" do
|
106
|
+
assert_equal({:target => "#relayrelay", :key => ""}.merge(@parsed.command.prefix.to_hash), @parsed.to_event.to_hash)
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
context "When parsing a PRIVMSG" do
|
112
|
+
setup { @parsed = @@parser.new(":SuttoL!n=SuttoL@sutto.net PRIVMSG #relayrelay :testing...") }
|
113
|
+
|
114
|
+
should "not be nil" do
|
115
|
+
assert !@parsed.nil?
|
116
|
+
end
|
117
|
+
|
118
|
+
should "have a command" do
|
119
|
+
assert !@parsed.command.nil?
|
120
|
+
end
|
121
|
+
|
122
|
+
should "have a prefix" do
|
123
|
+
assert !@parsed.command.prefix.nil?
|
124
|
+
end
|
125
|
+
|
126
|
+
should "have a code of PRIVMSG" do
|
127
|
+
assert_equal "PRIVMSG", @parsed.command.code
|
128
|
+
end
|
129
|
+
|
130
|
+
should "have the correct arguments" do
|
131
|
+
assert_equal ["#relayrelay", "testing..."], @parsed.command.params
|
132
|
+
end
|
133
|
+
|
134
|
+
should "have a host mask" do
|
135
|
+
assert @parsed.command.prefix.is_a?(Marvin::Parsers::Prefixes::HostMask)
|
136
|
+
end
|
137
|
+
|
138
|
+
should "have the correct nick" do
|
139
|
+
assert_equal "SuttoL", @parsed.command.prefix.nick
|
140
|
+
end
|
141
|
+
|
142
|
+
should "have the correct user" do
|
143
|
+
assert_equal "n=SuttoL", @parsed.command.prefix.user
|
144
|
+
end
|
145
|
+
|
146
|
+
should "have the correct host" do
|
147
|
+
assert_equal "sutto.net", @parsed.command.prefix.host
|
148
|
+
end
|
149
|
+
|
150
|
+
should "be able to convert to an event" do
|
151
|
+
assert !@parsed.to_event.nil?
|
152
|
+
end
|
153
|
+
|
154
|
+
should "have the correct incoming event name" do
|
155
|
+
assert_equal :incoming_message, @parsed.to_event.to_incoming_event_name
|
156
|
+
end
|
157
|
+
|
158
|
+
should "have the correct outgoing event name" do
|
159
|
+
assert_equal :outgoing_message, @parsed.to_event.to_outgoing_event_name
|
160
|
+
end
|
161
|
+
|
162
|
+
should "convert to the correct hash" do
|
163
|
+
assert_equal({:target => "#relayrelay", :message => "testing..."}.merge(@parsed.command.prefix.to_hash), @parsed.to_event.to_hash)
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
|
168
|
+
context "When parsing a numeric - 366" do
|
169
|
+
setup { @parsed = @@parser.new(":irc.darth.vpn.spork.in 366 testbot #testing :End of NAMES list") }
|
170
|
+
|
171
|
+
should "not be nil" do
|
172
|
+
assert !@parsed.nil?
|
173
|
+
end
|
174
|
+
|
175
|
+
should "have a command" do
|
176
|
+
assert !@parsed.command.nil?
|
177
|
+
end
|
178
|
+
|
179
|
+
should "have a prefix" do
|
180
|
+
assert !@parsed.command.prefix.nil?
|
181
|
+
end
|
182
|
+
|
183
|
+
should "have a code of 366" do
|
184
|
+
assert_equal "366", @parsed.command.code
|
185
|
+
end
|
186
|
+
|
187
|
+
should "have the correct arguments" do
|
188
|
+
assert_equal ["testbot", "#testing", "End of NAMES list"], @parsed.command.params
|
189
|
+
end
|
190
|
+
|
191
|
+
should "have a host mask" do
|
192
|
+
assert @parsed.command.prefix.is_a?(Marvin::Parsers::Prefixes::Server)
|
193
|
+
end
|
194
|
+
|
195
|
+
should "have the correct name" do
|
196
|
+
assert_equal "irc.darth.vpn.spork.in", @parsed.command.prefix.name
|
197
|
+
end
|
198
|
+
|
199
|
+
should "be able to convert to an event" do
|
200
|
+
assert !@parsed.to_event.nil?
|
201
|
+
end
|
202
|
+
|
203
|
+
should "have the correct incoming event name" do
|
204
|
+
assert_equal :incoming_numeric, @parsed.to_event.to_incoming_event_name
|
205
|
+
end
|
206
|
+
|
207
|
+
should "have the correct outgoing event name" do
|
208
|
+
assert_equal :outgoing_numeric, @parsed.to_event.to_outgoing_event_name
|
209
|
+
end
|
210
|
+
|
211
|
+
should "convert to the correct hash" do
|
212
|
+
assert_equal({:code => "366", :data => "testbot #testing :End of NAMES list"}.merge(@parsed.command.prefix.to_hash), @parsed.to_event.to_hash)
|
213
|
+
end
|
214
|
+
|
215
|
+
end
|
216
|
+
|
217
|
+
context "When parsing a numeric - 004" do
|
218
|
+
setup { @parsed = @@parser.new(":wolfe.freenode.net 004 MarvinBot3000 wolfe.freenode.net hyperion-1.0.2b aAbBcCdDeEfFGhHiIjkKlLmMnNopPQrRsStTuUvVwWxXyYzZ01234569*@ bcdefFhiIklmnoPqstv") }
|
219
|
+
|
220
|
+
should "not be nil" do
|
221
|
+
assert !@parsed.nil?
|
222
|
+
end
|
223
|
+
|
224
|
+
should "have a command" do
|
225
|
+
assert !@parsed.command.nil?
|
226
|
+
end
|
227
|
+
|
228
|
+
should "have a prefix" do
|
229
|
+
assert !@parsed.command.prefix.nil?
|
230
|
+
end
|
231
|
+
|
232
|
+
should "have a code of 366" do
|
233
|
+
assert_equal "004", @parsed.command.code
|
234
|
+
end
|
235
|
+
|
236
|
+
should "have the correct arguments" do
|
237
|
+
assert_equal ["MarvinBot3000" , "wolfe.freenode.net", "hyperion-1.0.2b", "aAbBcCdDeEfFGhHiIjkKlLmMnNopPQrRsStTuUvVwWxXyYzZ01234569*@", "bcdefFhiIklmnoPqstv"], @parsed.command.params
|
238
|
+
end
|
239
|
+
|
240
|
+
should "have a host mask" do
|
241
|
+
assert @parsed.command.prefix.is_a?(Marvin::Parsers::Prefixes::Server)
|
242
|
+
end
|
243
|
+
|
244
|
+
should "have the correct name" do
|
245
|
+
assert_equal "wolfe.freenode.net", @parsed.command.prefix.name
|
246
|
+
end
|
247
|
+
|
248
|
+
should "be able to convert to an event" do
|
249
|
+
assert !@parsed.to_event.nil?
|
250
|
+
end
|
251
|
+
|
252
|
+
should "have the correct incoming event name" do
|
253
|
+
assert_equal :incoming_numeric, @parsed.to_event.to_incoming_event_name
|
254
|
+
end
|
255
|
+
|
256
|
+
should "have the correct outgoing event name" do
|
257
|
+
assert_equal :outgoing_numeric, @parsed.to_event.to_outgoing_event_name
|
258
|
+
end
|
259
|
+
|
260
|
+
should "convert to the correct hash" do
|
261
|
+
assert_equal({:code => "004", :data => "MarvinBot3000 wolfe.freenode.net hyperion-1.0.2b aAbBcCdDeEfFGhHiIjkKlLmMnNopPQrRsStTuUvVwWxXyYzZ01234569*@ bcdefFhiIklmnoPqstv"}.merge(@parsed.command.prefix.to_hash), @parsed.to_event.to_hash)
|
262
|
+
end
|
263
|
+
|
264
|
+
end
|
265
|
+
|
266
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
# Testing dependencies
|
4
|
+
require 'test/unit'
|
5
|
+
require 'shoulda'
|
6
|
+
# RedGreen doesn't seem to be needed under 1.9
|
7
|
+
require 'redgreen' if RUBY_VERSION < "1.9"
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
root_directory = Pathname.new(__FILE__).dirname.join("..").expand_path
|
11
|
+
require root_directory.join("lib", "marvin")
|
12
|
+
|
13
|
+
Marvin::Settings.setup!
|
14
|
+
Marvin::Logger.setup!
|
15
|
+
|
16
|
+
Marvin::Settings.client = Marvin::TestClient
|
17
|
+
|
18
|
+
class Test::Unit::TestCase
|
19
|
+
|
20
|
+
@test_client = nil
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
def client(force_new = false)
|
25
|
+
@test_client = Marvin::TestClient.new if force_new || @test_client.nil?
|
26
|
+
@test_client
|
27
|
+
end
|
28
|
+
|
29
|
+
# Short hand for creating a class with
|
30
|
+
# a given class_eval block.
|
31
|
+
def class_via(*args, &blk)
|
32
|
+
klass = Class.new(*args)
|
33
|
+
klass.class_eval(&blk) unless blk.blank?
|
34
|
+
return klass
|
35
|
+
end
|
36
|
+
|
37
|
+
# Short hand for creating a test class
|
38
|
+
# for a set of mixins - give it the modules
|
39
|
+
# and it will include them all.
|
40
|
+
def test_class_for(*mods, &blk)
|
41
|
+
klass = Class.new
|
42
|
+
klass.class_eval { include(*mods) }
|
43
|
+
klass.class_eval(&blk) unless blk.blank?
|
44
|
+
return klass
|
45
|
+
end
|
46
|
+
|
47
|
+
def assert_dispatched(name, position = -1, opts = nil)
|
48
|
+
res = client.dispatched_events[position]
|
49
|
+
assert !res.nil?
|
50
|
+
assert_equal name, res[0]
|
51
|
+
assert_equal opts, res[1] if !opts.nil?
|
52
|
+
end
|
53
|
+
|
54
|
+
def assert_sent_line(line, position = -1)
|
55
|
+
assert_equal line, client.outgoing_commands[position]
|
56
|
+
end
|
57
|
+
|
58
|
+
def assert_resets_client
|
59
|
+
assert_equal [], client(true).dispatched_events
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
data/test/util_test.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class UtilTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "Converting a string to a channel name" do
|
6
|
+
|
7
|
+
should "not convert it if it starts with #" do
|
8
|
+
assert_equal "#offrails", Marvin::Util.channel_name("#offrails")
|
9
|
+
end
|
10
|
+
|
11
|
+
should "append a # if not present" do
|
12
|
+
assert_equal "#offrails", Marvin::Util.channel_name("offrails")
|
13
|
+
end
|
14
|
+
|
15
|
+
should "also be available as chan" do
|
16
|
+
assert_equal "#offrails", Marvin::Util.chan("#offrails")
|
17
|
+
assert_equal "#offrails", Marvin::Util.chan("offrails")
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
context "Parsing arguments" do
|
23
|
+
|
24
|
+
should "parse 'a b c' as ['a', 'b', 'c']" do
|
25
|
+
assert_equal ['a', 'b', 'c'], Marvin::Util.arguments("a b c")
|
26
|
+
end
|
27
|
+
|
28
|
+
should "parse 'a b :c d' as ['a', 'b', 'c d']" do
|
29
|
+
assert_equal ['a', 'b', 'c d'], Marvin::Util.arguments("a b :c d")
|
30
|
+
end
|
31
|
+
|
32
|
+
should "parse 'a :b c :d e' as ['a', 'b c :d e']" do
|
33
|
+
assert_equal ['a', 'b c :d e'], Marvin::Util.arguments('a :b c :d e')
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
context "Preparing last parameters" do
|
39
|
+
|
40
|
+
should "prepend a :" do
|
41
|
+
assert_equal ':zomg ninjas', Marvin::Util.last_param('zomg ninjas')
|
42
|
+
assert_equal '::zomg ninjas', Marvin::Util.last_param(':zomg ninjas')
|
43
|
+
end
|
44
|
+
|
45
|
+
should "strip the input" do
|
46
|
+
assert_equal ':zomg ninjas', Marvin::Util.last_param(' zomg ninjas ')
|
47
|
+
end
|
48
|
+
|
49
|
+
should "be available as lp" do
|
50
|
+
assert_equal ':zomg ninjas', Marvin::Util.lp('zomg ninjas')
|
51
|
+
assert_equal '::zomg ninjas', Marvin::Util.lp(':zomg ninjas')
|
52
|
+
assert_equal ':zomg ninjas', Marvin::Util.lp(' zomg ninjas ')
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|