socky 0.0.7 → 0.0.8
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/CHANGELOG.textile +25 -0
- data/README.textile +27 -0
- data/Rakefile +19 -0
- data/VERSION +1 -1
- data/lib/em-websocket_hacks.rb +1 -3
- data/lib/socky.rb +17 -15
- data/lib/socky/connection.rb +12 -6
- data/lib/socky/connection/authentication.rb +7 -6
- data/lib/socky/connection/finders.rb +3 -3
- data/lib/socky/message.rb +26 -20
- data/lib/socky/misc.rb +2 -2
- data/lib/socky/net_request.rb +2 -2
- data/lib/socky/options.rb +16 -18
- data/lib/socky/options/config.rb +37 -18
- data/lib/socky/options/parser.rb +50 -40
- data/lib/socky/runner.rb +3 -4
- data/lib/socky/server.rb +1 -1
- data/spec/em-websocket_spec.rb +37 -0
- data/spec/files/default.yml +7 -0
- data/spec/files/invalid.yml +1 -0
- data/spec/socky/connection/authentication_spec.rb +162 -0
- data/spec/socky/connection/finders_spec.rb +96 -0
- data/spec/socky/connection_spec.rb +143 -0
- data/spec/socky/message_spec.rb +260 -0
- data/spec/socky/misc_spec.rb +74 -0
- data/spec/socky/net_request_spec.rb +43 -0
- data/spec/socky/options/config_spec.rb +67 -0
- data/spec/socky/options/parser_spec.rb +59 -0
- data/spec/socky/options_spec.rb +65 -0
- data/spec/socky/runner_spec.rb +73 -0
- data/spec/socky/server_spec.rb +35 -0
- data/spec/socky_spec.rb +82 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/stallion.rb +96 -0
- metadata +39 -7
- data/README +0 -10
data/lib/socky/options/parser.rb
CHANGED
@@ -1,58 +1,68 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
1
3
|
module Socky
|
2
|
-
|
3
|
-
|
4
|
+
class Options
|
5
|
+
class Parser
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
opts
|
7
|
+
class << self
|
8
|
+
def parse(argv)
|
9
|
+
result = {}
|
10
|
+
opts = OptionParser.new do |opts|
|
11
|
+
opts.summary_width = 25
|
12
|
+
opts.banner = "Usage: socky [options]\n"
|
9
13
|
|
10
|
-
|
11
|
-
|
14
|
+
opts.separator ""
|
15
|
+
opts.separator "Configuration:"
|
12
16
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
+
opts.on("-g", "--generate FILE", String, "Generate config file") do |path|
|
18
|
+
result[:config_path] = File.expand_path(path) if path
|
19
|
+
Config.generate(result[:config_path])
|
20
|
+
end
|
17
21
|
|
18
|
-
|
19
|
-
|
20
|
-
|
22
|
+
opts.on("-c", "--config FILE", String, "Path to configuration file.", "(default: #{Socky.config_path})") do |path|
|
23
|
+
result[:config_path] = File.expand_path(path)
|
24
|
+
end
|
21
25
|
|
22
|
-
|
26
|
+
opts.separator ""; opts.separator "Network:"
|
23
27
|
|
24
|
-
|
25
|
-
|
26
|
-
|
28
|
+
opts.on("-p", "--port PORT", Integer, "Specify port", "(default: 8080)") do |port|
|
29
|
+
result[:port] = port
|
30
|
+
end
|
27
31
|
|
28
|
-
|
32
|
+
opts.separator ""; opts.separator "Logging:"
|
29
33
|
|
30
|
-
|
31
|
-
|
32
|
-
|
34
|
+
opts.on("-l", "--log FILE", String, "Path to print debugging information.", "(default: #{Socky.log_path})") do |path|
|
35
|
+
result[:log_path] = File.expand_path(path)
|
36
|
+
end
|
33
37
|
|
34
|
-
|
35
|
-
|
36
|
-
|
38
|
+
opts.on("--debug", "Run in debug mode") do
|
39
|
+
result[:debug] = true
|
40
|
+
end
|
37
41
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
+
opts.on("--deep-debug", "Run in debug mode that is even more verbose") do
|
43
|
+
result[:debug] = true
|
44
|
+
result[:deep_debug] = true
|
45
|
+
end
|
42
46
|
|
43
|
-
|
47
|
+
opts.separator ""; opts.separator "Miscellaneous:"
|
44
48
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
+
opts.on_tail("-?", "--help", "Display this usage information.") do
|
50
|
+
puts "#{opts}\n"
|
51
|
+
exit
|
52
|
+
end
|
49
53
|
|
50
|
-
|
51
|
-
|
52
|
-
|
54
|
+
opts.on_tail("-v", "--version", "Display version") do
|
55
|
+
puts "Socky #{VERSION}"
|
56
|
+
exit
|
57
|
+
end
|
53
58
|
end
|
54
|
-
|
55
|
-
|
59
|
+
opts.parse!(argv)
|
60
|
+
result
|
61
|
+
rescue OptionParser::InvalidOption => error
|
62
|
+
puts "#{opts}\n"
|
63
|
+
puts error.message
|
64
|
+
exit
|
65
|
+
end
|
56
66
|
end
|
57
67
|
|
58
68
|
end
|
data/lib/socky/runner.rb
CHANGED
@@ -1,17 +1,16 @@
|
|
1
1
|
module Socky
|
2
2
|
class Runner
|
3
3
|
include Socky::Misc
|
4
|
-
include Socky::Options
|
5
4
|
|
6
5
|
class << self
|
7
6
|
def run(argv = ARGV)
|
8
|
-
self.new(argv)
|
7
|
+
server = self.new(argv)
|
8
|
+
server.start
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
12
|
def initialize(argv = ARGV)
|
13
|
-
|
14
|
-
start
|
13
|
+
Options.prepare(argv)
|
15
14
|
end
|
16
15
|
|
17
16
|
def start
|
data/lib/socky/server.rb
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe EM::WebSocket::Connection do
|
4
|
+
|
5
|
+
it "should not receive debug message if :debug option is false" do
|
6
|
+
Socky.logger.stub!(:debug)
|
7
|
+
Socky.logger.should_not_receive(:debug)
|
8
|
+
EM.run do
|
9
|
+
EM.add_timer(0.1) do
|
10
|
+
http = EventMachine::HttpRequest.new('ws://127.0.0.1:9999/').get(:timeout => 0)
|
11
|
+
http.errback { http.close_connection }
|
12
|
+
http.callback { http.close_connection }
|
13
|
+
end
|
14
|
+
|
15
|
+
EM::WebSocket.start(:host => "127.0.0.1", :port => 9999, :debug => false) do |ws|
|
16
|
+
ws.onclose { EM.stop }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should use Socky.logger.debug instead of pp when instance call #debug" do
|
22
|
+
Socky.logger.stub!(:debug)
|
23
|
+
Socky.logger.should_receive(:debug).with("Socket initialize")
|
24
|
+
EM.run do
|
25
|
+
EM.add_timer(0.1) do
|
26
|
+
http = EventMachine::HttpRequest.new('ws://127.0.0.1:9999/').get(:timeout => 0)
|
27
|
+
http.errback { http.close_connection }
|
28
|
+
http.callback { http.close_connection }
|
29
|
+
end
|
30
|
+
|
31
|
+
EM::WebSocket.start(:host => "127.0.0.1", :port => 9999, :debug => true) do |ws|
|
32
|
+
ws.onclose { EM.stop }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
invalid data
|
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe Socky::Connection::Authentication do
|
4
|
+
include Socky::Connection::Authentication
|
5
|
+
|
6
|
+
context "instance" do
|
7
|
+
context "#subscribe_request" do
|
8
|
+
it "should not call #send_subscribe_request if already authenticated" do
|
9
|
+
stub!(:authenticated?).and_return(true)
|
10
|
+
should_not_receive(:send_subscribe_request)
|
11
|
+
subscribe_request
|
12
|
+
end
|
13
|
+
it "should call #send_subscribe_request if unauthenticated" do
|
14
|
+
stub!(:authenticated?).and_return(false)
|
15
|
+
should_receive(:send_subscribe_request)
|
16
|
+
subscribe_request
|
17
|
+
end
|
18
|
+
it "should add self to connection list if #send_subscribe_request block is true" do
|
19
|
+
stub!(:authenticated?).and_return(false)
|
20
|
+
stub!(:send_subscribe_request).and_yield(true)
|
21
|
+
should_receive(:add_to_pool)
|
22
|
+
subscribe_request
|
23
|
+
end
|
24
|
+
it "should be authenticated by url if #send_subscribe_request block is true" do
|
25
|
+
stub!(:authenticated?).and_return(false)
|
26
|
+
stub!(:send_subscribe_request).and_yield(true)
|
27
|
+
stub!(:add_to_pool)
|
28
|
+
subscribe_request
|
29
|
+
authenticated_by_url?.should be_true
|
30
|
+
end
|
31
|
+
it "should disconnect if #send_subscribe_request block is false" do
|
32
|
+
stub!(:admin).and_return(false)
|
33
|
+
stub!(:send_subscribe_request).and_yield(false)
|
34
|
+
should_receive(:disconnect)
|
35
|
+
subscribe_request
|
36
|
+
end
|
37
|
+
end
|
38
|
+
context "#unsubscribe_request" do
|
39
|
+
it "should remove self from connection list if authenticated" do
|
40
|
+
stub!(:admin).and_return(false)
|
41
|
+
stub!(:authenticated?).and_return(true)
|
42
|
+
should_receive(:remove_from_pool)
|
43
|
+
unsubscribe_request
|
44
|
+
end
|
45
|
+
it "should send unsubscribe request if authenticated but not admin" do
|
46
|
+
stub!(:admin).and_return(false)
|
47
|
+
stub!(:authenticated?).and_return(true)
|
48
|
+
stub!(:remove_from_pool)
|
49
|
+
should_receive(:send_unsubscribe_request)
|
50
|
+
unsubscribe_request
|
51
|
+
end
|
52
|
+
it "should not send unsubscribe request if authenticated and admin" do
|
53
|
+
stub!(:admin).and_return(true)
|
54
|
+
stub!(:authenticated?).and_return(true)
|
55
|
+
stub!(:remove_from_pool)
|
56
|
+
should_not_receive(:send_unsubscribe_request)
|
57
|
+
unsubscribe_request
|
58
|
+
end
|
59
|
+
it "should not send unsubscribe request if unauthenticated" do
|
60
|
+
stub!(:authenticated?).and_return(false)
|
61
|
+
should_not_receive(:send_unsubscribe_request)
|
62
|
+
unsubscribe_request
|
63
|
+
end
|
64
|
+
end
|
65
|
+
context "#authenticated?" do
|
66
|
+
it "should authenticate as admin if admin" do
|
67
|
+
stub!(:admin).and_return(true)
|
68
|
+
should_receive(:authenticate_as_admin)
|
69
|
+
authenticated?
|
70
|
+
end
|
71
|
+
it "should authenticate as user if not admin" do
|
72
|
+
stub!(:admin).and_return(false)
|
73
|
+
should_receive(:authenticate_as_user)
|
74
|
+
authenticated?
|
75
|
+
end
|
76
|
+
end
|
77
|
+
context "#authenticate_as_admin" do
|
78
|
+
it "should return true if admin" do
|
79
|
+
stub!(:admin).and_return(true)
|
80
|
+
authenticate_as_admin.should be_true
|
81
|
+
end
|
82
|
+
it "should return false if not admin" do
|
83
|
+
stub!(:admin).and_return(false)
|
84
|
+
authenticate_as_admin.should be_false
|
85
|
+
end
|
86
|
+
end
|
87
|
+
it "#authenticate_as_user should call #authenticated_by_url?" do
|
88
|
+
should_receive(:authenticated_by_url?)
|
89
|
+
authenticate_as_user
|
90
|
+
end
|
91
|
+
it "#authenticated_by_url? should return current status" do
|
92
|
+
instance_variable_set('@authenticated_by_url',true)
|
93
|
+
authenticated_by_url?.should be_true
|
94
|
+
instance_variable_set('@authenticated_by_url',false)
|
95
|
+
authenticated_by_url?.should be_false
|
96
|
+
end
|
97
|
+
context "#send_subscribe_request" do
|
98
|
+
it "should build params for request if socky option subscribe_url is not nil" do
|
99
|
+
Socky.stub!(:options).and_return({:subscribe_url => "any"})
|
100
|
+
should_receive(:params_for_request)
|
101
|
+
send_subscribe_request
|
102
|
+
end
|
103
|
+
it "should call Socky::NetRequest#post if socky option subscribe_url is not nil" do
|
104
|
+
Socky.stub!(:options).and_return({:subscribe_url => "any"})
|
105
|
+
stub!(:params_for_request)
|
106
|
+
Socky::NetRequest.should_receive(:post)
|
107
|
+
send_subscribe_request
|
108
|
+
end
|
109
|
+
it "should not call Socky::NetRequest#post if socky option subscribe_url is nil" do
|
110
|
+
Socky.stub!(:options).and_return({:subscribe_url => nil})
|
111
|
+
Socky::NetRequest.should_not_receive(:post)
|
112
|
+
send_subscribe_request
|
113
|
+
end
|
114
|
+
end
|
115
|
+
context "#send_unsubscribe_request" do
|
116
|
+
it "should build params for request if socky option unsubscribe_url is not nil" do
|
117
|
+
Socky.stub!(:options).and_return({:unsubscribe_url => "any"})
|
118
|
+
should_receive(:params_for_request)
|
119
|
+
send_unsubscribe_request
|
120
|
+
end
|
121
|
+
it "should call Socky::NetRequest#post if socky option unsubscribe_url is not nil" do
|
122
|
+
Socky.stub!(:options).and_return({:unsubscribe_url => "any"})
|
123
|
+
stub!(:params_for_request)
|
124
|
+
Socky::NetRequest.should_receive(:post)
|
125
|
+
send_unsubscribe_request
|
126
|
+
end
|
127
|
+
it "should not call Socky::NetRequest#post if socky option unsubscribe_url is nil" do
|
128
|
+
Socky.stub!(:options).and_return({:unsubscribe_url => nil})
|
129
|
+
Socky::NetRequest.should_not_receive(:post)
|
130
|
+
send_unsubscribe_request
|
131
|
+
end
|
132
|
+
end
|
133
|
+
context "#params_for_request" do
|
134
|
+
before(:each) do
|
135
|
+
stub!(:client)
|
136
|
+
stub!(:secret)
|
137
|
+
stub!(:channels).and_return([])
|
138
|
+
end
|
139
|
+
it "should return empty hash if none of (client,secret,channels) are set" do
|
140
|
+
params_for_request.should eql({})
|
141
|
+
end
|
142
|
+
it "should return client as client_id if set" do
|
143
|
+
stub!(:client).and_return("some client")
|
144
|
+
params_for_request.should eql({:client_id => "some client"})
|
145
|
+
end
|
146
|
+
it "should return secret as client_secret if set" do
|
147
|
+
stub!(:secret).and_return("some secret")
|
148
|
+
params_for_request.should eql({:client_secret => "some secret"})
|
149
|
+
end
|
150
|
+
it "should return channels if not empty" do
|
151
|
+
stub!(:channels).and_return(["some channel"])
|
152
|
+
params_for_request.should eql({:channels => ["some channel"]})
|
153
|
+
end
|
154
|
+
it "should return client, secret and channels as hash if all are set" do
|
155
|
+
stub!(:client).and_return("some client")
|
156
|
+
stub!(:secret).and_return("some secret")
|
157
|
+
stub!(:channels).and_return(["some channel"])
|
158
|
+
params_for_request.should eql({:client_id => "some client", :client_secret => "some secret", :channels => ["some channel"]})
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe Socky::Connection::Finders do
|
4
|
+
include Socky::Connection::Finders
|
5
|
+
|
6
|
+
context "class" do
|
7
|
+
before(:each) do
|
8
|
+
@connection1 = mock(:connection1, :client => "client1", :channels => [])
|
9
|
+
@connection2 = mock(:connection2, :client => "client1", :channels => ["1", "3", "5"])
|
10
|
+
@connection3 = mock(:connection3, :client => "client2", :channels => ["2", "5"])
|
11
|
+
@connection4 = mock(:connection4, :client => "client3", :channels => ["3", "5"])
|
12
|
+
@connections = [@connection1,@connection2,@connection3,@connection4]
|
13
|
+
@connections.collect { |connection| Socky::Connection.connections << connection }
|
14
|
+
end
|
15
|
+
after(:each) do
|
16
|
+
Socky::Connection.connections.clear
|
17
|
+
end
|
18
|
+
|
19
|
+
it "#find_all should return all connections" do
|
20
|
+
self.class.find_all.should eql(@connections)
|
21
|
+
end
|
22
|
+
context "#find" do
|
23
|
+
it "should return all connections if no options specified" do
|
24
|
+
self.class.find.should eql(@connections)
|
25
|
+
end
|
26
|
+
context "if :clients option is specified" do
|
27
|
+
it "should return all connections if :clients is nil or empty" do
|
28
|
+
self.class.find(:clients => nil).should eql(@connections)
|
29
|
+
self.class.find(:clients => []).should eql(@connections)
|
30
|
+
end
|
31
|
+
it "should return only connections from specified client" do
|
32
|
+
self.class.find(:clients => "client1").should eql([@connection1,@connection2])
|
33
|
+
end
|
34
|
+
it "should return only connections from specified clients if array provided" do
|
35
|
+
self.class.find(:clients => ["client1","client2"]).should eql([@connection1,@connection2,@connection3])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
context "if :channels option is specified" do
|
39
|
+
it "should return all connections if :channels is nil or empty" do
|
40
|
+
self.class.find(:channels => nil).should eql(@connections)
|
41
|
+
self.class.find(:channels => []).should eql(@connections)
|
42
|
+
end
|
43
|
+
it "should return all connections that include specified channel" do
|
44
|
+
self.class.find(:channels => "3").should eql([@connection2,@connection4])
|
45
|
+
end
|
46
|
+
it "should return all connections that include at last one of specified channels" do
|
47
|
+
self.class.find(:channels => ["2","3"]).should eql([@connection2,@connection3,@connection4])
|
48
|
+
end
|
49
|
+
end
|
50
|
+
context "if both :clients and :channels options are provided" do
|
51
|
+
context "but :channels are empty" do
|
52
|
+
it "should return only connections from specified client" do
|
53
|
+
self.class.find(:channels => [],:clients => "client1").should eql([@connection1,@connection2])
|
54
|
+
end
|
55
|
+
it "should return only connections from specified clients if array provided" do
|
56
|
+
self.class.find(:channels => [],:clients => ["client1","client2"]).should eql([@connection1,@connection2,@connection3])
|
57
|
+
end
|
58
|
+
end
|
59
|
+
context "but :clients are empty" do
|
60
|
+
it "should return all connections that include specified channel" do
|
61
|
+
self.class.find(:clients => [],:channels => "3").should eql([@connection2,@connection4])
|
62
|
+
end
|
63
|
+
it "should return all connections that include at last one of specified channels" do
|
64
|
+
self.class.find(:clients => [],:channels => ["2","3"]).should eql([@connection2,@connection3,@connection4])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
it "should return only connections from specified client that include specified channel" do
|
68
|
+
self.class.find(:clients => "client1",:channels => "3").should eql([@connection2])
|
69
|
+
self.class.find(:clients => "client1",:channels => "2").should eql([])
|
70
|
+
end
|
71
|
+
it "should return only connections from specified client that include one of specified channels" do
|
72
|
+
self.class.find(:clients => "client1",:channels => ["2","3"]).should eql([@connection2])
|
73
|
+
end
|
74
|
+
it "should return only connections from specified clients that include specified channel" do
|
75
|
+
self.class.find(:clients => ["client1","client2"],:channels => "2").should eql([@connection3])
|
76
|
+
end
|
77
|
+
it "should return only connections from specified clients that include at last one of specified channels" do
|
78
|
+
self.class.find(:clients => ["client1","client2"],:channels => ["2","1"]).should eql([@connection2,@connection3])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
it "#find_by_clients should call #find with clients option" do
|
83
|
+
self.class.should_receive(:find).with({:clients => "client1"})
|
84
|
+
self.class.find_by_clients("client1")
|
85
|
+
end
|
86
|
+
it "#find_by_channels should call #find with channels option" do
|
87
|
+
self.class.should_receive(:find).with({:channels => "1"})
|
88
|
+
self.class.find_by_channels("1")
|
89
|
+
end
|
90
|
+
it "#find_by_clients_and_channels should call #find with both clients and channels option" do
|
91
|
+
self.class.should_receive(:find).with({:clients => "client1", :channels => "1"})
|
92
|
+
self.class.find_by_clients_and_channels("client1","1")
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|