smartfox_jruby 0.1 → 0.2.3
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 +78 -0
- data/lib/smartfox_jruby.rb +6 -5
- data/lib/smartfox_jruby/common.rb +25 -22
- data/lib/smartfox_jruby/sfs_adapter.rb +137 -135
- data/lib/smartfox_jruby/sfs_runner.rb +91 -88
- data/lib/smartfox_jruby/sfs_worker.rb +199 -197
- metadata +52 -110
- data/Gemfile +0 -9
- data/Jarfile +0 -6
- data/smartfox_jruby.gemspec +0 -25
data/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# SmartFox Server client library for JRuby (extension requests testing).
|
2
|
+
|
3
|
+
This is a small library helping you to interact with a SmartFox server.
|
4
|
+
It's main purpose is to test the backend extension using the requests.
|
5
|
+
It requires JRuby and some jar-dependencies in a classpath.
|
6
|
+
|
7
|
+
## What it gives
|
8
|
+
|
9
|
+
You can easily connect and interact with a SmartFox server to test your server extension requests
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
adapter = SmartfoxJruby::SfsAdapter.new
|
13
|
+
adapter.login_as("user", "password")
|
14
|
+
adapter.connect!(
|
15
|
+
:host => "localhost",
|
16
|
+
:port => 9933,
|
17
|
+
:zone => "test-zone"
|
18
|
+
)
|
19
|
+
|
20
|
+
adapter.process! {
|
21
|
+
# create extension request
|
22
|
+
request(:GetProducts, :productType => :ITEM).expect(:GetProductsOK) { |data|
|
23
|
+
puts "Whoa! I've got the following products: #{data.to_json}"
|
24
|
+
|
25
|
+
request(:BuyProduct, {:productId => data[:data].first[:id]},
|
26
|
+
:serialize_opts => {:productId_type => :long}).
|
27
|
+
expect(:BuyProductOK) { |data|
|
28
|
+
puts "Whoa! I've bought product! #{data.to_json}"
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
adapter.disconnect!
|
33
|
+
|
34
|
+
```
|
35
|
+
|
36
|
+
## How to install
|
37
|
+
|
38
|
+
This library uses [Doubleshot]() to process the dependencies. So you can add it as a reference by creating the
|
39
|
+
Doubleshot
|
40
|
+
file on project root level:
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
# encoding: utf-8
|
44
|
+
Doubleshot.new do |config|
|
45
|
+
|
46
|
+
config.project = "myproject"
|
47
|
+
config.version = "0.1"
|
48
|
+
|
49
|
+
config.gem 'smartfox_jruby'
|
50
|
+
|
51
|
+
config.gemspec do |spec|
|
52
|
+
spec.summary = "Test Smartfox library"
|
53
|
+
spec.description = "TODO"
|
54
|
+
|
55
|
+
spec.homepage = "http://mysite.info"
|
56
|
+
spec.author = "me"
|
57
|
+
spec.email = "me@mail.com"
|
58
|
+
spec.license = "Apache 2.0"
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
```
|
65
|
+
|
66
|
+
Copyright (c) 2013 smecsia
|
67
|
+
|
68
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
69
|
+
you may not use this file except in compliance with the License.
|
70
|
+
You may obtain a copy of the License at
|
71
|
+
|
72
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
73
|
+
|
74
|
+
Unless required by applicable law or agreed to in writing, software
|
75
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
76
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
77
|
+
See the License for the specific language governing permissions and
|
78
|
+
limitations under the License.
|
data/lib/smartfox_jruby.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'ostruct'
|
3
3
|
require 'pathname'
|
4
|
-
Dir[Pathname.new(File.dirname(File.expand_path(__FILE__))).join("#{File.basename(__FILE__)}").join("*.rb")].each { |f| require f }
|
5
4
|
|
6
5
|
####################################################
|
7
6
|
# Main module
|
8
7
|
module SmartfoxJruby
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
MYDIR = Pathname.new(File.dirname(File.expand_path(__FILE__)))
|
9
|
+
autoload :SfsRunner, MYDIR.join('smartfox_jruby/sfs_runner')
|
10
|
+
autoload :SfsAdapter, MYDIR.join('smartfox_jruby/sfs_adapter')
|
11
|
+
autoload :SfsWorker, MYDIR.join('smartfox_jruby/sfs_worker')
|
12
|
+
autoload :SFSUtil, MYDIR.join('smartfox_jruby/common')
|
13
|
+
VERSION = "0.2.3"
|
13
14
|
end
|
14
15
|
|
@@ -20,35 +20,38 @@ module ISFSObject
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
module SmartfoxJruby
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
23
|
+
module SmartfoxJruby
|
24
|
+
module SFSUtil
|
25
|
+
class << self
|
26
|
+
def boxing(v, type)
|
27
|
+
case type
|
28
|
+
when :long
|
29
|
+
java.lang.Long.valueOf(v)
|
30
|
+
when :float
|
31
|
+
java.lang.Float.valueOf(v)
|
32
|
+
when :double
|
33
|
+
java.lang.Double.valueOf(v)
|
34
|
+
when :int
|
35
|
+
java.lang.Integer.valueOf(v)
|
36
|
+
when :boolean
|
37
|
+
java.lang.Boolean.valueOf(v)
|
38
|
+
else
|
39
|
+
v
|
40
|
+
end
|
39
41
|
end
|
40
|
-
end
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
43
|
+
def to_java_list(value, type)
|
44
|
+
list = java.util.ArrayList.new
|
45
|
+
value.to_java(type).each do |v|
|
46
|
+
list.add(boxing(v, type))
|
47
|
+
end
|
48
|
+
list
|
46
49
|
end
|
47
|
-
list
|
48
50
|
end
|
49
51
|
end
|
50
52
|
end
|
51
53
|
|
54
|
+
|
52
55
|
def SFSObject.from_hash(hash, opts = {})
|
53
56
|
res = SFSObject.new
|
54
57
|
opts ||= {}
|
@@ -1,172 +1,174 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/sfs_worker')
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
3
|
+
module SmartfoxJruby
|
4
|
+
|
5
|
+
class SfsAdapter
|
6
|
+
include IEventListener
|
7
|
+
attr_reader :opts
|
8
|
+
attr_reader :smart_fox
|
9
|
+
attr_reader :worker
|
10
|
+
attr_reader :username
|
11
|
+
DEBUG = false
|
12
|
+
|
13
|
+
def initialize(opts = {})
|
14
|
+
@opts = opts
|
15
|
+
@smart_fox = SmartFox.new(false)
|
16
|
+
@connected = false
|
17
|
+
@worker = opts[:worker]
|
18
|
+
@login_as = opts[:login_as] || {}
|
19
|
+
@opts[:timeout] ||= 20
|
20
|
+
@opts[:logger] ||= Logger.new(STDOUT)
|
21
|
+
SFSEvent.constants.each do |evt|
|
22
|
+
evt_value = SFSEvent.const_get(evt)
|
23
|
+
debug "Registering event adapter to self for event '#{evt}' --> '#{evt_value}'..."
|
24
|
+
smart_fox.add_event_listener(evt_value, self)
|
25
|
+
end
|
26
|
+
debug "initializing sfs adapter..."
|
24
27
|
end
|
25
|
-
end
|
26
28
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
def connect!(opt = {})
|
30
|
+
opts.reverse_merge!(opt)
|
31
|
+
raise "host and port are required to connect SfsAdapter!" if opts[:host].blank? || opts[:port].blank?
|
32
|
+
debug "connecting to smartfox at #{opts[:host]}:#{opts[:port]} ..."
|
33
|
+
smart_fox.connect(opts[:host], opts[:port])
|
34
|
+
end
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
def dispatch(event)
|
37
|
+
debug "got event #{event.type}: #{event}"
|
38
|
+
callback = "on_#{event.type.try(:underscore)}_event"
|
39
|
+
if respond_to?(callback, true)
|
40
|
+
send(callback, event)
|
41
|
+
else
|
42
|
+
debug "Unknown event caught #{event.type} (No method '#{callback}' in #{self})"
|
43
|
+
end
|
41
44
|
end
|
42
|
-
end
|
43
45
|
|
44
|
-
|
45
|
-
|
46
|
-
|
46
|
+
def disconnect!
|
47
|
+
smart_fox.disconnect
|
48
|
+
end
|
47
49
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
50
|
+
def process!(wrk = nil, &block)
|
51
|
+
wait_with_timeout(@opts[:timeout]) { connected? }
|
52
|
+
@worker = wrk || opts[:worker]
|
53
|
+
if block_given? && connected?
|
54
|
+
instance_eval(&block)
|
55
|
+
else
|
56
|
+
raise "Worker is null!" if @worker.blank?
|
57
|
+
raise "Not connected!" unless connected?
|
58
|
+
end
|
59
|
+
worker.perform!
|
56
60
|
end
|
57
|
-
worker.perform!
|
58
|
-
end
|
59
61
|
|
60
|
-
|
61
|
-
|
62
|
-
|
62
|
+
def connected?
|
63
|
+
@connected
|
64
|
+
end
|
63
65
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
66
|
+
def on_connect(&block)
|
67
|
+
@on_connect ||= []
|
68
|
+
@on_connect << block if block_given?
|
69
|
+
end
|
68
70
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
71
|
+
def on_login(&block)
|
72
|
+
@on_login ||= []
|
73
|
+
@on_login << block if block_given?
|
74
|
+
end
|
73
75
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
76
|
+
def login_as(username, password, params = {})
|
77
|
+
params = params.to_sfsobject if params.is_a?(Hash)
|
78
|
+
@login_as = {:username => username, :password => password, :params => params}
|
79
|
+
end
|
78
80
|
|
79
|
-
|
81
|
+
private
|
80
82
|
|
81
|
-
|
82
|
-
|
83
|
+
###############
|
84
|
+
### HELPERS ###
|
83
85
|
|
84
|
-
|
85
|
-
|
86
|
-
|
86
|
+
def request(*args)
|
87
|
+
worker.request(*args)
|
88
|
+
end
|
87
89
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
90
|
+
def worker(opts = {})
|
91
|
+
@worker ||= SfsWorker::Worker.new(@smart_fox, opts)
|
92
|
+
@worker
|
93
|
+
end
|
92
94
|
|
93
|
-
|
94
|
-
|
95
|
-
|
95
|
+
def sfs_send(req)
|
96
|
+
smart_fox.send(req)
|
97
|
+
end
|
96
98
|
|
97
|
-
|
98
|
-
|
99
|
+
#########################
|
100
|
+
### EVENTS PROCESSORS ###
|
99
101
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
102
|
+
def on_extension_response_event(event)
|
103
|
+
debug "extension_response #{event.arguments.get("cmd")}"
|
104
|
+
@worker.response(event.arguments.get("cmd"), event.arguments.get("params").try(:to_hash) || {}) unless @worker.blank?
|
105
|
+
end
|
104
106
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
107
|
+
def on_connection_event(event)
|
108
|
+
debug "on_connection #{event}"
|
109
|
+
@on_connect.each { |block|
|
110
|
+
block.call(event) if block.is_a?(Proc)
|
111
|
+
} unless @on_connect.blank?
|
112
|
+
sfs_send(LoginRequest.new(@login_as[:username], @login_as[:password], opts[:zone],
|
113
|
+
(@login_as[:params] || {}.to_sfsobject)));
|
114
|
+
end
|
113
115
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
116
|
+
def on_login_event(event)
|
117
|
+
args = event.arguments.get("data").to_hash
|
118
|
+
user = event.arguments.get("user")
|
119
|
+
debug("on_login, args=#{args.to_json}")
|
120
|
+
unless user.blank?
|
121
|
+
info "connected as #{user.name}"
|
122
|
+
@username = user.name
|
123
|
+
@connected = true
|
124
|
+
@on_login.each { |block|
|
125
|
+
block.call(@username) if block.is_a?(Proc)
|
126
|
+
} unless @on_login.blank?
|
127
|
+
else
|
128
|
+
raise "login error '#{args[Aimy::Param.ERROR_MESSAGE]}'"
|
129
|
+
end
|
127
130
|
end
|
128
|
-
end
|
129
131
|
|
130
|
-
|
131
|
-
|
132
|
-
|
132
|
+
def on_login_error_event(event)
|
133
|
+
error("error while logging-in: #{event.arguments}")
|
134
|
+
end
|
133
135
|
|
134
|
-
|
135
|
-
|
136
|
-
|
136
|
+
def on_connection_lost_event(event)
|
137
|
+
# nothing to do
|
138
|
+
end
|
137
139
|
|
138
|
-
|
139
|
-
|
140
|
-
|
140
|
+
def on_handshake_event(event)
|
141
|
+
# nothing to do
|
142
|
+
end
|
141
143
|
|
142
144
|
|
143
|
-
|
144
|
-
|
145
|
+
#######################
|
146
|
+
### SERVICE HELPERS ###
|
145
147
|
|
146
|
-
|
147
|
-
|
148
|
-
|
148
|
+
def logger
|
149
|
+
opts[:logger]
|
150
|
+
end
|
149
151
|
|
150
|
-
|
151
|
-
|
152
|
-
|
152
|
+
def debug_enabled?
|
153
|
+
opts[:debug] || DEBUG
|
154
|
+
end
|
153
155
|
|
154
|
-
|
155
|
-
|
156
|
-
|
156
|
+
def debug(msg)
|
157
|
+
logger.debug "#{msg}" if debug_enabled?
|
158
|
+
end
|
157
159
|
|
158
|
-
|
159
|
-
|
160
|
-
|
160
|
+
def info(msg)
|
161
|
+
logger.info "#{msg}"
|
162
|
+
end
|
161
163
|
|
162
|
-
|
163
|
-
|
164
|
-
|
164
|
+
def log(msg)
|
165
|
+
logger.info "#{msg}"
|
166
|
+
end
|
165
167
|
|
166
|
-
|
167
|
-
|
168
|
-
|
168
|
+
def error(msg)
|
169
|
+
logger.error "#{msg}"
|
170
|
+
end
|
169
171
|
|
172
|
+
end
|
170
173
|
|
171
174
|
end
|
172
|
-
|