shout-bot 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/shout-bot.rb +229 -0
  2. metadata +63 -0
data/shout-bot.rb ADDED
@@ -0,0 +1,229 @@
1
+ =begin
2
+ ShoutBot
3
+ Ridiculously simple library to quickly say something on IRC
4
+ <http://github.com/sr/shout-bot>
5
+
6
+ EXAMPLE
7
+
8
+ ShoutBot.shout('irc://shoutbot:password@irc.freenode.net:6667/#github') do |channel|
9
+ channel.say "check me out! http://github.com/sr/shout-bot"
10
+ end
11
+
12
+ LICENSE
13
+
14
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
15
+ Version 2, December 2004
16
+
17
+ Copyright (C) 2008, 2009 Simon Rozet <http://purl.org/net/sr/>
18
+ Copyright (C) 2008, 2009 Harry Vangberg <http://trueaffection.net>
19
+
20
+ Everyone is permitted to copy and distribute verbatim or modified
21
+ copies of this license document, and changing it is allowed as long
22
+ as the name is changed.
23
+
24
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
25
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
26
+
27
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
28
+ =end
29
+
30
+ require "rubygems"
31
+ require "addressable/uri"
32
+ require "socket"
33
+
34
+ class ShoutBot
35
+ def self.shout(uri, &block)
36
+ raise ArgumentError unless block_given?
37
+
38
+ uri = Addressable::URI.parse(uri)
39
+ irc = new(uri.host, uri.port, uri.user, uri.password) do |irc|
40
+ if channel = uri.fragment
41
+ irc.join(channel, &block)
42
+ else
43
+ irc.channel = uri.path[1..-1]
44
+ yield irc
45
+ end
46
+ end
47
+ end
48
+
49
+ attr_accessor :channel
50
+
51
+ def initialize(server, port, nick, password=nil)
52
+ raise ArgumentError unless block_given?
53
+
54
+ @socket = TCPSocket.open(server, port || 6667)
55
+ @socket.puts "PASSWORD #{password}" if password
56
+ @socket.puts "NICK #{nick}"
57
+ @socket.puts "USER #{nick} #{nick} #{nick} :#{nick}"
58
+ sleep 1
59
+ yield self
60
+ @socket.puts "QUIT"
61
+ @socket.gets until @socket.eof?
62
+ end
63
+
64
+ def join(channel)
65
+ raise ArgumentError unless block_given?
66
+
67
+ @channel = "##{channel}"
68
+ @socket.puts "JOIN #{@channel}"
69
+ yield self
70
+ @socket.puts "PART #{@channel}"
71
+ end
72
+
73
+ def say(message)
74
+ return unless @channel
75
+ @socket.puts "PRIVMSG #{@channel} :#{message}"
76
+ end
77
+ end
78
+
79
+ if $0 == __FILE__ || $0 == "-e"
80
+ require "test/unit"
81
+ require "context"
82
+ require "rr"
83
+
84
+ class MockSocket
85
+ attr_accessor :in, :out
86
+ def gets() @in.gets end
87
+ def puts(m) @out.puts(m) end
88
+ def eof?() true end
89
+ end
90
+
91
+ class ShoutBot
92
+ include Test::Unit::Assertions
93
+ end
94
+
95
+ class Test::Unit::TestCase
96
+ include RR::Adapters::TestUnit
97
+
98
+ def setup
99
+ @socket, @server = MockSocket.new, MockSocket.new
100
+ @socket.in, @server.out = IO.pipe
101
+ @server.in, @socket.out = IO.pipe
102
+
103
+ stub(TCPSocket).open(anything, anything) {@socket}
104
+ end
105
+ end
106
+
107
+ class TestShoutBot < Test::Unit::TestCase
108
+ def create_shoutbot(&block)
109
+ ShoutBot.new("irc.freenode.net", 6667, "john", &block || lambda {})
110
+ end
111
+
112
+ def create_shoutbot_and_register(&block)
113
+ create_shoutbot &block
114
+ 2.times { @server.gets } # NICK + USER
115
+ end
116
+
117
+ test "raises error if no block given" do
118
+ assert_raises ArgumentError do
119
+ ShoutBot.new("irc.freenode.net", 6667, "john")
120
+ end
121
+ end
122
+
123
+ test "registers to the irc server" do
124
+ create_shoutbot
125
+ assert_equal "NICK john\n", @server.gets
126
+ assert_equal "USER john john john :john\n", @server.gets
127
+ end
128
+
129
+ test "sends password if specified" do
130
+ # hey, retarded test!
131
+ ShoutBot.new("irc.freenode.net", 6667, "john", "malbec") {@socket}
132
+ assert_equal "PASSWORD malbec\n", @server.gets
133
+ end
134
+
135
+ test "falls back to port 6667 if not specified" do
136
+ # talk about retarded test
137
+ mock(TCPSocket).open("irc.freenode.net", 6667) {@socket}
138
+ ShoutBot.new("irc.freenode.net", nil, "john") {}
139
+ end
140
+
141
+ test "quits after doing its job" do
142
+ create_shoutbot_and_register {}
143
+ assert_equal "QUIT\n", @server.gets
144
+ end
145
+
146
+ test "raises error if no block is given to join" do
147
+ create_shoutbot do |bot|
148
+ assert_raises(ArgumentError) {bot.join "integrity"}
149
+ end
150
+ end
151
+
152
+ test "joins channel" do
153
+ create_shoutbot_and_register do |bot|
154
+ bot.join("integrity") {}
155
+ end
156
+ assert_equal "JOIN #integrity\n", @server.gets
157
+ end
158
+
159
+ test "doesn't do anything until receiving RPL_MYINFO / 004" do
160
+ # pending
161
+ end
162
+
163
+ test "joins channel and says something" do
164
+ create_shoutbot_and_register do |bot|
165
+ bot.join "integrity" do |c|
166
+ c.say "foo bar!"
167
+ end
168
+ end
169
+ @server.gets # JOIN
170
+ assert_equal "PRIVMSG #integrity :foo bar!\n", @server.gets
171
+ end
172
+
173
+ test "sends private message to user" do
174
+ create_shoutbot_and_register do |bot|
175
+ bot.channel = "sr"
176
+ bot.say "Look Ma, new tests!"
177
+ end
178
+ assert_equal "PRIVMSG sr :Look Ma, new tests!\n", @server.gets
179
+ end
180
+ end
181
+
182
+ class TestShouter < Test::Unit::TestCase
183
+ def create_shouter(&block)
184
+ shouter = ShoutBot.new("irc.freenode.net", 6667, "shouter") {}
185
+ mock(ShoutBot).new(anything, anything, anything, anything).yields(shouter) {shouter}
186
+ shouter
187
+ end
188
+
189
+ test "raises error unless block is given" do
190
+ assert_raises ArgumentError do
191
+ ShoutBot.shout("irc://shouter@irc.freenode.net:6667/foo")
192
+ end
193
+ end
194
+
195
+ test "creates a new instance of shoutbot" do
196
+ mock(ShoutBot).new("irc.freenode.net", 6667, "shouter", nil)
197
+ ShoutBot.shout("irc://shouter@irc.freenode.net:6667/foo") {}
198
+ end
199
+
200
+ test "creates a new instance of shoutbot with password" do
201
+ mock(ShoutBot).new("irc.freenode.net", 6667, "shouter", "badass")
202
+ ShoutBot.shout("irc://shouter:badass@irc.freenode.net:6667/foo") {}
203
+ end
204
+
205
+ test "joins channel" do
206
+ shouter = create_shouter
207
+ mock(shouter).join("integrity")
208
+ ShoutBot.shout("irc://shouter@irc.freenode.net:6667/#integrity") {}
209
+ end
210
+
211
+ test "says stuff in channel" do
212
+ shouter = create_shouter
213
+ mock(shouter).say("foo bar!")
214
+ ShoutBot.shout("irc://shouter@irc.freenode.net:6667/#integrity") do |bot|
215
+ bot.say "foo bar!"
216
+ end
217
+ assert_equal "#integrity", shouter.channel
218
+ end
219
+
220
+ test "sends private message to nick" do
221
+ shouter = create_shouter
222
+ mock(shouter).say("foo bar!")
223
+ ShoutBot.shout("irc://shouter@irc.freenode.net:6667/harry") do |bot|
224
+ bot.say "foo bar!"
225
+ end
226
+ assert_equal "harry", shouter.channel
227
+ end
228
+ end
229
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: shout-bot
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Simon Rozet
8
+ - Harry Vangberg
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-03-02 00:00:00 +01:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: addressable
18
+ type: :runtime
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ version:
26
+ description: Ridiculously simple library to quickly say something on IRC
27
+ email: simon@rozet.name
28
+ executables: []
29
+
30
+ extensions: []
31
+
32
+ extra_rdoc_files: []
33
+
34
+ files:
35
+ - shout-bot.rb
36
+ has_rdoc: false
37
+ homepage: http://github.com/sr/shout-bot
38
+ post_install_message:
39
+ rdoc_options: []
40
+
41
+ require_paths:
42
+ - .
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ requirements: []
56
+
57
+ rubyforge_project:
58
+ rubygems_version: 1.3.1
59
+ signing_key:
60
+ specification_version: 2
61
+ summary: Ridiculously simple library to quickly say something on IRC
62
+ test_files: []
63
+