socky 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.textile +9 -0
- data/Rakefile +4 -0
- data/VERSION +1 -1
- data/lib/socky.rb +12 -0
- data/lib/socky/connection.rb +49 -14
- data/lib/socky/connection/authentication.rb +27 -7
- data/lib/socky/connection/finders.rb +54 -43
- data/lib/socky/message.rb +30 -12
- data/lib/socky/misc.rb +22 -0
- data/lib/socky/net_request.rb +5 -0
- data/lib/socky/options.rb +18 -7
- data/lib/socky/options/config.rb +20 -14
- data/lib/socky/options/parser.rb +5 -0
- data/lib/socky/runner.rb +29 -18
- data/spec/em-websocket_spec.rb +3 -4
- data/spec/socky/connection/authentication_spec.rb +27 -16
- data/spec/socky/connection/finders_spec.rb +44 -44
- data/spec/socky/connection_spec.rb +5 -5
- data/spec/socky/message_spec.rb +43 -76
- data/spec/socky/net_request_spec.rb +0 -1
- data/spec/socky/runner_spec.rb +7 -3
- data/spec/{stallion.rb → support/stallion.rb} +0 -0
- metadata +21 -7
data/lib/socky/misc.rb
CHANGED
@@ -1,46 +1,68 @@
|
|
1
1
|
module Socky
|
2
|
+
# common methods for all other classes
|
2
3
|
module Misc
|
3
4
|
|
5
|
+
# extend including class by itself
|
4
6
|
def self.included(base)
|
5
7
|
base.extend Socky::Misc
|
6
8
|
end
|
7
9
|
|
10
|
+
# return server-wide options
|
11
|
+
# @see Socky.options
|
8
12
|
def options
|
9
13
|
Socky.options
|
10
14
|
end
|
11
15
|
|
16
|
+
# write server-wide options
|
12
17
|
def options=(ob)
|
13
18
|
Socky.options = ob
|
14
19
|
end
|
15
20
|
|
21
|
+
# return name of current object
|
22
|
+
# @example when included in connection
|
23
|
+
# @connection.name #=> "Connection(2149785820)"
|
16
24
|
def name
|
17
25
|
"#{self.class.to_s.split("::").last}(#{self.object_id})"
|
18
26
|
end
|
19
27
|
|
28
|
+
# return log path
|
20
29
|
def log_path
|
21
30
|
Socky.log_path
|
22
31
|
end
|
23
32
|
|
33
|
+
# return pid path
|
24
34
|
def pid_path
|
25
35
|
Socky.pid_path
|
26
36
|
end
|
27
37
|
|
38
|
+
# return config path
|
28
39
|
def config_path
|
29
40
|
Socky.config_path
|
30
41
|
end
|
31
42
|
|
43
|
+
# log message at info level
|
44
|
+
# @param [Array] args data for logging
|
32
45
|
def info(args)
|
33
46
|
Socky.logger.info args.join(" ")
|
34
47
|
end
|
35
48
|
|
49
|
+
# log message at debug level
|
50
|
+
# @param [Array] args data for logging
|
36
51
|
def debug(args)
|
37
52
|
Socky.logger.debug args.join(" ")
|
38
53
|
end
|
39
54
|
|
55
|
+
# log message at error level
|
56
|
+
# @param [String] name object name with raised error
|
57
|
+
# @param [Error] error error instance that was raised
|
40
58
|
def error(name, error)
|
41
59
|
debug [name, "raised:", error.class, error.message]
|
42
60
|
end
|
43
61
|
|
62
|
+
# convert keys of hash to symbol
|
63
|
+
# @param [Hash] hash hash to symbolize
|
64
|
+
# @return [Hash] with symbolized keys
|
65
|
+
# @return [Object] if hash isn't instance of Hash
|
44
66
|
def symbolize_keys(hash)
|
45
67
|
return hash unless hash.is_a?(Hash)
|
46
68
|
hash.inject({}) do |options, (key, value)|
|
data/lib/socky/net_request.rb
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
require 'em-http'
|
2
2
|
|
3
3
|
module Socky
|
4
|
+
# this class provide unobtrusive http request methods
|
4
5
|
class NetRequest
|
5
6
|
include Socky::Misc
|
6
7
|
|
7
8
|
class << self
|
8
9
|
|
10
|
+
# send unobtrusive http POST request to gived address and return status of request as block response
|
11
|
+
# @param [String] url address to send request in format 'http://address[:port]/[path]'
|
12
|
+
# @param [Hash] params params for request(will be attached in post message)
|
13
|
+
# @yield [Boolean] called after request is finished - if response status is 200 then it's true, else false
|
9
14
|
def post(url, params = {}, &block)
|
10
15
|
http = EventMachine::HttpRequest.new(url).post :body => params, :timeout => options[:timeout] || 3
|
11
16
|
http.errback { yield false }
|
data/lib/socky/options.rb
CHANGED
@@ -2,12 +2,29 @@ require 'socky/options/config'
|
|
2
2
|
require 'socky/options/parser'
|
3
3
|
|
4
4
|
module Socky
|
5
|
+
# options parser - reads options from STDIN and config file and set Socky.options
|
5
6
|
class Options
|
6
7
|
include Socky::Misc
|
7
8
|
|
8
9
|
class << self
|
10
|
+
# prepare server-wide options from config and parser
|
11
|
+
# @param [Array] argv arguments that will be provided to parser
|
12
|
+
# @see default_options default options
|
13
|
+
# @see Config.read merged with default options
|
14
|
+
# @see Parser.parse merges with default options after config
|
9
15
|
def prepare(argv)
|
10
|
-
self.options =
|
16
|
+
self.options = default_options
|
17
|
+
|
18
|
+
parsed_options = Parser.parse(argv)
|
19
|
+
config_options = Config.read(parsed_options[:config_path] || config_path, :kill => parsed_options[:kill])
|
20
|
+
|
21
|
+
self.options.merge!(config_options)
|
22
|
+
self.options.merge!(parsed_options)
|
23
|
+
end
|
24
|
+
|
25
|
+
# default options for server
|
26
|
+
def default_options
|
27
|
+
{
|
11
28
|
:config_path => config_path,
|
12
29
|
:port => 8080,
|
13
30
|
:debug => false,
|
@@ -15,12 +32,6 @@ module Socky
|
|
15
32
|
:secure => false,
|
16
33
|
:log_path => log_path
|
17
34
|
}
|
18
|
-
|
19
|
-
parsed_options = Parser.parse(argv)
|
20
|
-
config_options = Config.read(parsed_options[:config_path] || config_path, :kill => parsed_options[:kill])
|
21
|
-
|
22
|
-
self.options.merge!(config_options)
|
23
|
-
self.options.merge!(parsed_options)
|
24
35
|
end
|
25
36
|
end
|
26
37
|
|
data/lib/socky/options/config.rb
CHANGED
@@ -3,24 +3,23 @@ require 'erb'
|
|
3
3
|
|
4
4
|
module Socky
|
5
5
|
class Options
|
6
|
+
# config parser class - used by Socky::Options
|
6
7
|
class Config
|
7
8
|
|
8
|
-
class NoConfigFile < Socky::SockyError #:nodoc:
|
9
|
-
end
|
10
|
-
|
11
|
-
class
|
12
|
-
end
|
13
|
-
|
14
|
-
class AlreadyExists < Socky::SockyError #:nodoc:
|
15
|
-
end
|
16
|
-
|
17
|
-
class ConfigUnavailable < Socky::SockyError #:nodoc:
|
18
|
-
end
|
19
|
-
|
20
|
-
class SuccessfullyCreated < Socky::SockyError #:nodoc:
|
21
|
-
end
|
9
|
+
class NoConfigFile < Socky::SockyError; end #:nodoc:
|
10
|
+
class InvalidConfig < Socky::SockyError; end #:nodoc:
|
11
|
+
class AlreadyExists < Socky::SockyError; end #:nodoc:
|
12
|
+
class ConfigUnavailable < Socky::SockyError; end #:nodoc:
|
13
|
+
class SuccessfullyCreated < Socky::SockyError; end #:nodoc:
|
22
14
|
|
23
15
|
class << self
|
16
|
+
# read config file or exits if file don't exists or is invalid
|
17
|
+
# @param [String] path path to valid yaml file
|
18
|
+
# @param [Hash] args args to rescue eventual problems
|
19
|
+
# @option args [Any] kill (nil) if not nil then empty hash will be returned if config file isn't found
|
20
|
+
# @return [Hash] parsed config options
|
21
|
+
# @raise [NoConfigFile] if file doesn't exists
|
22
|
+
# @raise [InvalidConfig] if file isn't valid yaml
|
24
23
|
def read(path, args = {})
|
25
24
|
raise(NoConfigFile, "You must generate a config file (socky -g filename.yml)") unless File.exists?(path)
|
26
25
|
result = YAML::load(ERB.new(IO.read(path)).result)
|
@@ -35,6 +34,12 @@ module Socky
|
|
35
34
|
end
|
36
35
|
end
|
37
36
|
|
37
|
+
# generate default config file
|
38
|
+
# @see DEFAULT_CONFIG_FILE
|
39
|
+
# @param [String] path path to file that will be created
|
40
|
+
# @raise [AlreadyExists] if file exists(you must delete it manually)
|
41
|
+
# @raise [ConfigUnavailable] if file cannot be created(wrong privilages?)
|
42
|
+
# @raise [SuccessfullyCreated] if file is successfully created
|
38
43
|
def generate(path)
|
39
44
|
raise(AlreadyExists, "Config file already exists. You must remove it before generating a new one.") if File.exists?(path)
|
40
45
|
File.open(path, 'w+') do |file|
|
@@ -46,6 +51,7 @@ module Socky
|
|
46
51
|
exit
|
47
52
|
end
|
48
53
|
|
54
|
+
# default config file content
|
49
55
|
DEFAULT_CONFIG_FILE= <<-EOF
|
50
56
|
:port: 8080
|
51
57
|
:debug: false
|
data/lib/socky/options/parser.rb
CHANGED
@@ -2,9 +2,14 @@ require 'optparse'
|
|
2
2
|
|
3
3
|
module Socky
|
4
4
|
class Options
|
5
|
+
# STDIN options parser - used by Socky::Options
|
5
6
|
class Parser
|
6
7
|
|
7
8
|
class << self
|
9
|
+
# parse options(usually from STDIN)
|
10
|
+
# see source code for available options
|
11
|
+
# @param [Array] argv options for parser
|
12
|
+
# @return [Hash] parsed options from array
|
8
13
|
def parse(argv)
|
9
14
|
result = {}
|
10
15
|
opts = OptionParser.new do |opts|
|
data/lib/socky/runner.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
module Socky
|
2
|
+
# default runner class - creates server and runs it
|
2
3
|
class Runner
|
3
4
|
include Socky::Misc
|
4
5
|
|
5
6
|
class << self
|
7
|
+
# create new eventmachine server
|
6
8
|
def run(argv = ARGV)
|
7
9
|
server = self.new(argv)
|
8
10
|
|
@@ -16,10 +18,13 @@ module Socky
|
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
21
|
+
# set server-wide options from args
|
19
22
|
def initialize(argv = ARGV)
|
20
23
|
Options.prepare(argv)
|
21
24
|
end
|
22
25
|
|
26
|
+
# start eventmachine server
|
27
|
+
# require options to be parsed earlier
|
23
28
|
def start
|
24
29
|
EventMachine.epoll
|
25
30
|
|
@@ -42,33 +47,28 @@ module Socky
|
|
42
47
|
end
|
43
48
|
end
|
44
49
|
|
50
|
+
# stop eventmachine server
|
45
51
|
def stop
|
46
52
|
info ["Server stopping"]
|
47
53
|
EventMachine.stop
|
48
54
|
end
|
49
55
|
|
50
|
-
|
51
|
-
FileUtils.mkdir_p(File.dirname(pid_path))
|
52
|
-
File.open(pid_path, 'w'){|f| f.write("#{pid}\n")}
|
53
|
-
rescue => e
|
54
|
-
puts e
|
55
|
-
exit
|
56
|
-
end
|
57
|
-
|
56
|
+
# run server in daemon mode
|
58
57
|
def daemonize
|
59
58
|
fork do
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
59
|
+
Process.setsid
|
60
|
+
exit if fork
|
61
|
+
store_pid(Process.pid)
|
62
|
+
# Dir.chdir "/" # Mucks up logs
|
63
|
+
File.umask 0000
|
64
|
+
STDIN.reopen "/dev/null"
|
65
|
+
STDOUT.reopen "/dev/null", "a"
|
66
|
+
STDERR.reopen STDOUT
|
67
|
+
start
|
68
|
+
end
|
70
69
|
end
|
71
70
|
|
71
|
+
# kill daemonized server according to pid file in pid_path
|
72
72
|
def kill_pid
|
73
73
|
begin
|
74
74
|
pid = IO.read(pid_path).chomp.to_i
|
@@ -80,5 +80,16 @@ module Socky
|
|
80
80
|
end
|
81
81
|
exit
|
82
82
|
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def store_pid(pid)
|
87
|
+
FileUtils.mkdir_p(File.dirname(pid_path))
|
88
|
+
File.open(pid_path, 'w'){|f| f.write("#{pid}\n")}
|
89
|
+
rescue => e
|
90
|
+
puts e
|
91
|
+
exit
|
92
|
+
end
|
93
|
+
|
83
94
|
end
|
84
95
|
end
|
data/spec/em-websocket_spec.rb
CHANGED
@@ -3,9 +3,8 @@ require 'spec_helper'
|
|
3
3
|
describe EM::WebSocket::Connection do
|
4
4
|
|
5
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
6
|
EM.run do
|
7
|
+
Socky.logger.should_not_receive(:debug)
|
9
8
|
EM.add_timer(0.1) do
|
10
9
|
http = EventMachine::HttpRequest.new('ws://127.0.0.1:9999/').get(:timeout => 0)
|
11
10
|
http.errback { http.close_connection }
|
@@ -19,9 +18,9 @@ describe EM::WebSocket::Connection do
|
|
19
18
|
end
|
20
19
|
|
21
20
|
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
21
|
EM.run do
|
22
|
+
Socky.logger.should_receive(:debug).with("Socket initialize")
|
23
|
+
Socky.logger.should_receive(:debug).with(anything()).at_least(:once)
|
25
24
|
EM.add_timer(0.1) do
|
26
25
|
http = EventMachine::HttpRequest.new('ws://127.0.0.1:9999/').get(:timeout => 0)
|
27
26
|
http.errback { http.close_connection }
|
@@ -20,22 +20,33 @@ describe Socky::Connection::Authentication do
|
|
20
20
|
subscribe_request
|
21
21
|
end
|
22
22
|
it "should add self to connection list if #send_subscribe_request block is true" do
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
EM.run do
|
24
|
+
stub!(:authenticated?).and_return(false)
|
25
|
+
stub!(:send_subscribe_request).and_yield(true)
|
26
|
+
should_receive(:add_to_pool)
|
27
|
+
subscribe_request
|
28
|
+
EM.stop
|
29
|
+
end
|
27
30
|
end
|
28
31
|
it "should be authenticated by url if #send_subscribe_request block is true" do
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
32
|
+
EM.run do
|
33
|
+
stub!(:authenticated?).and_return(false)
|
34
|
+
stub!(:send_subscribe_request).and_yield(true)
|
35
|
+
stub!(:add_to_pool)
|
36
|
+
subscribe_request
|
37
|
+
authenticated_by_url?.should be_true
|
38
|
+
EM.stop
|
39
|
+
end
|
34
40
|
end
|
35
41
|
it "should disconnect if #send_subscribe_request block is false" do
|
36
|
-
|
37
|
-
|
38
|
-
|
42
|
+
EM.run do
|
43
|
+
stub!(:send_subscribe_request).and_yield(false)
|
44
|
+
should_receive(:disconnect)
|
45
|
+
subscribe_request
|
46
|
+
EM.add_timer(0.1) do
|
47
|
+
EM.stop
|
48
|
+
end
|
49
|
+
end
|
39
50
|
end
|
40
51
|
end
|
41
52
|
context "#unsubscribe_request" do
|
@@ -119,25 +130,25 @@ describe Socky::Connection::Authentication do
|
|
119
130
|
it "should not call Socky::NetRequest#post if socky option subscribe_url is nil" do
|
120
131
|
Socky.stub!(:options).and_return({:subscribe_url => nil})
|
121
132
|
Socky::NetRequest.should_not_receive(:post)
|
122
|
-
send_subscribe_request
|
133
|
+
send_subscribe_request{}
|
123
134
|
end
|
124
135
|
end
|
125
136
|
context "#send_unsubscribe_request" do
|
126
137
|
it "should build params for request if socky option unsubscribe_url is not nil" do
|
127
138
|
Socky.stub!(:options).and_return({:unsubscribe_url => "any"})
|
128
139
|
should_receive(:params_for_request)
|
129
|
-
send_unsubscribe_request
|
140
|
+
send_unsubscribe_request{}
|
130
141
|
end
|
131
142
|
it "should call Socky::NetRequest#post if socky option unsubscribe_url is not nil" do
|
132
143
|
Socky.stub!(:options).and_return({:unsubscribe_url => "any"})
|
133
144
|
stub!(:params_for_request)
|
134
145
|
Socky::NetRequest.should_receive(:post)
|
135
|
-
send_unsubscribe_request
|
146
|
+
send_unsubscribe_request{}
|
136
147
|
end
|
137
148
|
it "should not call Socky::NetRequest#post if socky option unsubscribe_url is nil" do
|
138
149
|
Socky.stub!(:options).and_return({:unsubscribe_url => nil})
|
139
150
|
Socky::NetRequest.should_not_receive(:post)
|
140
|
-
send_unsubscribe_request
|
151
|
+
send_unsubscribe_request{}
|
141
152
|
end
|
142
153
|
end
|
143
154
|
context "#params_for_request" do
|
@@ -18,86 +18,86 @@ describe Socky::Connection::Finders do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
it "#find_all should return all connections" do
|
21
|
-
|
21
|
+
find_all.should eql(@connections)
|
22
22
|
end
|
23
23
|
context "#find" do
|
24
24
|
it "should return all connections if no options specified" do
|
25
|
-
|
25
|
+
find.should eql(@connections)
|
26
26
|
end
|
27
27
|
context "on :to" do
|
28
28
|
context "if :clients option is specified" do
|
29
29
|
it "should return all connections if :clients is nil" do
|
30
|
-
|
30
|
+
find(:to => {:clients => nil}).should eql(@connections)
|
31
31
|
end
|
32
32
|
it "should return none connections if :clients is empty" do
|
33
|
-
|
33
|
+
find(:to => {:clients => []}).should eql([])
|
34
34
|
end
|
35
35
|
it "should return only connections from specified client" do
|
36
|
-
|
36
|
+
find(:to => {:clients => "client1"}).should eql([@connection1,@connection2])
|
37
37
|
end
|
38
38
|
it "should return only connections from specified clients if array provided" do
|
39
|
-
|
39
|
+
find(:to => {:clients => ["client1","client2"]}).should eql([@connection1,@connection2,@connection3])
|
40
40
|
end
|
41
41
|
end
|
42
42
|
context "if :channels option is specified" do
|
43
43
|
it "should return all connections if :channels is nil" do
|
44
|
-
|
44
|
+
find(:to => {:channels => nil}).should eql(@connections)
|
45
45
|
end
|
46
46
|
it "should return none connections if :channels is empty" do
|
47
|
-
|
47
|
+
find(:to => {:channels => []}).should eql([])
|
48
48
|
end
|
49
49
|
it "should return all connections that include specified channel" do
|
50
|
-
|
50
|
+
find(:to => {:channels => "3"}).should eql([@connection2,@connection4])
|
51
51
|
end
|
52
52
|
it "should return all connections that include at last one of specified channels" do
|
53
|
-
|
53
|
+
find(:to => {:channels => ["2","3"]}).should eql([@connection2,@connection3,@connection4])
|
54
54
|
end
|
55
55
|
end
|
56
56
|
context "if both :clients and :channels options are provided" do
|
57
57
|
context "but :channels are nil" do
|
58
58
|
it "should return only connections from specified client" do
|
59
|
-
|
59
|
+
find(:to => {:channels => nil,:clients => "client1"}).should eql([@connection1,@connection2])
|
60
60
|
end
|
61
61
|
it "should return only connections from specified clients if array provided" do
|
62
|
-
|
62
|
+
find(:to => {:channels => nil,:clients => ["client1","client2"]}).should eql([@connection1,@connection2,@connection3])
|
63
63
|
end
|
64
64
|
end
|
65
65
|
context "but :channels are empty" do
|
66
66
|
it "should return none connections" do
|
67
|
-
|
67
|
+
find(:to => {:channels => [],:clients => "client1"}).should eql([])
|
68
68
|
end
|
69
69
|
it "should return none connections if array provided" do
|
70
|
-
|
70
|
+
find(:to => {:channels => [],:clients => ["client1","client2"]}).should eql([])
|
71
71
|
end
|
72
72
|
end
|
73
73
|
context "but :clients are nil" do
|
74
74
|
it "should return all connections that include specified channel" do
|
75
|
-
|
75
|
+
find(:to => {:clients => nil,:channels => "3"}).should eql([@connection2,@connection4])
|
76
76
|
end
|
77
77
|
it "should return all connections that include at last one of specified channels" do
|
78
|
-
|
78
|
+
find(:to => {:clients => nil,:channels => ["2","3"]}).should eql([@connection2,@connection3,@connection4])
|
79
79
|
end
|
80
80
|
end
|
81
81
|
context "but :clients are empty" do
|
82
82
|
it "should return none connections" do
|
83
|
-
|
83
|
+
find(:to => {:clients => [],:channels => "3"}).should eql([])
|
84
84
|
end
|
85
85
|
it "should return none connections if array provided" do
|
86
|
-
|
86
|
+
find(:to => {:clients => [],:channels => ["2","3"]}).should eql([])
|
87
87
|
end
|
88
88
|
end
|
89
89
|
it "should return only connections from specified client that include specified channel" do
|
90
|
-
|
91
|
-
|
90
|
+
find(:to => {:clients => "client1",:channels => "3"}).should eql([@connection2])
|
91
|
+
find(:to => {:clients => "client1",:channels => "2"}).should eql([])
|
92
92
|
end
|
93
93
|
it "should return only connections from specified client that include one of specified channels" do
|
94
|
-
|
94
|
+
find(:to => {:clients => "client1",:channels => ["2","3"]}).should eql([@connection2])
|
95
95
|
end
|
96
96
|
it "should return only connections from specified clients that include specified channel" do
|
97
|
-
|
97
|
+
find(:to => {:clients => ["client1","client2"],:channels => "2"}).should eql([@connection3])
|
98
98
|
end
|
99
99
|
it "should return only connections from specified clients that include at last one of specified channels" do
|
100
|
-
|
100
|
+
find(:to => {:clients => ["client1","client2"],:channels => ["2","1"]}).should eql([@connection2,@connection3])
|
101
101
|
end
|
102
102
|
end
|
103
103
|
end
|
@@ -105,63 +105,63 @@ describe Socky::Connection::Finders do
|
|
105
105
|
context "on :except" do
|
106
106
|
context "if :clients option is specified" do
|
107
107
|
it "should return all connections if :clients is nil" do
|
108
|
-
|
108
|
+
find(:except => {:clients => nil}).should eql(@connections)
|
109
109
|
end
|
110
110
|
it "should return all connections if :clients is empty" do
|
111
|
-
|
111
|
+
find(:except => {:clients => []}).should eql(@connections)
|
112
112
|
end
|
113
113
|
it "should return all connections except of specified client" do
|
114
|
-
|
114
|
+
find(:except => {:clients => "client1"}).should eql([@connection3,@connection4])
|
115
115
|
end
|
116
116
|
it "should return all connections except of specified clients if array provided" do
|
117
|
-
|
117
|
+
find(:except => {:clients => ["client1","client2"]}).should eql([@connection4])
|
118
118
|
end
|
119
119
|
end
|
120
120
|
context "if :channels option is specified" do
|
121
121
|
it "should return all connections if :channels is nil" do
|
122
|
-
|
122
|
+
find(:except => {:channels => nil}).should eql(@connections)
|
123
123
|
end
|
124
124
|
it "should return all connections if :channels is empty" do
|
125
|
-
|
125
|
+
find(:except => {:channels => []}).should eql(@connections)
|
126
126
|
end
|
127
127
|
it "should return all connections except of that include all specified channels" do
|
128
|
-
|
128
|
+
find(:except => {:channels => ["2","5"]}).should eql([@connection1,@connection2,@connection4])
|
129
129
|
end
|
130
130
|
end
|
131
131
|
context "if both :clients and :channels options are provided" do
|
132
132
|
context "but :channels are nil" do
|
133
133
|
it "should return all connections except of specified client" do
|
134
|
-
|
134
|
+
find(:except => {:channels => nil,:clients => "client1"}).should eql([@connection3,@connection4])
|
135
135
|
end
|
136
136
|
it "should return all connections except of specified clients if array provided" do
|
137
|
-
|
137
|
+
find(:except => {:channels => nil,:clients => ["client1","client2"]}).should eql([@connection4])
|
138
138
|
end
|
139
139
|
end
|
140
140
|
context "but :channels are empty" do
|
141
141
|
it "should return all connections except of specified client" do
|
142
|
-
|
142
|
+
find(:except => {:channels => [],:clients => "client1"}).should eql([@connection3,@connection4])
|
143
143
|
end
|
144
144
|
it "should return all connections except of provided clients if array provided" do
|
145
|
-
|
145
|
+
find(:except => {:channels => [],:clients => ["client1","client2"]}).should eql([@connection4])
|
146
146
|
end
|
147
147
|
end
|
148
148
|
context "but :clients are nil" do
|
149
149
|
it "should return all connections except of that include all of specified channels" do
|
150
|
-
|
150
|
+
find(:except => {:clients => nil,:channels => ["2","5"]}).should eql([@connection1,@connection2,@connection4])
|
151
151
|
end
|
152
152
|
end
|
153
153
|
context "but :clients are empty" do
|
154
154
|
it "should return all connections except of that include all of specified channels " do
|
155
|
-
|
155
|
+
find(:except => {:clients => [],:channels => ["2","5"]}).should eql([@connection1,@connection2,@connection4])
|
156
156
|
end
|
157
157
|
end
|
158
158
|
it "should return all connections except of specified client or all specified channels" do
|
159
|
-
|
160
|
-
|
159
|
+
find(:except => {:clients => "client2",:channels => "3"}).should eql([@connection1,@connection2,@connection4])
|
160
|
+
find(:except => {:clients => "client2",:channels => ["3","5"]}).should eql([@connection1,@connection2])
|
161
161
|
end
|
162
162
|
it "should return only connections from specified clients that include specified channel" do
|
163
|
-
|
164
|
-
|
163
|
+
find(:except => {:clients => ["client1","client2"],:channels => "3"}).should eql([@connection4])
|
164
|
+
find(:except => {:clients => ["client1","client2"],:channels => ["3","5"]}).should eql([])
|
165
165
|
end
|
166
166
|
end
|
167
167
|
end
|
@@ -169,16 +169,16 @@ describe Socky::Connection::Finders do
|
|
169
169
|
context "on :to and :except" do
|
170
170
|
context "should value 'except' more that 'to'" do
|
171
171
|
it "on :client" do
|
172
|
-
|
172
|
+
find(:to => {:clients => "client1"},:except => {:clients => "client1"}).should eql([])
|
173
173
|
end
|
174
174
|
it "on :channels" do
|
175
|
-
|
175
|
+
find(:to => {:channels => "5"},:except => {:channels => "5"}).should eql([])
|
176
176
|
end
|
177
177
|
it "on :client allow and :channels except" do
|
178
|
-
|
178
|
+
find(:to => {:clients => "client2"},:except => {:channels => ["2","5"]}).should eql([])
|
179
179
|
end
|
180
180
|
it "on :channels allow and :clients except" do
|
181
|
-
|
181
|
+
find(:to => {:channels => ["5"]},:except => {:clients => "client2"}).should eql([@connection2,@connection4])
|
182
182
|
end
|
183
183
|
end
|
184
184
|
end
|