fargo 0.2.0 → 0.3.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/README.md +61 -0
- data/ext/fargo/extconf.rb +1 -1
- data/ext/fargo/fargo_tth.c +0 -2
- data/lib/fargo/client.rb +30 -24
- data/lib/fargo/parser.rb +90 -59
- data/lib/fargo/protocol/dc.rb +24 -8
- data/lib/fargo/protocol/hub.rb +41 -20
- data/lib/fargo/protocol/peer.rb +114 -0
- data/lib/fargo/protocol/{download.rb → peer_download.rb} +51 -115
- data/lib/fargo/protocol/peer_upload.rb +160 -0
- data/lib/fargo/search.rb +38 -5
- data/lib/fargo/supports/downloads.rb +17 -17
- data/lib/fargo/supports/local_file_list.rb +164 -0
- data/lib/fargo/supports/nick_list.rb +18 -5
- data/lib/fargo/supports/persistence.rb +2 -2
- data/lib/fargo/supports/{file_list.rb → remote_file_list.rb} +4 -5
- data/lib/fargo/supports/searches.rb +5 -12
- data/lib/fargo/supports/uploads.rb +24 -5
- data/lib/fargo/version.rb +1 -1
- data/lib/fargo.rb +12 -3
- data/spec/fargo/parser_spec.rb +198 -0
- data/spec/fargo/protocol/dc_spec.rb +77 -0
- data/spec/fargo/protocol/hub_spec.rb +155 -0
- data/spec/fargo/protocol/peer_download_spec.rb +104 -0
- data/spec/fargo/protocol/peer_spec.rb +58 -0
- data/spec/fargo/protocol/peer_upload_spec.rb +128 -0
- data/spec/fargo/search_spec.rb +107 -0
- data/spec/fargo/supports/chat_spec.rb +33 -0
- data/spec/fargo/supports/local_file_list_spec.rb +70 -0
- data/spec/fargo/supports/nick_list_spec.rb +35 -0
- data/spec/fargo/utils_spec.rb +26 -0
- data/spec/spec_helper.rb +47 -0
- data/spec/support/matchers.rb +17 -0
- metadata +37 -9
- data/lib/fargo/search_result.rb +0 -31
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Fargo::Protocol::PeerDownload do
|
4
|
+
let(:conn) {
|
5
|
+
helper_object(Fargo::Protocol::Peer).tap do |conn|
|
6
|
+
conn.client = Fargo::Client.new
|
7
|
+
conn.instance_variable_set '@other_nick', 'foobar'
|
8
|
+
end
|
9
|
+
}
|
10
|
+
|
11
|
+
shared_examples_for 'a downloader' do |command, data|
|
12
|
+
it "downloads a file correctly after receiving: #{command}" do
|
13
|
+
conn.stub(:send_message)
|
14
|
+
|
15
|
+
conn.begin_download!
|
16
|
+
conn.receive_data command
|
17
|
+
conn.receive_data data
|
18
|
+
|
19
|
+
file = conn.client.config.download_dir + '/foobar/file'
|
20
|
+
file.should have_contents('0123456789')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
before :each do
|
25
|
+
conn.stub :set_comm_inactivity_timeout
|
26
|
+
conn.post_init
|
27
|
+
conn.download = Fargo::Download.new 'foobar', 'path/to/file', 'tth', 100, 0
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'the standard DC protocol for downloading' do
|
31
|
+
before :each do
|
32
|
+
conn.instance_variable_set '@client_extensions', []
|
33
|
+
end
|
34
|
+
|
35
|
+
it "requests a download via the $Get command" do
|
36
|
+
conn.should_receive(:send_message).with('Get', "path/to/file$1")
|
37
|
+
|
38
|
+
conn.begin_download!
|
39
|
+
end
|
40
|
+
|
41
|
+
it "requests the file to be sent after the $FileLength command" do
|
42
|
+
conn.stub(:send_message).with('Get', "path/to/file$1")
|
43
|
+
conn.should_receive(:send_message).with('Send')
|
44
|
+
|
45
|
+
conn.begin_download!
|
46
|
+
conn.receive_data '$FileLength 10|'
|
47
|
+
end
|
48
|
+
|
49
|
+
it_should_behave_like 'a downloader', '$FileLength 10|', '0123456789'
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'the ADC protocol for downloading' do
|
53
|
+
before :each do
|
54
|
+
conn.instance_variable_set '@client_extensions', ['ADCGet']
|
55
|
+
end
|
56
|
+
|
57
|
+
context "with zlib compression" do
|
58
|
+
before :each do
|
59
|
+
conn.instance_variable_get('@client_extensions') << 'ZLIG'
|
60
|
+
end
|
61
|
+
|
62
|
+
it "requests a download via the $ADCGET command with ZL1" do
|
63
|
+
conn.should_receive(:send_message).with('ADCGET',
|
64
|
+
'file path/to/file 0 100 ZL1')
|
65
|
+
|
66
|
+
conn.begin_download!
|
67
|
+
end
|
68
|
+
|
69
|
+
it_should_behave_like 'a downloader',
|
70
|
+
'$ADCSND file path/to/file 0 10 ZL1|',
|
71
|
+
Zlib::Deflate.deflate('0123456789')
|
72
|
+
|
73
|
+
it_should_behave_like 'a downloader',
|
74
|
+
'$ADCSND file path/to/file 0 10|', '0123456789'
|
75
|
+
end
|
76
|
+
|
77
|
+
context "without zlib compression" do
|
78
|
+
it "requests a download via the $ADCGET command with ZL1" do
|
79
|
+
conn.should_receive(:send_message).with('ADCGET',
|
80
|
+
'file path/to/file 0 100')
|
81
|
+
|
82
|
+
conn.begin_download!
|
83
|
+
end
|
84
|
+
|
85
|
+
it_should_behave_like 'a downloader',
|
86
|
+
'$ADCSND file path/to/file 0 10|', '0123456789'
|
87
|
+
end
|
88
|
+
|
89
|
+
context "with TTHF enabled" do
|
90
|
+
before :each do
|
91
|
+
conn.instance_variable_get('@client_extensions') << 'TTHF'
|
92
|
+
end
|
93
|
+
|
94
|
+
it "requests a download via $ADCGET with the tth of the file" do
|
95
|
+
conn.should_receive(:send_message).with('ADCGET', 'file TTH/tth 0 100')
|
96
|
+
|
97
|
+
conn.begin_download!
|
98
|
+
end
|
99
|
+
|
100
|
+
it_should_behave_like 'a downloader',
|
101
|
+
'$ADCSND file TTH/tth 0 10|', '0123456789'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Fargo::Protocol::Peer do
|
4
|
+
|
5
|
+
let(:client) { Fargo::Client.new }
|
6
|
+
|
7
|
+
let(:conn) {
|
8
|
+
helper_object(described_class).tap do |conn|
|
9
|
+
conn.stub(:generate_lock).and_return ['lock', 'pk']
|
10
|
+
conn.stub :set_comm_inactivity_timeout
|
11
|
+
conn.post_init
|
12
|
+
conn.client = client
|
13
|
+
end
|
14
|
+
}
|
15
|
+
|
16
|
+
include Fargo::Utils
|
17
|
+
|
18
|
+
describe "the client to client handshake" do
|
19
|
+
before :each do
|
20
|
+
client.config.nick = 'fargo'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "responds with all the correct info when the remote nick is received" do
|
24
|
+
conn.should_receive(:send_data).with('$MyNick fargo|').ordered
|
25
|
+
conn.should_receive(:send_data).with(/^\$Lock \w+ Pk=\w+\|$/).ordered
|
26
|
+
conn.should_receive(:send_data).with(/^\$Supports (\w+ ?)+\|$/).ordered
|
27
|
+
conn.should_receive(:send_data).with(
|
28
|
+
/^\$Direction (Download|Upload) \d+\|$/).ordered
|
29
|
+
conn.should_receive(:send_data).with(
|
30
|
+
"$Key #{generate_key('lock')}|").ordered
|
31
|
+
|
32
|
+
conn.receive_data '$MyNick foobar|$Lock lock Pk=pk|'
|
33
|
+
end
|
34
|
+
|
35
|
+
it "responds correctly when the nick is sent first" do
|
36
|
+
conn.should_receive(:send_data).with('$MyNick fargo|').ordered
|
37
|
+
conn.should_receive(:send_data).with('$Lock lock Pk=pk|').ordered
|
38
|
+
|
39
|
+
conn.send_lock
|
40
|
+
|
41
|
+
conn.should_receive(:send_data).with(/^\$Supports (\w+ ?)+\|$/).ordered
|
42
|
+
conn.should_receive(:send_data).with(
|
43
|
+
/^\$Direction (Download|Upload) \d+\|$/).ordered
|
44
|
+
conn.should_receive(:send_data).with(
|
45
|
+
"$Key #{generate_key('lock')}|").ordered
|
46
|
+
|
47
|
+
conn.receive_data '$MyNick foobar|$Lock lock Pk=pk|$Supports a|' +
|
48
|
+
"$Direction Download 100|$Key #{generate_key('lock')}|"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it "disconnects with an appropriate message" do
|
53
|
+
client.channel.should_receive(:<<).with(
|
54
|
+
[:peer_disconnected, instance_of(Hash)])
|
55
|
+
|
56
|
+
conn.unbind
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Fargo::Protocol::PeerUpload do
|
4
|
+
let(:conn) {
|
5
|
+
helper_object(Fargo::Protocol::Peer).tap do |conn|
|
6
|
+
conn.client = Fargo::Client.new
|
7
|
+
end
|
8
|
+
}
|
9
|
+
let(:file) { Fargo.config.download_dir + '/file' }
|
10
|
+
|
11
|
+
before :each do
|
12
|
+
File.open(file, 'w'){ |f| f << '0123456789' }
|
13
|
+
conn.client.share_directory Fargo.config.download_dir
|
14
|
+
conn.stub(:set_comm_inactivity_timeout)
|
15
|
+
conn.stub(:get_outbound_data_size).and_return 0
|
16
|
+
conn.post_init
|
17
|
+
conn.instance_variable_set '@handshake_step', 5
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "the standard DC protocol using $Get" do
|
21
|
+
it "sends the $FileLength command with the length of the file requested" do
|
22
|
+
conn.should_receive(:send_message).with('FileLength', 10)
|
23
|
+
|
24
|
+
conn.receive_data '$Get tmp/file$1|'
|
25
|
+
end
|
26
|
+
|
27
|
+
it "sends the $FileLength discounting the offset" do
|
28
|
+
conn.should_receive(:send_message).with('FileLength', 10)
|
29
|
+
|
30
|
+
conn.receive_data '$Get tmp/file$5|'
|
31
|
+
end
|
32
|
+
|
33
|
+
it "uploads the file after receiving $Send" do
|
34
|
+
conn.stub(:send_message)
|
35
|
+
conn.receive_data '$Get tmp/file$1|'
|
36
|
+
conn.should_receive(:send_data).with('0123456789')
|
37
|
+
conn.receive_data '$Send|'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "uploading via the ADC protocol" do
|
42
|
+
it "sends the $ADCSND command with ZL1 if requested" do
|
43
|
+
conn.should_receive(:send_message).with('ADCSND',
|
44
|
+
'file tmp/file 0 10 ZL1')
|
45
|
+
conn.stub(:begin_streaming)
|
46
|
+
|
47
|
+
conn.receive_data '$ADCGET file tmp/file 0 -1 ZL1|'
|
48
|
+
end
|
49
|
+
|
50
|
+
it "sends the $ADCSND command without ZL1 when not requested" do
|
51
|
+
conn.should_receive(:send_message).with('ADCSND', 'file tmp/file 0 10')
|
52
|
+
conn.stub(:begin_streaming)
|
53
|
+
|
54
|
+
conn.receive_data '$ADCGET file tmp/file 0 -1|'
|
55
|
+
end
|
56
|
+
|
57
|
+
it "immediately begins uploading the file" do
|
58
|
+
conn.stub(:send_message)
|
59
|
+
conn.should_receive(:send_data).with '0123'
|
60
|
+
|
61
|
+
conn.receive_data '$ADCGET file tmp/file 0 4|'
|
62
|
+
end
|
63
|
+
|
64
|
+
it "compresses the sent data with zlib if requested" do
|
65
|
+
conn.stub(:send_message)
|
66
|
+
conn.should_receive(:send_data).with Zlib::Deflate.deflate('0123')
|
67
|
+
|
68
|
+
conn.receive_data '$ADCGET file tmp/file 0 4 ZL1|'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "huge files" do
|
73
|
+
let(:size) { 16 * 1024 * 2 + 100 }
|
74
|
+
|
75
|
+
before :each do
|
76
|
+
File.open(file + '2', 'w'){ |f| f << ('a' * size) }
|
77
|
+
conn.client.share_directory Fargo.config.download_dir
|
78
|
+
end
|
79
|
+
|
80
|
+
it "are uploaded efficiently" do
|
81
|
+
conn.stub(:send_message)
|
82
|
+
conn.should_receive(:send_data).with('a' * 16 * 1024).twice.ordered
|
83
|
+
conn.should_receive(:send_data).with('a' * 100).ordered
|
84
|
+
|
85
|
+
conn.receive_data '$ADCGET file tmp/file2 0 -1|'
|
86
|
+
end
|
87
|
+
|
88
|
+
it "compresses successfully" do
|
89
|
+
sent_data = ''
|
90
|
+
conn.stub(:send_message)
|
91
|
+
conn.stub(:send_data){ |d| sent_data << d }
|
92
|
+
|
93
|
+
conn.receive_data '$ADCGET file tmp/file2 0 -1 ZL1|'
|
94
|
+
sent_data.should == Zlib::Deflate.deflate('a' * size)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
it "sends $MaxedOut when the client has no slots" do
|
99
|
+
conn.client.take_slot! while conn.client.open_upload_slots > 0
|
100
|
+
|
101
|
+
conn.should_receive(:send_message).with('MaxedOut')
|
102
|
+
|
103
|
+
conn.receive_data '$Get tmp/file$1|'
|
104
|
+
end
|
105
|
+
|
106
|
+
it "doesn't sent $MaxedOut if the requested file is the file list" do
|
107
|
+
conn.client.take_slot! while conn.client.open_upload_slots > 0
|
108
|
+
|
109
|
+
conn.stub(:send_message)
|
110
|
+
conn.should_receive(:send_message).with('MaxedOut').never
|
111
|
+
conn.stub(:begin_streaming)
|
112
|
+
|
113
|
+
conn.receive_data '$Get files.xml.bz2$1|'
|
114
|
+
end
|
115
|
+
|
116
|
+
it "closes the connection when a file list is finished uploading" do
|
117
|
+
conn.stub(:send_data)
|
118
|
+
conn.should_receive(:close_connection_after_writing)
|
119
|
+
|
120
|
+
conn.receive_data '$ADCGET file files.xml.bz2 0 -1|'
|
121
|
+
end
|
122
|
+
|
123
|
+
it "sends $Error when the requested file does not exist" do
|
124
|
+
conn.should_receive(:send_message).with('Error', 'File Not Available')
|
125
|
+
|
126
|
+
conn.receive_data '$Get tmp/nonexistent$1|'
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec::Matchers.define :match_hash do |hash|
|
4
|
+
match do |search|
|
5
|
+
search.matches? hash
|
6
|
+
end
|
7
|
+
|
8
|
+
failure_message_for_should do |search|
|
9
|
+
"#{search.to_s} should have matched the hash: #{hash.inspect}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
RSpec::Matchers.define :match_file do |file|
|
14
|
+
match do |search|
|
15
|
+
search.matches? :file => file
|
16
|
+
end
|
17
|
+
|
18
|
+
failure_message_for_should do |search|
|
19
|
+
"#{search.to_s} should have matched the file: #{file}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe Fargo::Search do
|
24
|
+
it "matches based on file names" do
|
25
|
+
subject.query = 'foo bar'
|
26
|
+
|
27
|
+
subject.should match_file('foobar.mkv')
|
28
|
+
subject.should match_file('foo/bar.avi')
|
29
|
+
subject.should_not match_file('foo.avi')
|
30
|
+
subject.should_not match_file('bar.jpg')
|
31
|
+
end
|
32
|
+
|
33
|
+
it "filters based off of the maximum size of the file" do
|
34
|
+
subject.query = 'foo'
|
35
|
+
subject.size = 100
|
36
|
+
subject.size_restricted = true
|
37
|
+
|
38
|
+
subject.should match_hash(:file => 'foo', :size => 50)
|
39
|
+
subject.should_not match_hash(:file => 'foo', :size => 101)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "filters based off of the minimum size of the file" do
|
43
|
+
subject.query = 'foo'
|
44
|
+
subject.size = 100
|
45
|
+
subject.size_restricted = true
|
46
|
+
subject.is_minimum_size = true
|
47
|
+
|
48
|
+
subject.should_not match_hash(:file => 'foo', :size => 50)
|
49
|
+
subject.should match_hash(:file => 'foo', :size => 101)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "matches based on TTH values" do
|
53
|
+
subject.query = 'TTH:foobar'
|
54
|
+
subject.filetype = Fargo::Search::TTH
|
55
|
+
|
56
|
+
subject.should match_hash(:tth => 'foobar')
|
57
|
+
end
|
58
|
+
|
59
|
+
it "doesn't match on tth if not specified" do
|
60
|
+
subject.query = 'TTH:foobar'
|
61
|
+
|
62
|
+
subject.should_not match_hash(:tth => 'foobar')
|
63
|
+
end
|
64
|
+
|
65
|
+
it "only matches anything with a filetype of ANY" do
|
66
|
+
subject.query = 'foo bar baz'
|
67
|
+
subject.filetype = Fargo::Search::ANY
|
68
|
+
|
69
|
+
subject.should match_file('foo/bar.baz')
|
70
|
+
subject.should match_file('foo/bar/baz')
|
71
|
+
subject.should match_file('foo/a/barb/bazc')
|
72
|
+
subject.should match_file('foo.bar.baz')
|
73
|
+
|
74
|
+
subject.should_not match_file('foo.bar')
|
75
|
+
subject.should_not match_file('foo.babaz')
|
76
|
+
subject.should_not match_file('bar/baz')
|
77
|
+
end
|
78
|
+
|
79
|
+
it "only matches audio with a filetype of AUDIO" do
|
80
|
+
subject.query = 'foo'
|
81
|
+
subject.filetype = Fargo::Search::AUDIO
|
82
|
+
|
83
|
+
subject.should match_file('foo.mp3')
|
84
|
+
subject.should match_file('foo.wav')
|
85
|
+
subject.should match_file('foo.flac')
|
86
|
+
subject.should match_file('foo.m4a')
|
87
|
+
|
88
|
+
subject.should_not match_file('foo.avi')
|
89
|
+
subject.should_not match_file('foo.jpg')
|
90
|
+
subject.should_not match_file('foo.mov')
|
91
|
+
end
|
92
|
+
|
93
|
+
it "only matches videos with a filetype of VIDEOS" do
|
94
|
+
subject.query = 'foo'
|
95
|
+
subject.filetype = Fargo::Search::VIDEO
|
96
|
+
|
97
|
+
subject.should match_file('foobar.mkv')
|
98
|
+
subject.should match_file('foo/bar.avi')
|
99
|
+
subject.should match_file('foobar.mov')
|
100
|
+
subject.should match_file('foobar.mpeg')
|
101
|
+
subject.should match_file('foobar.mpg')
|
102
|
+
|
103
|
+
subject.should_not match_file('foobar')
|
104
|
+
subject.should_not match_file('foobar.jpg')
|
105
|
+
subject.should_not match_file('foo.bar')
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Fargo::Supports::Chat, :type => :em do
|
4
|
+
let(:client) { Fargo::Client.new }
|
5
|
+
|
6
|
+
it "keeps a log of all messages sent" do
|
7
|
+
client.channel << [:chat, 'this is a chat!']
|
8
|
+
client.messages.should == ['this is a chat!']
|
9
|
+
|
10
|
+
client.channel << [:chat, 'another chat']
|
11
|
+
client.messages.should == ['this is a chat!', 'another chat']
|
12
|
+
end
|
13
|
+
|
14
|
+
it "keeps a log of all private messages sent" do
|
15
|
+
client.channel << [:privmsg, {:from => 'foo', :msg => 'this is a chat!'}]
|
16
|
+
client.channel << [:privmsg, {:from => 'foo', :msg => 'another'}]
|
17
|
+
|
18
|
+
client.messages_with('foo').should == [
|
19
|
+
{:from => 'foo', :msg => 'this is a chat!'},
|
20
|
+
{:from => 'foo', :msg => 'another'}
|
21
|
+
]
|
22
|
+
end
|
23
|
+
|
24
|
+
it "clears all the messages once the hub disconnects" do
|
25
|
+
client.channel << [:chat, 'this is a chat!']
|
26
|
+
client.channel << [:privmsg, {:from => 'foo', :msg => 'this is a chat!'}]
|
27
|
+
|
28
|
+
client.channel << [:hub_disconnected, 'foobar!']
|
29
|
+
|
30
|
+
client.messages.should == []
|
31
|
+
client.messages_with('foo').should == []
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Fargo::Supports::LocalFileList do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
@root = Fargo.config.download_dir + '/shared'
|
7
|
+
FileUtils.mkdir_p @root
|
8
|
+
File.open(@root + '/a', 'w'){ |f| f << 'a' }
|
9
|
+
File.open(@root + '/b', 'w'){ |f| f << 'c' }
|
10
|
+
FileUtils.mkdir @root + '/c'
|
11
|
+
File.open(@root + '/c/d', 'w'){ |f| f << 'd' }
|
12
|
+
|
13
|
+
@client = Fargo::Client.new
|
14
|
+
@client.config.override_share_size = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "maintains a list of local files, recursively searching folders" do
|
18
|
+
@client.share_directory @root
|
19
|
+
|
20
|
+
hash = @client.local_file_list
|
21
|
+
hash['shared'].should be_a(Hash)
|
22
|
+
hash['shared']['a'].should be_a(Fargo::Listing)
|
23
|
+
hash['shared']['b'].should be_a(Fargo::Listing)
|
24
|
+
hash['shared']['c'].should be_a(Hash)
|
25
|
+
hash['shared']['c']['d'].should be_a(Fargo::Listing)
|
26
|
+
|
27
|
+
hash['shared']['a'].name.should == 'shared/a'
|
28
|
+
hash['shared']['b'].name.should == 'shared/b'
|
29
|
+
hash['shared']['c']['d'].name.should == 'shared/c/d'
|
30
|
+
end
|
31
|
+
|
32
|
+
it "caches the size of each file shared" do
|
33
|
+
@client.share_directory @root
|
34
|
+
|
35
|
+
@client.share_size.should == 3 # 3 bytes, one in each file
|
36
|
+
end
|
37
|
+
|
38
|
+
it "allows overwriting the published share size just for fun" do
|
39
|
+
@client.config.override_share_size = 100
|
40
|
+
|
41
|
+
@client.share_size.should == 100
|
42
|
+
end
|
43
|
+
|
44
|
+
it "correctly creates an array of listings that it's sharing" do
|
45
|
+
@client.share_directory @root
|
46
|
+
|
47
|
+
listings = @client.local_listings
|
48
|
+
|
49
|
+
listings.size.should == 3
|
50
|
+
|
51
|
+
listings.shift.name.should == 'shared/a'
|
52
|
+
listings.shift.name.should == 'shared/b'
|
53
|
+
listings.shift.name.should == 'shared/c/d'
|
54
|
+
end
|
55
|
+
|
56
|
+
it "finds listings correctly when given their name" do
|
57
|
+
@client.share_directory @root
|
58
|
+
|
59
|
+
ret_val = @client.listing_for 'shared/a'
|
60
|
+
ret_val.should be_a(Fargo::Listing)
|
61
|
+
ret_val.name.should == 'shared/a'
|
62
|
+
end
|
63
|
+
|
64
|
+
it "also finds listings based on their TTH value" do
|
65
|
+
@client.share_directory @root
|
66
|
+
listing = @client.local_listings[0]
|
67
|
+
|
68
|
+
@client.listing_for('TTH/' + listing.tth).should == listing
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Fargo::Supports::NickList, :type => :em do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
@client = Fargo::Client.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'gets the most up to date information about the nick' do
|
10
|
+
@client.should_receive(:info).with('nick').twice
|
11
|
+
@client.nick_has_slot? 'nick' # Triggers info the first time
|
12
|
+
@client.nick_has_slot? 'nick' # Make sure we didn't cache the results
|
13
|
+
end
|
14
|
+
|
15
|
+
it "uses results from search queries for open slot information" do
|
16
|
+
@client.channel << [:search_result, {:nick => 'nick', :open_slots => 0}]
|
17
|
+
@client.nick_has_slot?('nick').should be_false
|
18
|
+
|
19
|
+
@client.channel << [:search_result, {:nick => 'nick', :open_slots => 1}]
|
20
|
+
@client.nick_has_slot?('nick').should be_true
|
21
|
+
|
22
|
+
t = Time.now + 20.minutes
|
23
|
+
Time.stub(:now).and_return t
|
24
|
+
@client.stub(:info).with('nick').and_return nil
|
25
|
+
@client.nick_has_slot?('nick').should be_false
|
26
|
+
end
|
27
|
+
|
28
|
+
it "gets the nick list from the subscribed channel" do
|
29
|
+
@client.nicks.should == []
|
30
|
+
|
31
|
+
@client.channel << [:nick_list, {:nicks => ['a', 'b']}]
|
32
|
+
|
33
|
+
@client.nicks.should == ['a', 'b']
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Fargo::Utils do
|
4
|
+
|
5
|
+
let(:helper) {
|
6
|
+
o = Object.new
|
7
|
+
o.send(:class_eval) do
|
8
|
+
include Fargo::Utils
|
9
|
+
end
|
10
|
+
o
|
11
|
+
}
|
12
|
+
|
13
|
+
it "generates a correct key" do
|
14
|
+
helper.generate_key('FOO').should == "4\220/%DCN000%/"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "generates a correct lock and pk" do
|
18
|
+
# there's not a whole lot of documentation about this online...
|
19
|
+
20.times do
|
20
|
+
lock, pk = helper.generate_lock
|
21
|
+
pk.size.should >= 0
|
22
|
+
lock.size.should >= 0
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
require 'rspec/core'
|
5
|
+
require 'fargo'
|
6
|
+
|
7
|
+
download_dir = File.expand_path '../tmp', __FILE__
|
8
|
+
|
9
|
+
Fargo.logger.level = ActiveSupport::BufferedLogger::WARN
|
10
|
+
|
11
|
+
RSpec.configure do |c|
|
12
|
+
c.color_enabled = true
|
13
|
+
|
14
|
+
c.before :each do
|
15
|
+
Fargo.configure do |config|
|
16
|
+
config.download_dir = download_dir
|
17
|
+
config.config_dir = download_dir + '/config'
|
18
|
+
config.nick = 'fargo'
|
19
|
+
config.override_share_size = nil
|
20
|
+
config.upload_slots = 4
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
c.around :each do |example|
|
25
|
+
FileUtils.mkdir_p download_dir
|
26
|
+
example.run
|
27
|
+
FileUtils.rm_rf download_dir
|
28
|
+
end
|
29
|
+
|
30
|
+
c.around :each, :type => :em do |example|
|
31
|
+
EventMachine.run {
|
32
|
+
example.run
|
33
|
+
|
34
|
+
EventMachine.stop_event_loop
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
Dir[File.dirname(__FILE__) + '/support/*.rb'].each { |f| load f }
|
40
|
+
|
41
|
+
def helper_object mod
|
42
|
+
o = Object.new
|
43
|
+
o.send(:class_eval) do
|
44
|
+
include mod
|
45
|
+
end
|
46
|
+
o
|
47
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
RSpec::Matchers.define :have_contents do |contents|
|
2
|
+
match do |file|
|
3
|
+
File.file?(file) && File.read(file).chomp.should == contents.chomp
|
4
|
+
end
|
5
|
+
|
6
|
+
failure_message do |file|
|
7
|
+
msg = "Expected #{file} to contain:\n\t#{contents.gsub("\n", "\n\t")}\nWhen"
|
8
|
+
|
9
|
+
if File.file?(file)
|
10
|
+
msg += " it contained:\n#{File.read(file)}".gsub("\n", "\n\t")
|
11
|
+
else
|
12
|
+
msg += ' it did not exist.'
|
13
|
+
end
|
14
|
+
|
15
|
+
msg
|
16
|
+
end
|
17
|
+
end
|