Auto 4.0.0.alpha.1-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +7 -0
- data/Gemfile +19 -0
- data/LICENSE.md +31 -0
- data/README.md +109 -0
- data/Rakefile +41 -0
- data/bin/auto +110 -0
- data/bin/auto-conf +45 -0
- data/conf/example.json +100 -0
- data/conf/example.yml +125 -0
- data/docs/Contributing.md +77 -0
- data/docs/Events.md +103 -0
- data/docs/Todo.md +21 -0
- data/docs/Upgrade.md +16 -0
- data/ext/dsl_base.c +49 -0
- data/ext/libauto/auto.h +20 -0
- data/ext/libauto/extconf.rb +16 -0
- data/ext/libauto/libauto.c +29 -0
- data/ext/libauto/libauto.h +28 -0
- data/ext/libauto/logger.c +177 -0
- data/ext/libauto/logger.h +44 -0
- data/lib/auto.rb +43 -0
- data/lib/auto/api.rb +7 -0
- data/lib/auto/api/events.rb +166 -0
- data/lib/auto/api/object.rb +29 -0
- data/lib/auto/api/plugin.rb +155 -0
- data/lib/auto/api/timers.rb +93 -0
- data/lib/auto/bot.rb +338 -0
- data/lib/auto/config.rb +181 -0
- data/lib/auto/configure.rb +410 -0
- data/lib/auto/configure/shell.rb +154 -0
- data/lib/auto/dsl/base.rb +74 -0
- data/lib/auto/dsl/irc.rb +13 -0
- data/lib/auto/irc.rb +8 -0
- data/lib/auto/irc/common.rb +63 -0
- data/lib/auto/irc/library.rb +89 -0
- data/lib/auto/irc/object/channel.rb +21 -0
- data/lib/auto/irc/object/entity.rb +90 -0
- data/lib/auto/irc/object/message.rb +99 -0
- data/lib/auto/irc/object/user.rb +139 -0
- data/lib/auto/irc/protocol.rb +164 -0
- data/lib/auto/irc/protocol/numerics.rb +60 -0
- data/lib/auto/irc/sasl/diffie_hellman.rb +36 -0
- data/lib/auto/irc/sasl/mech.rb +15 -0
- data/lib/auto/irc/sasl/mech/dh_blowfish.rb +83 -0
- data/lib/auto/irc/sasl/mech/plain.rb +39 -0
- data/lib/auto/irc/server.rb +301 -0
- data/lib/auto/irc/state/channel_manager.rb +6 -0
- data/lib/auto/irc/state/support.rb +142 -0
- data/lib/auto/irc/state/user_manager.rb +6 -0
- data/lib/auto/irc/std/commands.rb +99 -0
- data/lib/auto/irc/std/numerics.rb +216 -0
- data/lib/auto/rubyext/integer.rb +25 -0
- data/lib/auto/rubyext/string.rb +10 -0
- data/lib/auto/version.rb +18 -0
- data/lib/libauto.so +0 -0
- data/spec/api_events_spec.rb +68 -0
- data/spec/config_json_spec.rb +116 -0
- data/spec/config_other_spec.rb +29 -0
- data/spec/config_yaml_spec.rb +136 -0
- data/spec/helper.rb +19 -0
- data/spec/irc_object_entity_spec.rb +51 -0
- data/spec/logger_spec.rb +30 -0
- data/spec/plugin_base_spec.rb +35 -0
- data/spec/timers_spec.rb +42 -0
- metadata +238 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
# This code exists in the public domain.
|
2
|
+
|
3
|
+
# Extends Integer with some needed methods for Diffie-Hellman key exchange.
|
4
|
+
class Integer
|
5
|
+
|
6
|
+
# Compute self ^ e mod m
|
7
|
+
def mod_exp e, m
|
8
|
+
result = 1
|
9
|
+
b = self
|
10
|
+
while e > 0
|
11
|
+
result = (result * b) % m if e[0] == 1
|
12
|
+
e = e >> 1
|
13
|
+
b = (b * b) % m
|
14
|
+
end
|
15
|
+
return result
|
16
|
+
end
|
17
|
+
|
18
|
+
# A roundabout, slow but fun way of counting bits.
|
19
|
+
def bits_set
|
20
|
+
("%b" % self).count('1')
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
# vim: set ts=4 sts=2 sw=2 et:
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# This changes the String class in Ruby's standard library to make life easier
|
2
|
+
# by aliasing String#uc to String#upcase and String#dc to String#downcase
|
3
|
+
class String
|
4
|
+
alias_method :uc, :upcase
|
5
|
+
alias_method :dc, :downcase
|
6
|
+
alias_method :uc!, :upcase!
|
7
|
+
alias_method :dc!, :downcase!
|
8
|
+
end
|
9
|
+
|
10
|
+
# vim: set ts=4 sts=2 sw=2 et:
|
data/lib/auto/version.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
|
2
|
+
# This free software is distributed under the FreeBSD license (LICENSE.md).
|
3
|
+
|
4
|
+
module Auto
|
5
|
+
VERSIONSPEC = {
|
6
|
+
major: 4,
|
7
|
+
minor: 0,
|
8
|
+
patch: 0,
|
9
|
+
pre: 'alpha.1',
|
10
|
+
codename: 'phoenix'
|
11
|
+
}.freeze
|
12
|
+
VERSION = "#{VERSIONSPEC[:major]}.#{VERSIONSPEC[:minor]}.#{VERSIONSPEC[:patch]}"
|
13
|
+
VERSION.concat '.'+VERSIONSPEC[:pre] if VERSIONSPEC.include? :pre
|
14
|
+
VERSION.freeze
|
15
|
+
FULLVERSION = "#{VERSION}-#{VERSIONSPEC[:codename]}".freeze
|
16
|
+
end
|
17
|
+
|
18
|
+
# vim: set ts=4 sts=2 sw=2 et:
|
data/lib/libauto.so
ADDED
Binary file
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# Auto 4
|
2
|
+
# Copyright (c) 2013, Auto Project
|
3
|
+
# Distributed under the terms of the FreeBSD license (LICENSE.md).
|
4
|
+
require(File.expand_path('../helper.rb', __FILE__))
|
5
|
+
|
6
|
+
require 'auto/api/events'
|
7
|
+
|
8
|
+
describe 'Auto::API::Events' do
|
9
|
+
|
10
|
+
before do
|
11
|
+
@events = Auto::API::Events.new
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#on' do
|
15
|
+
it 'should return identification data' do
|
16
|
+
@events.on(:foo_bar) { nil }.must_be_instance_of Array
|
17
|
+
end
|
18
|
+
it 'should return sufficient identification data' do
|
19
|
+
@events.on(:meow_cat) { nil }.length.must_equal 3
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#call' do
|
24
|
+
before do
|
25
|
+
$m.opts.expects(:verbose?)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should call all hooks of given event' do
|
29
|
+
@ok = false
|
30
|
+
@events.on('bunnyEvent') { @ok = true }
|
31
|
+
@events.call('bunnyEvent')
|
32
|
+
@events.threads.each { |thr| thr.join }
|
33
|
+
@ok.must_equal true
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should call hooks in descending priority' do
|
37
|
+
@order = ''
|
38
|
+
@events.on(:kitten_event, 5) { @order << 'C' }
|
39
|
+
@events.on(:kitten_event, 1) { @order << 'A' }
|
40
|
+
@events.on(:kitten_event, 3) { @order << 'B' }
|
41
|
+
@events.call(:kitten_event)
|
42
|
+
@events.threads.each { |thr| thr.join }
|
43
|
+
@order.must_equal 'ABC'
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should suspend execution if false is received' do
|
47
|
+
@good = true
|
48
|
+
@events.on(:dragon_event, 1) { false }
|
49
|
+
@events.on(:dragon_event, 3) { @good = false }
|
50
|
+
@events.call(:dragon_event)
|
51
|
+
@events.threads.each { |thr| thr.join }
|
52
|
+
@good.must_equal true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#del' do
|
57
|
+
it 'should delete an event' do
|
58
|
+
@deleted = true
|
59
|
+
id = @events.on(:unicorn_event) { @deleted = false }
|
60
|
+
@events.del(id)
|
61
|
+
@events.call(:unicorn_event)
|
62
|
+
@deleted.must_equal true
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
# vim: set ts=4 sts=2 sw=2 et:
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# Auto 4
|
2
|
+
# Copyright (c) 2013, Auto Project
|
3
|
+
# Distributed under the terms of the FreeBSD license (LICENSE.md).
|
4
|
+
require(File.join(File.expand_path(File.dirname(__FILE__)), 'helper.rb'))
|
5
|
+
require 'auto/config'
|
6
|
+
|
7
|
+
describe "A configuration using JSON" do
|
8
|
+
|
9
|
+
JSON_ORIGINAL_CONF = <<EOF
|
10
|
+
{
|
11
|
+
// This is a comment; swarley+noxgirl=<3
|
12
|
+
"foo": {
|
13
|
+
"cat": ["meow","//purr"],
|
14
|
+
"cow": ["/* moo */"/* my loveybear wrote a really cool regexp that strips these comments*/],
|
15
|
+
"dinosaur": /* weirdly placed comments ftw */ ["rawr"]
|
16
|
+
}
|
17
|
+
}
|
18
|
+
EOF
|
19
|
+
|
20
|
+
JSON_NEW_CONF = <<EOF
|
21
|
+
{
|
22
|
+
// This is a comment; swarley+noxgirl=<3
|
23
|
+
"foo": {
|
24
|
+
"cat": ["meow","purr"],
|
25
|
+
"cow": ["moo"/* my loveybear wrote a really cool regexp that strips these comments*/],
|
26
|
+
"dinosaur": /* weirdly placed comments ftw */ ["rawr"],
|
27
|
+
"bunny": /* OMG BUNNIES <3 */ ["unimaginable cuteness that forces you to coo"]
|
28
|
+
}
|
29
|
+
}
|
30
|
+
EOF
|
31
|
+
|
32
|
+
JSON_BAD_CONF = <<EOF
|
33
|
+
THIS ARE RUBBISH
|
34
|
+
|
35
|
+
THAT W!LL F41L
|
36
|
+
|
37
|
+
...0R SHOULD
|
38
|
+
EOF
|
39
|
+
|
40
|
+
JSON_HASH_ORIGINAL = {
|
41
|
+
'foo' => {
|
42
|
+
'cat' => ['meow', '//purr'],
|
43
|
+
'cow' => ['/* moo */'],
|
44
|
+
'dinosaur' => ['rawr']
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
JSON_HASH_NEW = {
|
49
|
+
'foo' => {
|
50
|
+
'cat' => ['meow', 'purr'],
|
51
|
+
'cow' => ['moo'],
|
52
|
+
'dinosaur' => ['rawr'],
|
53
|
+
'bunny' => ['unimaginable cuteness that forces you to coo']
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
before do
|
58
|
+
File.open('.temp.json_config.json', 'w') do |io|
|
59
|
+
io.write JSON_ORIGINAL_CONF
|
60
|
+
end
|
61
|
+
|
62
|
+
@conf = Auto::Config.new('.temp.json_config.json')
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should have a type of JSON' do
|
66
|
+
@conf.type.must_equal :json
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should have @conf, a Hash' do
|
70
|
+
@conf.conf.class.must_equal Hash
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should point [x] to @conf[x]' do
|
74
|
+
@conf['foo'].must_be_same_as @conf.conf['foo']
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should have correctly processed data' do
|
78
|
+
@conf.conf.must_equal JSON_HASH_ORIGINAL
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should rehash on rehash!()' do
|
82
|
+
|
83
|
+
File.open('.temp.json_config.json', 'w') do |io|
|
84
|
+
io.write JSON_NEW_CONF
|
85
|
+
end
|
86
|
+
|
87
|
+
$m.events.expects(:call).with('bot:onRehash')
|
88
|
+
@conf.rehash!
|
89
|
+
@conf.conf.must_equal JSON_HASH_NEW
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'should fail on rehash!() if data is bad' do
|
93
|
+
File.open('.temp.json_config.json', 'w') do |io|
|
94
|
+
io.write JSON_BAD_CONF
|
95
|
+
end
|
96
|
+
|
97
|
+
$m.expects(:debug)
|
98
|
+
$m.expects(:error)
|
99
|
+
@conf.rehash!.must_equal 0
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'should should revert to old data if rehash!() fails' do
|
103
|
+
File.open('.temp.json_config.json', 'w') do |io|
|
104
|
+
io.write JSON_BAD_CONF
|
105
|
+
end
|
106
|
+
$m.expects(:debug)
|
107
|
+
$m.expects(:error)
|
108
|
+
@conf.rehash!
|
109
|
+
@conf.conf.must_equal JSON_HASH_ORIGINAL
|
110
|
+
end
|
111
|
+
|
112
|
+
after do
|
113
|
+
File.delete '.temp.json_config.json'
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Auto 4
|
2
|
+
# Copyright (c) 2013, Auto Project
|
3
|
+
# Distributed under the terms of the FreeBSD license (LICENSE.md).
|
4
|
+
require(File.join(File.expand_path(File.dirname(__FILE__)), 'helper.rb'))
|
5
|
+
|
6
|
+
require 'auto/config'
|
7
|
+
|
8
|
+
describe "A base configuration" do
|
9
|
+
|
10
|
+
before do
|
11
|
+
$m.expects(:debug)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should raise ConfigError on initialize if a non-existent file was provided' do
|
15
|
+
-> { Auto::Config.new('.temp.file_no_exist.yml') }.must_raise ConfigError
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should raise ConfigError on initialize if the file\'s extension is not recognized' do
|
19
|
+
File.open('.temp.xml_config.xml', 'w') do |io|
|
20
|
+
io.write "<title>Hello world</title>"
|
21
|
+
end
|
22
|
+
|
23
|
+
-> { Auto::Config.new('.temp.xml_config.xml') }.must_raise ConfigError
|
24
|
+
File.delete '.temp.xml_config.xml'
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
# vim: set ts=4 sts=2 sw=2 et:
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# Auto 4
|
2
|
+
# Copyright (c) 2013, Auto Project
|
3
|
+
# Distributed under the terms of the FreeBSD license (LICENSE.md).
|
4
|
+
require(File.join(File.expand_path(File.dirname(__FILE__)), 'helper.rb'))
|
5
|
+
|
6
|
+
require 'auto/config'
|
7
|
+
|
8
|
+
describe "A configuration using YAML" do
|
9
|
+
|
10
|
+
YAML_ORIGINAL_CONF = <<EOF
|
11
|
+
---
|
12
|
+
# This is a comment; unicorns are lovely
|
13
|
+
foo:
|
14
|
+
|
15
|
+
cat:
|
16
|
+
- meow
|
17
|
+
- purr
|
18
|
+
|
19
|
+
cow:
|
20
|
+
- moo
|
21
|
+
|
22
|
+
dinosaur:
|
23
|
+
- rawr
|
24
|
+
|
25
|
+
EOF
|
26
|
+
|
27
|
+
YAML_NEW_CONF = <<EOF
|
28
|
+
---
|
29
|
+
# This is a comment; unicorns are lovely
|
30
|
+
foo:
|
31
|
+
|
32
|
+
cat:
|
33
|
+
- meow
|
34
|
+
- purr
|
35
|
+
|
36
|
+
cow:
|
37
|
+
- moo
|
38
|
+
|
39
|
+
dinosaur:
|
40
|
+
- rawr
|
41
|
+
|
42
|
+
bunny:
|
43
|
+
- unimaginable cuteness that forces you to coo
|
44
|
+
|
45
|
+
EOF
|
46
|
+
|
47
|
+
YAML_BAD_CONF = <<EOF
|
48
|
+
THIS ARE RUBBISH
|
49
|
+
|
50
|
+
THAT W!LL F41L
|
51
|
+
|
52
|
+
...0R SHOULD
|
53
|
+
EOF
|
54
|
+
|
55
|
+
YAML_HASH_ORIGINAL = {
|
56
|
+
'foo' => {
|
57
|
+
'cat' => ['meow', 'purr'],
|
58
|
+
'cow' => ['moo'],
|
59
|
+
'dinosaur' => ['rawr']
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
YAML_HASH_NEW = {
|
64
|
+
'foo' => {
|
65
|
+
'cat' => ['meow', 'purr'],
|
66
|
+
'cow' => ['moo'],
|
67
|
+
'dinosaur' => ['rawr'],
|
68
|
+
'bunny' => ['unimaginable cuteness that forces you to coo']
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
before do
|
73
|
+
$m.expects(:debug)
|
74
|
+
$m.stubs(:events).returns(Mocha::Mock.new('Auto::API::Events'))
|
75
|
+
|
76
|
+
File.open('.temp.yaml_config.yml', 'w') do |io|
|
77
|
+
io.write YAML_ORIGINAL_CONF
|
78
|
+
end
|
79
|
+
|
80
|
+
@conf = Auto::Config.new('.temp.yaml_config.yml')
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should have a type of YAML' do
|
84
|
+
@conf.type.must_equal :yaml
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should have @conf, a Hash' do
|
88
|
+
@conf.conf.class.must_equal Hash
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should point [x] to @conf[x]' do
|
92
|
+
@conf['foo'].must_be_same_as @conf.conf['foo']
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should have correctly processed data' do
|
96
|
+
@conf.conf.must_equal YAML_HASH_ORIGINAL
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should rehash on rehash!()' do
|
100
|
+
$m.expects(:debug)
|
101
|
+
$m.expects(:events).times(2)
|
102
|
+
$m.stubs(:events).returns(Mocha::Mock.new('Auto::API::Events'))
|
103
|
+
$m.events.expects(:call)
|
104
|
+
|
105
|
+
File.open('.temp.yaml_config.yml', 'w') do |io|
|
106
|
+
io.write YAML_NEW_CONF
|
107
|
+
end
|
108
|
+
@conf.rehash!
|
109
|
+
@conf.conf.must_equal YAML_HASH_NEW
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'should fail on rehash!() if data is bad' do
|
113
|
+
$m.expects(:debug)
|
114
|
+
$m.expects(:error)
|
115
|
+
File.open('.temp.yaml_config.yml', 'w') do |io|
|
116
|
+
io.write YAML_BAD_CONF
|
117
|
+
end
|
118
|
+
@conf.rehash!.must_equal 0
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'should should revert to old data if rehash!() fails' do
|
122
|
+
$m.expects(:error)
|
123
|
+
$m.expects(:debug)
|
124
|
+
|
125
|
+
File.open('.temp.yaml_config.yml', 'w') do |io|
|
126
|
+
io.write YAML_BAD_CONF
|
127
|
+
end
|
128
|
+
@conf.rehash!
|
129
|
+
@conf.conf.must_equal YAML_HASH_ORIGINAL
|
130
|
+
end
|
131
|
+
|
132
|
+
after do
|
133
|
+
File.delete '.temp.yaml_config.yml'
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
data/spec/helper.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# Auto 4
|
2
|
+
# Copyright (c) 2013, Auto Project
|
3
|
+
# Distributed under the terms of the FreeBSD license (LICENSE.md).
|
4
|
+
|
5
|
+
# We use MiniTest, because we endorse bareMinerals.
|
6
|
+
require 'minitest/autorun'
|
7
|
+
require 'minitest/spec' # for specs
|
8
|
+
|
9
|
+
# ...and mocha, because liquid foundation is better anyway.
|
10
|
+
require 'mocha/setup'
|
11
|
+
|
12
|
+
$m = Mocha::Mock.new 'Auto::Bot'
|
13
|
+
[:debug, :foreground, :info].each do |m|
|
14
|
+
$m.stubs m
|
15
|
+
end
|
16
|
+
$m.stubs(:events).returns(Mocha::Mock.new('Auto::API::Events'))
|
17
|
+
$m.stubs(:opts).returns(Mocha::Mock.new('Slop'))
|
18
|
+
|
19
|
+
# vim: set ts=4 sts=2 sw=2 et:
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Auto 4
|
2
|
+
# Copyright (c) 2013, Auto Project
|
3
|
+
# Distributed under the terms of the FreeBSD license (LICENSE.md).
|
4
|
+
require(File.expand_path('../helper.rb', __FILE__))
|
5
|
+
|
6
|
+
require 'auto/irc/object/entity'
|
7
|
+
|
8
|
+
describe Auto::IRC::Object::Entity do
|
9
|
+
|
10
|
+
before do
|
11
|
+
@ircmock = mock('Auto::IRC::Server')
|
12
|
+
@ent = Auto::IRC::Object::Entity.new(@ircmock, :channel, 'jonathantaylor')
|
13
|
+
end
|
14
|
+
|
15
|
+
it '#channel?' do
|
16
|
+
@ent.channel?.must_equal true
|
17
|
+
end
|
18
|
+
|
19
|
+
it '#user?' do
|
20
|
+
@ent.user?.must_equal false
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#msg' do
|
24
|
+
before do
|
25
|
+
@ircmock.stubs(:nick).returns('unicorn')
|
26
|
+
@ircmock.stubs(:user).returns('nyan')
|
27
|
+
@ircmock.stubs(:mask).returns('alyx.is.a.goose.autoproj.org')
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should send a message' do
|
31
|
+
@ircmock.expects(:snd).with('PRIVMSG jonathantaylor :le Oshawott')
|
32
|
+
$m.events.expects(:call).with('irc:onMsg', @ent, 'le Oshawott')
|
33
|
+
@ent.msg 'le Oshawott'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should divide messages which are too long' do
|
37
|
+
@ircmock.expects(:snd).times 2
|
38
|
+
$m.events.expects(:call)
|
39
|
+
@ent.msg 'der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt der Welt'
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should send a notice if told to' do
|
43
|
+
@ircmock.expects(:snd).with('NOTICE jonathantaylor :le Oshawott')
|
44
|
+
$m.events.expects(:call).with('irc:onMsg', @ent, 'le Oshawott')
|
45
|
+
@ent.msg 'le Oshawott', true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
# vim: set ts=4 sts=2 sw=2 et:
|