em-irc 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  module EventMachine
2
2
  module IRC
3
- VERSION = '0.0.1'
3
+ VERSION = '0.0.2'
4
4
  end
5
5
  end
@@ -0,0 +1,22 @@
1
+ module DslAccessor
2
+ def self.included(base)
3
+ base.extend Macros
4
+ end
5
+
6
+ module Macros
7
+ def dsl_accessor(*keys)
8
+ keys.map(&:to_s).each do |k|
9
+ class_eval <<-ACCESSORS
10
+ attr_writer :#{k}
11
+ def #{k}(v = nil)
12
+ if v
13
+ @#{k} = v
14
+ else
15
+ @#{k}
16
+ end
17
+ end
18
+ ACCESSORS
19
+ end
20
+ end
21
+ end
22
+ end
@@ -19,11 +19,16 @@ end
19
19
 
20
20
  shared_examples_for "integration" do
21
21
  it 'should work' do
22
- dan = client(nick: 'dan')
23
- bob = client(nick: 'bob')
22
+ dan = client
23
+ bob = client
24
+ ace = client
24
25
 
25
- dan.on(:connect) {dan.join('#americano-test')}
26
- bob.on(:connect) {bob.join('#americano-test')}
26
+ dan.on(:connect) {dan.nick('dan')}
27
+ bob.on(:connect) {bob.nick('bob')}
28
+ ace.on(:connect) {ace.nick('bob')}
29
+
30
+ dan.on(:nick) {dan.join('#americano-test')}
31
+ bob.on(:nick) {bob.join('#americano-test')}
27
32
 
28
33
  bob.on(:join) do |who, channel|
29
34
  bob.message(channel, "dan: hello bob")
@@ -31,19 +36,34 @@ shared_examples_for "integration" do
31
36
  # dan.quit
32
37
  end
33
38
 
39
+ dan.on(:message) do |who, channel, message|
40
+ @who = who
41
+ @channel = channel
42
+ @message = message
43
+ end
44
+
34
45
  EM.run {
35
46
  dan.connect
36
- EM::add_timer(2) {bob.connect}
37
- EM::add_timer(5) {EM::stop}
47
+ bob.connect
48
+ ace.connect
49
+ EM::add_timer(2) {EM::stop}
38
50
  }
39
51
 
40
52
  # TODO: matchers for commands
53
+ dan.nick.should == 'dan'
41
54
  dan.history.should =~ /Welcome/
42
55
  dan.history.should =~ /JOIN :#americano-test/
43
- dan.history.should =~ /dan: hello bob/
44
56
 
57
+ @who.should == "bob"
58
+ @channel.should == "#americano-test"
59
+ @message.should == "dan: hello bob"
60
+
61
+ bob.nick.should == 'bob'
45
62
  bob.history.should =~ /Welcome/
46
63
  bob.history.should =~ /JOIN :#americano-test/
64
+
65
+ ace.nick.should == nil
66
+ ace.history.should =~ /Nickname already in use/
47
67
  end
48
68
  end
49
69
 
@@ -51,8 +71,8 @@ end
51
71
  describe EventMachine::IRC::Client, :integration => true do
52
72
  let(:options) do
53
73
  {
54
- host: '127.0.0.1',
55
- port: '16667'
74
+ :host => '127.0.0.1',
75
+ :port => '16667'
56
76
  }.merge(@options || {})
57
77
  end
58
78
 
@@ -71,8 +91,8 @@ describe EventMachine::IRC::Client, :integration => true do
71
91
  before :all do
72
92
  raise "encrypted ircd not on :16697" unless `lsof -i :16697`.chomp.size > 1
73
93
  @options = {
74
- port: '16697',
75
- ssl: true
94
+ :port => '16697',
95
+ :ssl => true
76
96
  }
77
97
  end
78
98
  it_behaves_like "integration"
@@ -26,16 +26,23 @@ describe EventMachine::IRC::Client do
26
26
  subject.should_not be_connected
27
27
  end
28
28
 
29
- it 'should default a nick' do
30
- subject.nick.should_not be_blank
29
+ it 'should have blank nick' do
30
+ subject.nick.should be_blank
31
31
  end
32
32
 
33
- it 'should yield self' do
34
- client = described_class.new do |c|
33
+ it 'should optionally yield self' do
34
+ described_class.new do |c|
35
35
  c.should be_kind_of(described_class)
36
36
  end
37
37
  end
38
38
 
39
+ it 'should optionally instance eval' do
40
+ client = described_class.new do
41
+ host 'stella.net'
42
+ end
43
+ client.host.should == 'stella.net'
44
+ end
45
+
39
46
  it 'should allow a custom logger' do
40
47
  subject.logger = Logger.new(STDOUT)
41
48
  subject.logger = nil
@@ -43,15 +50,15 @@ describe EventMachine::IRC::Client do
43
50
  end
44
51
 
45
52
  context 'connect' do
46
- it 'should create an EM TCP connection with host, port, handler, and self' do
47
- EventMachine.should_receive(:connect).with('irc.net', '9999', EventMachine::IRC::Dispatcher, parent: subject)
53
+ it 'should create an EM TCP connection with host, port, handler, and ssl' do
54
+ EventMachine.should_receive(:connect).with('irc.net', '9999', EventMachine::IRC::Dispatcher, :parent => subject, :ssl => subject.ssl)
48
55
  subject.host = 'irc.net'
49
56
  subject.port = '9999'
50
57
  subject.connect
51
58
  end
52
59
 
53
60
  it 'should be idempotent' do
54
- EventMachine.stub(connect: mock('Connection'))
61
+ EventMachine.stub(:connect => mock('Connection'))
55
62
  EventMachine.should_receive(:connect).exactly(1).times
56
63
  subject.connect
57
64
  subject.connect
@@ -61,17 +68,17 @@ describe EventMachine::IRC::Client do
61
68
  context 'send_data' do
62
69
  before do
63
70
  @connection = mock('Connection')
64
- subject.stub(conn: @connection)
65
- subject.stub(connected?: true)
71
+ subject.stub(:conn => @connection)
72
+ subject.stub(:connected? => true)
66
73
  end
67
74
 
68
75
  it 'should return false if not connected' do
69
- subject.stub(connected?: nil)
76
+ subject.stub(:connected? => nil)
70
77
  subject.send_data("NICK jch").should be_false
71
78
  end
72
79
 
73
80
  it 'should send message to irc server' do
74
- subject.stub(conn: @connection)
81
+ subject.stub(:conn => @connection)
75
82
  @connection.should_receive(:send_data).with("NICK jch\r\n")
76
83
  subject.send_data("NICK jch")
77
84
  end
@@ -79,7 +86,7 @@ describe EventMachine::IRC::Client do
79
86
 
80
87
  context 'ready' do
81
88
  before do
82
- subject.stub(conn: mock.as_null_object)
89
+ subject.stub(:conn => mock.as_null_object)
83
90
  end
84
91
 
85
92
  it 'should call :connect callback' do
@@ -122,48 +129,49 @@ describe EventMachine::IRC::Client do
122
129
  parsed = subject.parse_message('PING :irc.net')
123
130
  parsed[:params] =~ ['irc.net']
124
131
  end
132
+
133
+ it 'should return strings as a single param' do
134
+ parsed = subject.parse_message(":irc.the.net 001 jessie :Welcome to the Internet Relay Network jessie!~jessie@localhost")
135
+ parsed[:params] =~ ['jessie', 'Welcome to the Internet Relay Network jessie!~jessie@localhost']
136
+ end
125
137
  end
126
138
  end
127
139
 
128
140
  context 'receive_data' do
129
- before do
130
- subject.stub(:parse_message).and_return(mock.as_null_object)
131
- subject.stub(:handle_parsed_message).and_return(mock.as_null_object)
132
- end
133
-
134
- it 'should parse messages separated by \r\n' do
135
- data = [
141
+ let(:data) {
142
+ [
136
143
  ":irc.the.net 001 jessie :Welcome to the Internet Relay Network jessie!~jessie@localhost",
137
144
  ":irc.the.net 002 jessie :Your host is irc.the.net, running version ngircd-17.1 (i386/apple/darwin11.2.0)",
138
145
  ":irc.the.net 003 jessie :This server has been started Fri Feb 03 2012 at 14:42:38 (PST)"
139
146
  ].join("\r\n")
147
+ }
148
+ let(:parsed_message) {mock.as_null_object}
149
+
150
+ before do
151
+ subject.stub(:parse_message).and_return(parsed_message)
152
+ subject.stub(:handle_parsed_message)
153
+ end
140
154
 
155
+ it 'should parse messages separated by \r\n' do
141
156
  subject.should_receive(:parse_message).exactly(3).times
142
- subject.should_receive(:handle_parsed_message).exactly(3).times
143
157
  subject.receive_data(data)
144
158
  end
145
159
 
146
160
  it 'should handle parsed messages' do
161
+ subject.should_receive(:handle_parsed_message).exactly(3).times
162
+ subject.receive_data(data)
147
163
  end
148
- end
149
164
 
150
- context 'handle_parsed_message' do
151
- it 'should respond to pings' do
152
- subject.should_receive(:pong).with("irc.net")
153
- subject.handle_parsed_message({prefix: 'irc.net', command: 'PING', params: ['irc.net']})
165
+ it 'should trigger :raw callbacks' do
166
+ subject.should_receive(:trigger).with(:raw, parsed_message).exactly(3).times
167
+ subject.receive_data(data)
154
168
  end
169
+ end
155
170
 
156
- # TODO: do we want a delegate object and callbacks?
157
- # it 'should call optional delegate' do
158
- # subject.stub(delegate: mock('Delegate'))
159
- # subject.delegate.should_receive(:message)
160
- # subject.handle_parsed_message({prefix: 'jessie!jessie@localhost', command: 'PRIVMSG', params: ['#general', 'hello world'])
161
- # end
162
-
163
- it 'should trigger :raw callbacks' do
164
- m = mock('Parsed Response').as_null_object
165
- subject.should_receive(:trigger).with(:raw, m)
166
- subject.handle_parsed_message(m)
171
+ context 'handle_parsed_message' do
172
+ it 'should trigger error for messages 400-599' do
173
+ subject.should_receive(:trigger).with(:error, 'ERR_NICKNAMEINUSE')
174
+ subject.handle_parsed_message(:command => '433', :params => ['ERR_NICKNAMEINUSE'])
167
175
  end
168
176
  end
169
177
 
@@ -0,0 +1,166 @@
1
+ require 'spec_helper'
2
+
3
+ describe EventMachine::IRC::Commands do
4
+ subject {EventMachine::IRC::Client.new}
5
+
6
+ context "nick" do
7
+ it 'should set nick' do
8
+ subject.should_receive(:send_data).with("NICK jch")
9
+ subject.nick('jch')
10
+ end
11
+
12
+ it 'should get nick' do
13
+ subject.instance_eval {@nick = 'jch'}
14
+ subject.nick.should == 'jch'
15
+ end
16
+ end
17
+
18
+ context "join" do
19
+ it 'should join single channel' do
20
+ subject.should_receive(:send_data).with("JOIN #general")
21
+ subject.join("#general")
22
+ end
23
+
24
+ it 'should join multiple channels' do
25
+ subject.should_receive(:send_data).with("JOIN #general,#foo")
26
+ subject.join('#general', '#foo')
27
+ end
28
+
29
+ it 'should join channels with keys' do
30
+ subject.should_receive(:send_data).with("JOIN #foo,&bar fubar,bazly")
31
+ subject.join(['#foo', 'fubar'], ['&bar', 'bazly'])
32
+ end
33
+
34
+ it 'should join channels with and without keys' do
35
+ subject.should_receive(:send_data).with("JOIN #foo,#cat,&bar fubar,dog")
36
+ subject.join(['#foo', 'fubar'], '&bar', ["#cat", "dog"])
37
+ end
38
+
39
+ it 'should leave all currently joined channels' do
40
+ subject.should_receive(:join).with('0')
41
+ subject.join('0')
42
+ end
43
+ end
44
+
45
+ context "part_all" do
46
+ it 'should leave all currently joined channels' do
47
+ subject.should_receive(:join).with('0')
48
+ subject.part_all
49
+ end
50
+ end
51
+
52
+ context "part" do
53
+ it 'should part single' do
54
+ subject.should_receive(:send_data).with('PART #general :Leaving...')
55
+ subject.part('#general')
56
+ end
57
+
58
+ it 'should part single with custom message' do
59
+ subject.should_receive(:send_data).with('PART #general :Goodbye everybody!')
60
+ subject.part('#general', 'Goodbye everybody!')
61
+ end
62
+
63
+ it 'should part multiple' do
64
+ subject.should_receive(:send_data).with('PART #general,#foo :Leaving...')
65
+ subject.part('#general', '#foo')
66
+ end
67
+
68
+ it 'should part multiple with custom message' do
69
+ subject.should_receive(:send_data).with('PART #general,#foo :Goodbye everybody!')
70
+ subject.part('#general', '#foo', 'Goodbye everybody!')
71
+ end
72
+ end
73
+
74
+ context "topic" do
75
+ it 'should get topic' do
76
+ subject.should_receive(:send_data).with("TOPIC #foo")
77
+ subject.topic('#foo')
78
+ end
79
+
80
+ it 'should set topic' do
81
+ subject.should_receive(:send_data).with("TOPIC #foo :awesome channel")
82
+ subject.topic('#foo', "awesome channel")
83
+ end
84
+
85
+ it 'should unset topic' do
86
+ subject.should_receive(:send_data).with("TOPIC #foo :")
87
+ subject.topic('#foo', '')
88
+ end
89
+ end
90
+
91
+ context "names" do
92
+ it 'should list names for a single channel' do
93
+ subject.should_receive(:send_data).with("NAMES #foo")
94
+ subject.names("#foo")
95
+ end
96
+
97
+ it 'should list names for multiple channels' do
98
+ subject.should_receive(:send_data).with("NAMES #foo,&bar")
99
+ subject.names("#foo", "&bar")
100
+ end
101
+
102
+ it 'should list names with a target server' do
103
+ subject.should_receive(:send_data).with("NAMES #foo,&bar irc.net")
104
+ subject.names("#foo", "&bar", :target => 'irc.net')
105
+ end
106
+ end
107
+
108
+ context "list" do
109
+ it 'should list channel and topic' do
110
+ subject.should_receive(:send_data).with("LIST #foo")
111
+ subject.list("#foo")
112
+ end
113
+
114
+ it 'should list channels and topics for multiple channels' do
115
+ subject.should_receive(:send_data).with("LIST #foo,&bar")
116
+ subject.list("#foo", "&bar")
117
+ end
118
+
119
+ it 'should list names with a target server' do
120
+ subject.should_receive(:send_data).with("LIST #foo,&bar irc.net")
121
+ subject.list("#foo", "&bar", :target => 'irc.net')
122
+ end
123
+ end
124
+
125
+ context 'invite' do
126
+ it 'should invite user to a channel' do
127
+ subject.should_receive(:send_data).with("INVITE jch #foo")
128
+ subject.invite("jch", "#foo")
129
+ end
130
+ end
131
+
132
+ context 'kick' do
133
+ it 'should kick user from channel' do
134
+ subject.should_receive(:send_data).with("KICK #general jch")
135
+ subject.kick("#general", "jch")
136
+ end
137
+
138
+ it 'should kick multiple users from channels' do
139
+ subject.should_receive(:send_data).with("KICK #general,&bar jch,wcc")
140
+ subject.kick("#general", "&bar", "jch", "wcc")
141
+ end
142
+
143
+ it 'should raise error if no channels' do
144
+ expect {
145
+ subject.kick('jch')
146
+ }.to raise_error(ArgumentError)
147
+ end
148
+ end
149
+
150
+ context 'whois' do
151
+ it 'should query user' do
152
+ subject.should_receive(:send_data).with("WHOIS jch")
153
+ subject.whois('jch')
154
+ end
155
+
156
+ it 'should query users' do
157
+ subject.should_receive(:send_data).with("WHOIS jch,bar")
158
+ subject.whois('jch', 'bar')
159
+ end
160
+
161
+ it 'should query user from a target server' do
162
+ subject.should_receive(:send_data).with("WHOIS irc.net jch,bar")
163
+ subject.whois('jch', 'bar', :target => 'irc.net')
164
+ end
165
+ end
166
+ end
@@ -2,12 +2,14 @@ require 'spec_helper'
2
2
 
3
3
  shared_examples_for 'dispatcher' do
4
4
  it 'should delegate connection methods to parent' do
5
- parent = Class.new do
6
- attr_accessor :conn
7
- def ssl
8
- $ssl
5
+ module TestServer
6
+ def post_init
7
+ send_data "message"
9
8
  end
9
+ end
10
10
 
11
+ parent = Class.new do
12
+ attr_accessor :conn
11
13
  def receive_data(data)
12
14
  EventMachine::stop_event_loop
13
15
  raise "Didn't get expected message" unless data == 'message'
@@ -16,11 +18,9 @@ shared_examples_for 'dispatcher' do
16
18
  parent.should_receive(:ready)
17
19
  parent.should_receive(:unbind)
18
20
  EventMachine.run {
19
- EventMachine::start_server('127.0.0.1', '198511', described_class, parent: parent)
20
- EventMachine::connect('127.0.0.1', '198511') do |conn|
21
- conn.send_data("message")
22
- end
23
- EventMachine::add_timer(2) {
21
+ EventMachine::start_server('127.0.0.1', '198511', TestServer)
22
+ EventMachine::connect('127.0.0.1', '198511', EventMachine::IRC::Dispatcher, :parent => parent, :ssl => ssl)
23
+ EventMachine::add_timer(3) {
24
24
  EventMachine::stop_event_loop
25
25
  raise "Never reached receive_data or took too long"
26
26
  }
@@ -30,15 +30,15 @@ end
30
30
 
31
31
  describe EventMachine::IRC::Dispatcher do
32
32
  context 'ssl integration' do
33
- before {$ssl = true}
34
- it 'behaves like dispatcher' do
35
- pending "not sure how to test ssl"
36
- end
37
- # it_behaves_like "dispatcher"
33
+ it "how to test ssl?"
34
+ # it_behaves_like "dispatcher" do
35
+ # let(:ssl) {true}
36
+ # end
38
37
  end
39
38
 
40
39
  context 'non-ssl integration' do
41
- before {$ssl = false}
42
- it_behaves_like "dispatcher"
40
+ it_behaves_like "dispatcher" do
41
+ let(:ssl) {false}
42
+ end
43
43
  end
44
44
  end