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.
Files changed (65) hide show
  1. data/.yardopts +7 -0
  2. data/Gemfile +19 -0
  3. data/LICENSE.md +31 -0
  4. data/README.md +109 -0
  5. data/Rakefile +41 -0
  6. data/bin/auto +110 -0
  7. data/bin/auto-conf +45 -0
  8. data/conf/example.json +100 -0
  9. data/conf/example.yml +125 -0
  10. data/docs/Contributing.md +77 -0
  11. data/docs/Events.md +103 -0
  12. data/docs/Todo.md +21 -0
  13. data/docs/Upgrade.md +16 -0
  14. data/ext/dsl_base.c +49 -0
  15. data/ext/libauto/auto.h +20 -0
  16. data/ext/libauto/extconf.rb +16 -0
  17. data/ext/libauto/libauto.c +29 -0
  18. data/ext/libauto/libauto.h +28 -0
  19. data/ext/libauto/logger.c +177 -0
  20. data/ext/libauto/logger.h +44 -0
  21. data/lib/auto.rb +43 -0
  22. data/lib/auto/api.rb +7 -0
  23. data/lib/auto/api/events.rb +166 -0
  24. data/lib/auto/api/object.rb +29 -0
  25. data/lib/auto/api/plugin.rb +155 -0
  26. data/lib/auto/api/timers.rb +93 -0
  27. data/lib/auto/bot.rb +338 -0
  28. data/lib/auto/config.rb +181 -0
  29. data/lib/auto/configure.rb +410 -0
  30. data/lib/auto/configure/shell.rb +154 -0
  31. data/lib/auto/dsl/base.rb +74 -0
  32. data/lib/auto/dsl/irc.rb +13 -0
  33. data/lib/auto/irc.rb +8 -0
  34. data/lib/auto/irc/common.rb +63 -0
  35. data/lib/auto/irc/library.rb +89 -0
  36. data/lib/auto/irc/object/channel.rb +21 -0
  37. data/lib/auto/irc/object/entity.rb +90 -0
  38. data/lib/auto/irc/object/message.rb +99 -0
  39. data/lib/auto/irc/object/user.rb +139 -0
  40. data/lib/auto/irc/protocol.rb +164 -0
  41. data/lib/auto/irc/protocol/numerics.rb +60 -0
  42. data/lib/auto/irc/sasl/diffie_hellman.rb +36 -0
  43. data/lib/auto/irc/sasl/mech.rb +15 -0
  44. data/lib/auto/irc/sasl/mech/dh_blowfish.rb +83 -0
  45. data/lib/auto/irc/sasl/mech/plain.rb +39 -0
  46. data/lib/auto/irc/server.rb +301 -0
  47. data/lib/auto/irc/state/channel_manager.rb +6 -0
  48. data/lib/auto/irc/state/support.rb +142 -0
  49. data/lib/auto/irc/state/user_manager.rb +6 -0
  50. data/lib/auto/irc/std/commands.rb +99 -0
  51. data/lib/auto/irc/std/numerics.rb +216 -0
  52. data/lib/auto/rubyext/integer.rb +25 -0
  53. data/lib/auto/rubyext/string.rb +10 -0
  54. data/lib/auto/version.rb +18 -0
  55. data/lib/libauto.so +0 -0
  56. data/spec/api_events_spec.rb +68 -0
  57. data/spec/config_json_spec.rb +116 -0
  58. data/spec/config_other_spec.rb +29 -0
  59. data/spec/config_yaml_spec.rb +136 -0
  60. data/spec/helper.rb +19 -0
  61. data/spec/irc_object_entity_spec.rb +51 -0
  62. data/spec/logger_spec.rb +30 -0
  63. data/spec/plugin_base_spec.rb +35 -0
  64. data/spec/timers_spec.rb +42 -0
  65. 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:
@@ -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:
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
@@ -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: