minter-raccdoc 0.0.1
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/LICENSE +20 -0
- data/Manifest +8 -0
- data/README +0 -0
- data/Rakefile +39 -0
- data/lib/raccdoc.rb +361 -0
- data/raccdoc.gemspec +41 -0
- data/test/raccdoc_connection_test.rb +73 -0
- data/test/test_helper.rb +5 -0
- metadata +94 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 H. Wade Minter
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Manifest
ADDED
data/README
ADDED
File without changes
|
data/Rakefile
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'echoe', '~> 3.0.1'
|
3
|
+
require 'echoe'
|
4
|
+
require './lib/raccdoc.rb'
|
5
|
+
|
6
|
+
echoe = Echoe.new("raccdoc") do |p|
|
7
|
+
p.author = "H. Wade Minter"
|
8
|
+
p.email = "minter@lunenburg.org"
|
9
|
+
p.summary = "A Ruby interface into the Raccdoc protocol"
|
10
|
+
p.runtime_dependencies = ["socket", "time"]
|
11
|
+
p.version = Raccdoc::VERSION
|
12
|
+
p.ignore_pattern = ["tmp/*", "doc/*"]
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Generate the .gemspec file in the root directory'
|
16
|
+
task :gemspec do
|
17
|
+
File.open("#{echoe.name}.gemspec", "w") {|f| f << echoe.spec.to_ruby }
|
18
|
+
end
|
19
|
+
task :package => :gemspec
|
20
|
+
|
21
|
+
namespace :test do
|
22
|
+
desc 'Check test coverage'
|
23
|
+
task :coverage do
|
24
|
+
rm_f "coverage"
|
25
|
+
system("rcov -x '/Library/Ruby/Gems/1.8/gems/' --sort coverage #{File.join(File.dirname(__FILE__), 'test/*_test.rb')}")
|
26
|
+
show_test_coverage_results
|
27
|
+
end
|
28
|
+
|
29
|
+
def show_test_coverage_results
|
30
|
+
system("open #{File.join(File.dirname(__FILE__), 'coverage/index.html')}") if PLATFORM['darwin']
|
31
|
+
end
|
32
|
+
|
33
|
+
desc 'Remove coverage products'
|
34
|
+
task :clobber_coverage do
|
35
|
+
rm_r 'coverage' rescue nil
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
data/lib/raccdoc.rb
ADDED
@@ -0,0 +1,361 @@
|
|
1
|
+
module Raccdoc
|
2
|
+
|
3
|
+
VERSION = '0.0.1'
|
4
|
+
require 'socket'
|
5
|
+
require 'time'
|
6
|
+
|
7
|
+
class Connection
|
8
|
+
|
9
|
+
attr_reader :host
|
10
|
+
|
11
|
+
# Creates a new Raccdoc connection. By default, it connects to bbs.iscabbs.com, port 6145, which is the
|
12
|
+
# ISCABBS server.
|
13
|
+
#
|
14
|
+
# If a :user and :password is not supplied, a guest/anonymous login is done. Most, if not all, posting is
|
15
|
+
# restricted under this account.
|
16
|
+
#
|
17
|
+
# If the TCP connection fails, or the login is rejected, and exception is raised.
|
18
|
+
def initialize(param_args = {:host => 'bbs.iscabbs.com', :port => '6145', :user => nil, :password => nil})
|
19
|
+
args = {:host => 'bbs.iscabbs.com', :port => '6145', :user => nil, :password => nil }
|
20
|
+
|
21
|
+
args.merge!(param_args)
|
22
|
+
begin
|
23
|
+
@socket = TCPSocket.new(args[:host],args[:port])
|
24
|
+
rescue Errno::ECONNREFUSED
|
25
|
+
raise RuntimeError, "Could not connect to #{args[:host]}, port #{args[:port]}\n"
|
26
|
+
end
|
27
|
+
|
28
|
+
response = @socket.readline.chomp
|
29
|
+
unless response.match(/^2/)
|
30
|
+
raise RuntimeError, response
|
31
|
+
end
|
32
|
+
|
33
|
+
if (args[:user] && args[:password])
|
34
|
+
@socket.puts("LOGIN #{args[:user]}\t#{args[:password]}")
|
35
|
+
response = @socket.readline.chomp
|
36
|
+
unless response.match(/^2/)
|
37
|
+
raise RuntimeError, response
|
38
|
+
end
|
39
|
+
end
|
40
|
+
@host = args[:host]
|
41
|
+
end
|
42
|
+
|
43
|
+
# Closes the Raccdoc connection, then closes the socket.
|
44
|
+
def logout
|
45
|
+
unless @socket.closed?
|
46
|
+
@socket.puts "QUIT"
|
47
|
+
|
48
|
+
response = @socket.readline.chomp
|
49
|
+
unless response.match(/^2/)
|
50
|
+
raise RuntimeError, response
|
51
|
+
end
|
52
|
+
@socket.close
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Tests the TCP socket to make sure that it's still connected to the remote server.
|
57
|
+
def connected?
|
58
|
+
@socket.closed? ? false : true
|
59
|
+
end
|
60
|
+
|
61
|
+
# Sets the active forum on the server to the specified forum name or ID, and returns a new Raccdoc::Forum object.
|
62
|
+
#
|
63
|
+
# The forum can be specified by number (0), or name ("Lobby" or "Program")
|
64
|
+
def jump(forum = 0)
|
65
|
+
Raccdoc::Forum.new(@socket, forum.to_s)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns a hash of forum information. The key is the forum ID number, and the value is a hash containing the following data:
|
69
|
+
#
|
70
|
+
# * name - The forum name
|
71
|
+
# * lastnote - The earliest post ID number in the forum
|
72
|
+
# * admin - The handle of the forum admin
|
73
|
+
#
|
74
|
+
# Note that this does not return actual Raccdoc::Forum objects in the interest of saving resources, so you'll need to jump to the forum that you want.
|
75
|
+
def forums(type="all")
|
76
|
+
@socket.puts "LIST #{type}"
|
77
|
+
forums = Hash.new
|
78
|
+
|
79
|
+
response = @socket.readline.chomp
|
80
|
+
unless response.match(/^3/)
|
81
|
+
raise RuntimeError, response
|
82
|
+
end
|
83
|
+
|
84
|
+
while line = @socket.readline.chomp
|
85
|
+
break if line.match(/^\.$/)
|
86
|
+
tmp = Hash.new
|
87
|
+
line.split(/\t/).each do |pair|
|
88
|
+
(key, value) = pair.split(/:/)
|
89
|
+
if key == "admin"
|
90
|
+
value = value.split('/')[1]
|
91
|
+
end
|
92
|
+
tmp[key.to_sym] = value
|
93
|
+
end
|
94
|
+
id = tmp[:topic].to_i
|
95
|
+
forums[id] = tmp
|
96
|
+
end
|
97
|
+
|
98
|
+
return forums
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
class Forum
|
104
|
+
|
105
|
+
attr_reader :id
|
106
|
+
attr_reader :name
|
107
|
+
attr_reader :admin
|
108
|
+
|
109
|
+
# Sets the active forum on the server to the specified forum number (0) or name (Lobby, Program), then returns a new Raccdoc::Forum object.
|
110
|
+
#
|
111
|
+
# There are three variables exposed through attr_reader:
|
112
|
+
#
|
113
|
+
# * id - The forum ID number
|
114
|
+
# * name - The forum name
|
115
|
+
# * admin - The name of the forum administrator
|
116
|
+
def initialize(socket, forum = 0)
|
117
|
+
@socket = socket
|
118
|
+
@socket.puts "TOPIC #{forum.to_s}"
|
119
|
+
response = @socket.readline.chomp
|
120
|
+
unless response.match(/^2/)
|
121
|
+
raise RuntimeError, response
|
122
|
+
end
|
123
|
+
|
124
|
+
@headers = {}
|
125
|
+
tuples = response.split(/\t/)
|
126
|
+
tuples.delete_at(0)
|
127
|
+
tuples.each do |pair|
|
128
|
+
(key, value) = pair.split(/:/)
|
129
|
+
@headers[key.downcase.to_sym] = value
|
130
|
+
end
|
131
|
+
|
132
|
+
@id = @headers[:topic]
|
133
|
+
@name = @headers[:name]
|
134
|
+
@admin = @headers[:admin]
|
135
|
+
end
|
136
|
+
|
137
|
+
# Returns an array of all current post IDs in the forum.
|
138
|
+
def noteids
|
139
|
+
noteids = Array.new
|
140
|
+
@socket.puts("XHDR noteno")
|
141
|
+
response = @socket.readline.chomp
|
142
|
+
unless response.match(/^3/)
|
143
|
+
raise RuntimeError, response
|
144
|
+
end
|
145
|
+
|
146
|
+
while line = @socket.readline.chomp
|
147
|
+
break if line.match(/^\.$/)
|
148
|
+
(tag,noteid) = line.split(/:/)
|
149
|
+
noteids.push(noteid.to_i)
|
150
|
+
end
|
151
|
+
|
152
|
+
return noteids
|
153
|
+
end
|
154
|
+
|
155
|
+
# Returns a hash of the forum information. Keys are:
|
156
|
+
#
|
157
|
+
# * from - The username of the user who last updated the FI
|
158
|
+
# * date - The date the forum information was last updated (a Time object)
|
159
|
+
# * body - The actual text of the FI
|
160
|
+
def forum_information
|
161
|
+
fi = Hash.new
|
162
|
+
@socket.puts("SHOW info")
|
163
|
+
response = @socket.readline.chomp
|
164
|
+
unless response.match(/^3/)
|
165
|
+
raise RuntimeError, response
|
166
|
+
end
|
167
|
+
|
168
|
+
# Get header information
|
169
|
+
while line = @socket.readline.chomp
|
170
|
+
break if line.match(/^$/)
|
171
|
+
(key, value) = line.split(/: /)
|
172
|
+
if key.downcase == "date"
|
173
|
+
value = Time.parse(value)
|
174
|
+
end
|
175
|
+
fi[key.downcase.to_sym] = value
|
176
|
+
end
|
177
|
+
|
178
|
+
body = ""
|
179
|
+
while line = @socket.readline
|
180
|
+
break if line.match(/^\.$/)
|
181
|
+
body << line
|
182
|
+
end
|
183
|
+
fi[:body] = body
|
184
|
+
|
185
|
+
return fi
|
186
|
+
end
|
187
|
+
|
188
|
+
# Sets the current user's first-unread pointer to the specified number. Any posts greater than that number will be listed as unread.
|
189
|
+
def first_unread=(postid = 0)
|
190
|
+
@socket.puts("SETRC #{postid.to_s}")
|
191
|
+
response = @socket.readline.chomp
|
192
|
+
unless response.match(/^2/)
|
193
|
+
raise RuntimeError, response
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# Returns the post ID number of the last read post in the forum. Any posts greater than that number can be considered unread.
|
198
|
+
def first_unread
|
199
|
+
@socket.puts("SHOW rcval")
|
200
|
+
response = @socket.readline.chomp
|
201
|
+
unless response.match(/^2/)
|
202
|
+
raise RuntimeError, response
|
203
|
+
end
|
204
|
+
response.match(/\d+.*?:\s+(\d+)/)
|
205
|
+
return $1
|
206
|
+
end
|
207
|
+
|
208
|
+
# Returns a hash of information about the posts in the forum. The hash is keyed off of the post ID, and the value is a hash containing the following information:
|
209
|
+
#
|
210
|
+
# * author - The username of the user who created the post
|
211
|
+
# * date - The date the post was created or, if the post is anonymous, the current date in UTC
|
212
|
+
# * subject - The first line of the post
|
213
|
+
# * size - The size of the post in bytes
|
214
|
+
# * authority - If the post was made with Sysop or Forum Manager status, this is set
|
215
|
+
#
|
216
|
+
# You may provide an optional range (in the form "start_id-end_id") to limit the number of posts returned. The default is to return all posts in the forum.
|
217
|
+
def post_headers(range = "")
|
218
|
+
@socket.puts("XHDR ALL #{range}")
|
219
|
+
response = @socket.readline.chomp
|
220
|
+
unless response.match(/^3/)
|
221
|
+
raise RuntimeError, response
|
222
|
+
end
|
223
|
+
|
224
|
+
posts = Hash.new
|
225
|
+
|
226
|
+
while (line = @socket.readline.chomp)
|
227
|
+
break if line.match(/^\.$/)
|
228
|
+
tmpdata = Hash.new
|
229
|
+
line.split(/\t/).each do |tuple|
|
230
|
+
(key, value) = tuple.split(/:/, 2)
|
231
|
+
tmpdata[key.downcase.to_sym] = value
|
232
|
+
end
|
233
|
+
tmpdata[:date] = tmpdata[:date] ? Time.parse(tmpdata[:date]) : Time.new.getgm
|
234
|
+
tmpdata[:author] = tmpdata[:"formal-author"] ? tmpdata[:"formal-author"].split('/')[1] : 'Anonymous'
|
235
|
+
posts[tmpdata[:noteno]] = tmpdata
|
236
|
+
end
|
237
|
+
return posts
|
238
|
+
end
|
239
|
+
|
240
|
+
# Returns a new Raccdoc::Post object for the specified post ID in the current forum.
|
241
|
+
def read(postid)
|
242
|
+
Post.new(@socket,postid)
|
243
|
+
end
|
244
|
+
|
245
|
+
# Creates a new post in the current forum using the text provided in the argument.
|
246
|
+
#
|
247
|
+
# Returns a new Raccdoc::Post object that results from reading the newly created post.
|
248
|
+
def post(body)
|
249
|
+
@socket.puts("POST")
|
250
|
+
response = @socket.readline.chomp
|
251
|
+
unless response.match(/^3/)
|
252
|
+
raise RuntimeError, response
|
253
|
+
end
|
254
|
+
|
255
|
+
@socket.puts(body)
|
256
|
+
@socket.puts(".")
|
257
|
+
|
258
|
+
response = @socket.readline.chomp
|
259
|
+
if response.match(/^2/)
|
260
|
+
postid = response.split(/:\s+/)[1]
|
261
|
+
return Post.new(@socket,postid)
|
262
|
+
else
|
263
|
+
raise RuntimeError, response
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
# Checks to see if the currently logged in user has permission to post in the current forum.
|
268
|
+
#
|
269
|
+
# Returns true or false.
|
270
|
+
def post?
|
271
|
+
@socket.puts("OKAY POST")
|
272
|
+
response = @socket.readline.chomp
|
273
|
+
if response.match(/^2/)
|
274
|
+
return true
|
275
|
+
elsif response.match(/^4/)
|
276
|
+
return false
|
277
|
+
else
|
278
|
+
raise RuntimeError, response
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
class Post
|
284
|
+
|
285
|
+
attr_reader :id
|
286
|
+
attr_reader :date
|
287
|
+
attr_reader :author
|
288
|
+
attr_reader :body
|
289
|
+
|
290
|
+
# Creates a new Raccdoc::Post object by reading the specified post.
|
291
|
+
#
|
292
|
+
# Useful information returned:
|
293
|
+
#
|
294
|
+
# * id - The numerical post ID
|
295
|
+
# * date - The date the post was made (or the current date in UTC if the post is anonymous)
|
296
|
+
# * author - The username of the user that created the post
|
297
|
+
# * body - The textual body of the post.
|
298
|
+
def initialize(socket,postid)
|
299
|
+
@socket = socket
|
300
|
+
@socket.puts "READ #{postid}"
|
301
|
+
response = @socket.readline.chomp
|
302
|
+
unless response.match(/^3/)
|
303
|
+
raise RuntimeError, response
|
304
|
+
end
|
305
|
+
|
306
|
+
# Get header information
|
307
|
+
post = Hash.new
|
308
|
+
|
309
|
+
while line = @socket.readline.chomp
|
310
|
+
break if line.match(/^$/)
|
311
|
+
(key,value) = line.split(/: /)
|
312
|
+
post[key.downcase.to_sym] = value
|
313
|
+
end
|
314
|
+
post[:id] = postid
|
315
|
+
post[:date] = post[:date] ? Time.parse(post[:date]) : Time.new.getgm
|
316
|
+
post[:author] = post[:'formal-author'] ? post[:'formal-author'].split('/')[1] : 'Anonymous'
|
317
|
+
|
318
|
+
post[:body] = ""
|
319
|
+
while (line = @socket.readline)
|
320
|
+
break if line.match(/^\.$/)
|
321
|
+
post[:body] << line
|
322
|
+
end
|
323
|
+
|
324
|
+
@id = post[:id]
|
325
|
+
@date = post[:date]
|
326
|
+
@author = post[:author]
|
327
|
+
@body = post[:body]
|
328
|
+
return post
|
329
|
+
end
|
330
|
+
|
331
|
+
# Checks to see if the currently-logged-in user has permission to delete the current post.
|
332
|
+
#
|
333
|
+
# Returns true or false
|
334
|
+
def delete?
|
335
|
+
@socket.puts("OKAY DELETE NOTE #{self.id}")
|
336
|
+
response = @socket.readline.chomp
|
337
|
+
if response.match(/^2/)
|
338
|
+
return true
|
339
|
+
elsif response.match(/^4/)
|
340
|
+
return false
|
341
|
+
else
|
342
|
+
raise RuntimeError, response
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
# Attempts to delete the current post.
|
347
|
+
#
|
348
|
+
# Returns true or false
|
349
|
+
def delete
|
350
|
+
@socket.puts("DELETE NOTE #{self.id}")
|
351
|
+
response = @socket.readline.chomp
|
352
|
+
if response.match(/^2/)
|
353
|
+
return true
|
354
|
+
elsif response.match(/^4/)
|
355
|
+
return false
|
356
|
+
else response.match(/^2/)
|
357
|
+
raise RuntimeError, response
|
358
|
+
end
|
359
|
+
end
|
360
|
+
end
|
361
|
+
end
|
data/raccdoc.gemspec
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{raccdoc}
|
5
|
+
s.version = "0.0.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["H. Wade Minter"]
|
9
|
+
s.date = %q{2009-01-12}
|
10
|
+
s.description = %q{A Ruby interface into the Raccdoc protocol}
|
11
|
+
s.email = %q{minter@lunenburg.org}
|
12
|
+
s.extra_rdoc_files = ["lib/raccdoc.rb", "LICENSE", "README"]
|
13
|
+
s.files = ["lib/raccdoc.rb", "LICENSE", "Manifest", "raccdoc.gemspec", "Rakefile", "README", "test/raccdoc_connection_test.rb", "test/test_helper.rb"]
|
14
|
+
s.has_rdoc = true
|
15
|
+
s.homepage = %q{}
|
16
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Raccdoc", "--main", "README"]
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.rubyforge_project = %q{raccdoc}
|
19
|
+
s.rubygems_version = %q{1.3.1}
|
20
|
+
s.summary = %q{A Ruby interface into the Raccdoc protocol}
|
21
|
+
s.test_files = ["test/raccdoc_connection_test.rb", "test/test_helper.rb"]
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
25
|
+
s.specification_version = 2
|
26
|
+
|
27
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
28
|
+
s.add_runtime_dependency(%q<socket>, [">= 0"])
|
29
|
+
s.add_runtime_dependency(%q<time>, [">= 0"])
|
30
|
+
s.add_development_dependency(%q<echoe>, [">= 0"])
|
31
|
+
else
|
32
|
+
s.add_dependency(%q<socket>, [">= 0"])
|
33
|
+
s.add_dependency(%q<time>, [">= 0"])
|
34
|
+
s.add_dependency(%q<echoe>, [">= 0"])
|
35
|
+
end
|
36
|
+
else
|
37
|
+
s.add_dependency(%q<socket>, [">= 0"])
|
38
|
+
s.add_dependency(%q<time>, [">= 0"])
|
39
|
+
s.add_dependency(%q<echoe>, [">= 0"])
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class RaccdocConnectionTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@socket = mock()
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_valid_anonymous_connection
|
9
|
+
TCPSocket.expects(:new).returns(@socket)
|
10
|
+
@socket.expects(:readline).returns("200 Server started seed:Ci0B2YeMio8ftYjElTa+EQ==")
|
11
|
+
bbs = Raccdoc::Connection.new(:host => 'test.bbs.example')
|
12
|
+
assert_equal bbs.class, Raccdoc::Connection
|
13
|
+
assert_equal bbs.host, "test.bbs.example"
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_connection_refused_anonymous
|
17
|
+
TCPSocket.expects(:new).with('test.bbs.example', '6145').raises(Errno::ECONNREFUSED)
|
18
|
+
assert_raise(RuntimeError, 'Could not connect to test.bbs.example, port 6145') do
|
19
|
+
bbs = Raccdoc::Connection.new(:host => 'test.bbs.example')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_connection_bad_login
|
24
|
+
socket = mock()
|
25
|
+
socket.stubs(:readline).returns("200 Server started seed:Ci0B2YeMio8ftYjElTa+EQ==").then.returns("405 Cannot process login Invalid password")
|
26
|
+
socket.stubs(:puts)
|
27
|
+
TCPSocket.expects(:new).returns(socket)
|
28
|
+
assert_raise(RuntimeError, '404 User does not exist') do
|
29
|
+
bbs = Raccdoc::Connection.new(:host => 'test.bbs.example', :user => 'Bugcrusher', :password => 'BadPassword')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_connection_that_returns_unknown_status
|
34
|
+
socket = mock()
|
35
|
+
TCPSocket.expects(:new).returns(socket)
|
36
|
+
socket.expects(:readline).returns("999 Stuff is messed up")
|
37
|
+
assert_raise(RuntimeError) do
|
38
|
+
bbs = Raccdoc::Connection.new(:host => 'test.bbs.example')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_logout_succeeds
|
43
|
+
@socket.stubs(:puts)
|
44
|
+
@socket.stubs(:close)
|
45
|
+
@socket.stubs(:closed?).returns(false)
|
46
|
+
TCPSocket.expects(:new).returns(@socket)
|
47
|
+
@socket.stubs(:readline).returns("200 Server started seed:Ci0B2YeMio8ftYjElTa+EQ==").then.returns("201 Session ended")
|
48
|
+
bbs = Raccdoc::Connection.new(:host => 'test.bbs.example')
|
49
|
+
bbs.logout
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_logout_fails
|
53
|
+
@socket.stubs(:puts)
|
54
|
+
@socket.stubs(:close)
|
55
|
+
@socket.stubs(:closed?).returns(false)
|
56
|
+
TCPSocket.expects(:new).returns(@socket)
|
57
|
+
@socket.stubs(:readline).returns("200 Server started seed:Ci0B2YeMio8ftYjElTa+EQ==").then.returns("999 Something Broke")
|
58
|
+
bbs = Raccdoc::Connection.new(:host => 'test.bbs.example')
|
59
|
+
assert_raise(RuntimeError) do
|
60
|
+
bbs.logout
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_connected
|
65
|
+
@socket.stubs(:puts)
|
66
|
+
@socket.stubs(:closed?).returns(false)
|
67
|
+
TCPSocket.expects(:new).returns(@socket)
|
68
|
+
@socket.stubs(:readline).returns("200 Server started seed:Ci0B2YeMio8ftYjElTa+EQ==").then.returns("999 Something Broke")
|
69
|
+
bbs = Raccdoc::Connection.new(:host => 'test.bbs.example')
|
70
|
+
assert_equal bbs.connected?, true
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: minter-raccdoc
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- H. Wade Minter
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-01-12 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: socket
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: "0"
|
23
|
+
version:
|
24
|
+
- !ruby/object:Gem::Dependency
|
25
|
+
name: time
|
26
|
+
version_requirement:
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
requirements:
|
29
|
+
- - ">="
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: "0"
|
32
|
+
version:
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: echoe
|
35
|
+
version_requirement:
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: "0"
|
41
|
+
version:
|
42
|
+
description: A Ruby interface into the Raccdoc protocol
|
43
|
+
email: minter@lunenburg.org
|
44
|
+
executables: []
|
45
|
+
|
46
|
+
extensions: []
|
47
|
+
|
48
|
+
extra_rdoc_files:
|
49
|
+
- lib/raccdoc.rb
|
50
|
+
- LICENSE
|
51
|
+
- README
|
52
|
+
files:
|
53
|
+
- lib/raccdoc.rb
|
54
|
+
- LICENSE
|
55
|
+
- Manifest
|
56
|
+
- raccdoc.gemspec
|
57
|
+
- Rakefile
|
58
|
+
- README
|
59
|
+
- test/raccdoc_connection_test.rb
|
60
|
+
- test/test_helper.rb
|
61
|
+
has_rdoc: true
|
62
|
+
homepage: ""
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options:
|
65
|
+
- --line-numbers
|
66
|
+
- --inline-source
|
67
|
+
- --title
|
68
|
+
- Raccdoc
|
69
|
+
- --main
|
70
|
+
- README
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: "0"
|
78
|
+
version:
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: "1.2"
|
84
|
+
version:
|
85
|
+
requirements: []
|
86
|
+
|
87
|
+
rubyforge_project: raccdoc
|
88
|
+
rubygems_version: 1.2.0
|
89
|
+
signing_key:
|
90
|
+
specification_version: 2
|
91
|
+
summary: A Ruby interface into the Raccdoc protocol
|
92
|
+
test_files:
|
93
|
+
- test/raccdoc_connection_test.rb
|
94
|
+
- test/test_helper.rb
|