spqr 0.0.4 → 0.1.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/CHANGES +19 -0
- data/TODO +2 -3
- data/VERSION +1 -1
- data/examples/agent-app.rb +10 -0
- data/examples/examples/codegen/EchoAgent.rb +39 -0
- data/examples/hello.rb +41 -10
- data/examples/logservice.rb +14 -14
- data/lib/spqr/app.rb +34 -10
- data/lib/spqr/codegen.rb +47 -12
- data/lib/spqr/manageable.rb +45 -14
- data/test/example-apps.rb +19 -19
- data/test/test_spqr_clicker.rb +3 -3
- data/test/test_spqr_hello.rb +1 -4
- data/test/test_spqr_integerprop.rb +4 -1
- metadata +3 -1
data/CHANGES
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
version 0.1.0 (3a3ca52c4f086d1f20fdf5ed89dda262622c171d)
|
2
|
+
|
3
|
+
* Note that this version breaks backwards compatibility, for reasons
|
4
|
+
mentioned below. Most notably, the Manageable API names have changed,
|
5
|
+
and the old-style exposed-method declarations (with hash args) are no
|
6
|
+
longer supported in favor of a more idiomatic style.
|
7
|
+
|
8
|
+
* Exposed methods now use idiomatic parameter-passing style: input
|
9
|
+
(and in/out) parameters are passed in to methods by name (in the
|
10
|
+
order that they appear in the expose declaration), and output (and
|
11
|
+
in/out) values are returned in a list via a standard return
|
12
|
+
statement. (Again, the order of output and in/out parameters is
|
13
|
+
specified by the order that they appear in the expose declaration.)
|
14
|
+
|
15
|
+
* Code generation now uses idiomatic parameter-passing style. Code
|
16
|
+
generation should still be considered "alpha"-quality.
|
17
|
+
|
18
|
+
* Changed mixed-in method names from Manageable.
|
19
|
+
|
1
20
|
version 0.0.4 (180897a77b55400b31d364a08cb9f81c423eb59f)
|
2
21
|
|
3
22
|
* Test suite is mainly stable (individual tests will sometimes hang
|
data/TODO
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
To do, overall:
|
2
2
|
|
3
|
-
* packaging
|
3
|
+
* packaging (partially done)
|
4
4
|
|
5
5
|
|
6
6
|
To do for spqr:
|
@@ -8,12 +8,11 @@ To do for spqr:
|
|
8
8
|
! Event support
|
9
9
|
* Broader query support (partially done)
|
10
10
|
* Documentation
|
11
|
-
* Test suite
|
11
|
+
* Test suite (partially done)
|
12
12
|
- Automatic generation of smoke tests for services (either from schema or manageable class)
|
13
13
|
- Automatic schema generation from agent apps
|
14
14
|
- Usability improvements:
|
15
15
|
- Fewer required annotations
|
16
|
-
- Eliminate requirement for kwargs-style methods
|
17
16
|
- Automatic decoration of certain methods
|
18
17
|
|
19
18
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spqr/spqr'
|
2
|
+
|
3
|
+
module Examples
|
4
|
+
module Codegen
|
5
|
+
class EchoAgent
|
6
|
+
include ::SPQR::Manageable
|
7
|
+
|
8
|
+
qmf_package_name 'examples.codegen'
|
9
|
+
qmf_class_name 'EchoAgent'
|
10
|
+
# Find method (NB: you must implement this)
|
11
|
+
def EchoAgent.find_by_id(objid)
|
12
|
+
EchoAgent.new
|
13
|
+
end
|
14
|
+
|
15
|
+
# Find-all method (NB: you must implement this)
|
16
|
+
def EchoAgent.find_all
|
17
|
+
[EchoAgent.new]
|
18
|
+
end
|
19
|
+
### Schema method declarations
|
20
|
+
|
21
|
+
# echo returns its argument
|
22
|
+
# * arg (lstr/IO)
|
23
|
+
#
|
24
|
+
def echo(arg)
|
25
|
+
# Print values of in/out parameters
|
26
|
+
log.debug "echo: arg => #{arg.inspect}"
|
27
|
+
# Assign values to in/out parameters
|
28
|
+
arg ||= ""
|
29
|
+
# Return value
|
30
|
+
log.debug "echo: returning #{arg.inspect}"
|
31
|
+
return arg
|
32
|
+
end
|
33
|
+
|
34
|
+
expose :echo do |args|
|
35
|
+
args.declare :arg, :lstr, :inout, {}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/examples/hello.rb
CHANGED
@@ -1,30 +1,57 @@
|
|
1
|
-
require 'rubygems'
|
2
1
|
require 'spqr/spqr'
|
3
2
|
require 'spqr/app'
|
4
3
|
require 'logger'
|
5
4
|
|
6
5
|
class Hello
|
7
6
|
include SPQR::Manageable
|
8
|
-
|
9
|
-
|
7
|
+
|
8
|
+
# Input (in and inout) parameters are passed to exposed methods in
|
9
|
+
# the order they are declared in the expose block (see below).
|
10
|
+
def hello(name)
|
11
|
+
# We will keep track of the number of people we have greeted over
|
12
|
+
# the lifetime of this agent (see below for the people_greeted
|
13
|
+
# statistic declaration).
|
10
14
|
@people_greeted = @people_greeted + 1
|
11
|
-
|
15
|
+
|
16
|
+
# In methods that return only one value --- that is, those which
|
17
|
+
# have only one parameter that is either out or inout --- the
|
18
|
+
# return value is provided normally. Methods that have multiple
|
19
|
+
# out and inout parameters should return a list that includes the
|
20
|
+
# returned values in the order they are specified in the expose block.
|
21
|
+
"Hello, #{name}!"
|
12
22
|
end
|
13
23
|
|
14
|
-
|
24
|
+
# This block indicates that we intend to expose the "hello" method
|
25
|
+
# over QMF, that "name" is the first (and only) formal input
|
26
|
+
# parameter, and "result" is the first (and only) formal output
|
27
|
+
# parameter. Argument declarations include a name, a type, a
|
28
|
+
# direction, and optional keyword arguments.
|
29
|
+
expose :hello do |args|
|
15
30
|
args.declare :name, :lstr, :in
|
16
31
|
args.declare :result, :lstr, :out
|
17
32
|
end
|
18
33
|
|
19
|
-
# This is
|
34
|
+
# This is the method that will be called to get the value of the
|
35
|
+
# service_name property
|
20
36
|
def service_name
|
21
37
|
@service_name = "HelloAgent"
|
22
38
|
end
|
23
39
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
40
|
+
# The following two declarations provide the QMF package and class
|
41
|
+
# names for the published class. These can be provided either as
|
42
|
+
# symbols or as strings. If the class name is omitted, it will be
|
43
|
+
# generated from the class name.
|
44
|
+
qmf_package_name :hello
|
45
|
+
qmf_class_name :Hello
|
46
|
+
|
47
|
+
# The following two declarations create named QMF statistics and
|
48
|
+
# properties with given types. The value for a statistic or
|
49
|
+
# property is taken from the return values of the instance method
|
50
|
+
# with the same name as that statistic or property. If a method
|
51
|
+
# with this name does not exist, one is created with attr_reader
|
52
|
+
# and attr_writer.
|
53
|
+
qmf_statistic :people_greeted, :int
|
54
|
+
qmf_property :service_name, :lstr
|
28
55
|
|
29
56
|
# These should return the same object for the lifetime of the agent
|
30
57
|
# app, since this example has no persistent objects.
|
@@ -36,6 +63,10 @@ class Hello
|
|
36
63
|
@@hellos ||= [Hello.new]
|
37
64
|
@@hellos[0]
|
38
65
|
end
|
66
|
+
|
67
|
+
def initialize
|
68
|
+
@people_greeted = 0
|
69
|
+
end
|
39
70
|
end
|
40
71
|
|
41
72
|
app = SPQR::App.new(:loglevel => :debug)
|
data/examples/logservice.rb
CHANGED
@@ -22,7 +22,6 @@
|
|
22
22
|
# generated log records in that file, and they will persist between
|
23
23
|
# invocations.
|
24
24
|
|
25
|
-
require 'rubygems'
|
26
25
|
require 'spqr/spqr'
|
27
26
|
require 'spqr/app'
|
28
27
|
require 'rhubarb/rhubarb'
|
@@ -31,11 +30,11 @@ class LogService
|
|
31
30
|
include SPQR::Manageable
|
32
31
|
|
33
32
|
[:debug, :warn, :info, :error].each do |name|
|
34
|
-
define_method name do |
|
35
|
-
|
33
|
+
define_method name do |msg|
|
34
|
+
LogRecord.create(:l_when=>Time.now.to_i, :severity=>"#{name.to_s.upcase}", :msg=>msg.dup)
|
36
35
|
end
|
37
36
|
|
38
|
-
|
37
|
+
expose name do |args|
|
39
38
|
args.declare :msg, :lstr, :in
|
40
39
|
args.declare :result, :objId, :out
|
41
40
|
end
|
@@ -50,8 +49,8 @@ class LogService
|
|
50
49
|
@@singleton ||= LogService.new
|
51
50
|
end
|
52
51
|
|
53
|
-
|
54
|
-
|
52
|
+
qmf_package_name :examples
|
53
|
+
qmf_class_name :LogService
|
55
54
|
end
|
56
55
|
|
57
56
|
class LogRecord
|
@@ -65,22 +64,23 @@ class LogRecord
|
|
65
64
|
# XXX: rhubarb should create a find_all by default
|
66
65
|
declare_query :find_all, "1"
|
67
66
|
|
68
|
-
|
69
|
-
|
70
|
-
|
67
|
+
qmf_property :l_when, :uint
|
68
|
+
qmf_property :severity, :lstr
|
69
|
+
qmf_property :msg, :lstr
|
71
70
|
|
72
|
-
|
73
|
-
|
71
|
+
qmf_package_name :examples
|
72
|
+
qmf_class_name :LogRecord
|
74
73
|
|
75
74
|
def spqr_object_id
|
76
75
|
row_id
|
77
76
|
end
|
78
77
|
end
|
79
78
|
|
80
|
-
|
81
|
-
|
79
|
+
DBLOC = (ARGV[0] or ":memory:")
|
80
|
+
puts "storing results to #{DBLOC}"
|
81
|
+
DO_CREATE = (DBLOC == ":memory:" or not File.exist?(DBLOC))
|
82
82
|
|
83
|
-
Rhubarb::Persistence::open(
|
83
|
+
Rhubarb::Persistence::open(DBLOC)
|
84
84
|
|
85
85
|
LogRecord.create_table if DO_CREATE
|
86
86
|
|
data/lib/spqr/app.rb
CHANGED
@@ -56,7 +56,7 @@ module SPQR
|
|
56
56
|
|
57
57
|
schemaclass = schematize(klass)
|
58
58
|
|
59
|
-
klass.
|
59
|
+
klass.log = @log
|
60
60
|
|
61
61
|
@classes_by_id[klass.class_id] = klass
|
62
62
|
@classes_by_name[klass.name] = ClassMeta.new(klass, schemaclass)
|
@@ -75,21 +75,41 @@ module SPQR
|
|
75
75
|
|
76
76
|
@log.debug "calling method: context=#{context} method=#{name} object_id=#{obj_id}, args=#{args}, user=#{user_id}"
|
77
77
|
|
78
|
-
|
78
|
+
managed_object = find_object(context, class_id, obj_id)
|
79
|
+
@log.debug("managed object is #{managed_object}")
|
80
|
+
managed_method = managed_object.class.spqr_meta.mmethods[name.to_sym]
|
81
|
+
|
82
|
+
raise RuntimeError.new("#{managed_object.class} does not have #{name} exposed as a manageable method; has #{managed_object.class.spqr_meta.mmethods.inspect}") unless managed_method
|
83
|
+
|
84
|
+
# Extract actual parameters from the Qmf::Arguments structure into a proper ruby list
|
79
85
|
|
80
86
|
# XXX: consider adding appropriate impl method to Manageable
|
81
87
|
# to avoid this little dance
|
82
|
-
|
88
|
+
actuals_in = managed_method.formals_in.inject([]) {|acc,nm| acc << args[nm]}
|
89
|
+
actuals_in = actuals_in[0] if actuals_in.size == 1
|
83
90
|
|
84
|
-
managed_object
|
85
|
-
@log.debug("
|
91
|
+
@log.debug("managed_object.respond_to? #{managed_method.name.to_sym} ==> #{managed_object.respond_to? managed_method.name.to_sym}")
|
92
|
+
@log.debug("managed_object.class.spqr_meta.mmethods.include? #{name.to_sym} ==> #{managed_object.class.spqr_meta.mmethods.include? name.to_sym}")
|
93
|
+
@log.debug("formals: #{managed_method.formals_in.inspect}")
|
94
|
+
@log.debug("actuals: #{actuals_in.inspect}")
|
86
95
|
|
87
|
-
|
88
|
-
|
96
|
+
actuals_out = actuals_in.size > 0 ? managed_object.send(name.to_sym, actuals_in) : managed_object.send(name.to_sym)
|
97
|
+
|
98
|
+
raise RuntimeError.new("#{managed_object.class} did not return the appropriate number of return values; got '#{actuals_out.inspect}', but expected #{managed_method.types_out.inspect}") unless result_valid(actuals_out, managed_method)
|
99
|
+
|
100
|
+
if managed_method.formals_out.size == 0
|
101
|
+
actuals_out = [] # ignore return value in this case
|
102
|
+
elsif managed_method.formals_out.size == 1
|
103
|
+
actuals_out = [actuals_out] # wrap this up in a list
|
104
|
+
end
|
89
105
|
|
90
|
-
|
106
|
+
@log.debug("formals_out == #{managed_method.formals_out.inspect}")
|
107
|
+
@log.debug("actuals_out == #{actuals_out.inspect}")
|
108
|
+
|
109
|
+
# Copy any out parameters from return value to the
|
91
110
|
# Qmf::Arguments structure; see XXX above
|
92
|
-
|
111
|
+
managed_method.formals_out.zip(actuals_out).each do |k,v|
|
112
|
+
@log.debug("fixing up out params: #{k.inspect} --> #{v.inspect}")
|
93
113
|
encoded_val = encode_object(v)
|
94
114
|
args[k] = encoded_val
|
95
115
|
end
|
@@ -160,6 +180,10 @@ module SPQR
|
|
160
180
|
|
161
181
|
private
|
162
182
|
|
183
|
+
def result_valid(actuals, mm)
|
184
|
+
(actuals.kind_of?(Array) and mm.formals_out.size == actuals.size) or mm.formals_out.size <= 1
|
185
|
+
end
|
186
|
+
|
163
187
|
def qmf_arguments_to_hash(args)
|
164
188
|
result = {}
|
165
189
|
args.each do |k,v|
|
@@ -189,7 +213,7 @@ module SPQR
|
|
189
213
|
|
190
214
|
sc = Qmf::SchemaObjectClass.new(package, classname)
|
191
215
|
|
192
|
-
meta.
|
216
|
+
meta.manageable_methods.each do |mm|
|
193
217
|
@log.info("+-- creating a QMF schema for method #{mm}")
|
194
218
|
m_opts = mm.options
|
195
219
|
m_opts[:desc] ||= mm.description if mm.description
|
data/lib/spqr/codegen.rb
CHANGED
@@ -182,15 +182,17 @@ module SPQR
|
|
182
182
|
pp "include ::SPQR::Manageable"
|
183
183
|
pp ""
|
184
184
|
|
185
|
-
pp "
|
186
|
-
pp "
|
185
|
+
pp "qmf_package_name '#{@package_list.join(".")}'"
|
186
|
+
pp "qmf_class_name '#{@sc.name.split("::")[-1]}'"
|
187
187
|
|
188
188
|
pp '# Find method (NB: you must implement this)'
|
189
189
|
pp_decl :def, "#{@sc.name}.find_by_id", "(objid)" do
|
190
190
|
pp "#{@sc.name}.new"
|
191
191
|
end
|
192
192
|
|
193
|
-
pp "
|
193
|
+
pp ""
|
194
|
+
|
195
|
+
pp '# Find-all method (NB: you must implement this)'
|
194
196
|
pp_decl :def, "#{@sc.name}.find_all" do
|
195
197
|
pp "[#{@sc.name}.new]"
|
196
198
|
end
|
@@ -237,7 +239,7 @@ module SPQR
|
|
237
239
|
property.options[:desc] = property.desc if property.desc
|
238
240
|
|
239
241
|
pp ""
|
240
|
-
pp "
|
242
|
+
pp "qmf_property #{property.name.to_sym.inspect}, #{property.kind.to_sym.inspect}, #{property.options.inspect.gsub(/[{}]/, '')}"
|
241
243
|
end
|
242
244
|
|
243
245
|
def gen_statistic(statistic)
|
@@ -251,7 +253,7 @@ module SPQR
|
|
251
253
|
statistic.options[:desc] = statistic.desc if statistic.desc
|
252
254
|
|
253
255
|
pp ""
|
254
|
-
pp "
|
256
|
+
pp "qmf_property #{statistic.name.to_sym.inspect}, #{statistic.kind.to_sym.inspect}, #{statistic.options.inspect.gsub(/[{}]/, '')}"
|
255
257
|
end
|
256
258
|
|
257
259
|
def gen_method(method)
|
@@ -265,8 +267,22 @@ module SPQR
|
|
265
267
|
in_params = method.args.select {|arg| ['in', 'i', 'qmf::dir_in'].include? arg.dir.to_s.downcase }
|
266
268
|
out_params = method.args.select {|arg| ['out', 'o', 'qmf::dir_out'].include? arg.dir.to_s.downcase }
|
267
269
|
inout_params = method.args.select {|arg| ['inout', 'io', 'qmf::dir_inout'].include? arg.dir.to_s.downcase }
|
268
|
-
|
269
|
-
|
270
|
+
|
271
|
+
formals_in = method.args.select {|arg| ['in','i','qmf::dir_in','io','inout','qmf::dir_inout'].include? arg.dir.to_s.downcase}.map{|arg| arg.name}.join(",")
|
272
|
+
formals_out = method.args.select {|arg| ['out','o','qmf::dir_out','io','inout','qmf::dir_inout'].include? arg.dir.to_s.downcase}.map{|arg| arg.name}
|
273
|
+
|
274
|
+
actuals_out = case formals_out.size
|
275
|
+
when 0 then nil.inspect
|
276
|
+
when 1 then formals_out[0].to_s
|
277
|
+
else "[#{formals_out.join(", ")}]"
|
278
|
+
end
|
279
|
+
|
280
|
+
param_types = method.args.inject({}) do |acc, arg|
|
281
|
+
acc[arg.name.to_s] = arg.kind.to_s
|
282
|
+
acc
|
283
|
+
end
|
284
|
+
|
285
|
+
pp_decl :def, method.name, "(#{formals_in})" do
|
270
286
|
|
271
287
|
if in_params.size + inout_params.size > 0
|
272
288
|
what = "in"
|
@@ -279,8 +295,8 @@ module SPQR
|
|
279
295
|
|
280
296
|
pp "\# Print values of #{what} parameters"
|
281
297
|
(in_params + inout_params).each do |arg|
|
282
|
-
argdisplay = arg.name.to_s
|
283
|
-
pp('log.debug "' + "#{arg.name} => " + '#{
|
298
|
+
argdisplay = arg.name.to_s
|
299
|
+
pp('log.debug "' + "#{method.name}: #{arg.name} => " + '#{' + "#{argdisplay}" + '}"')
|
284
300
|
end
|
285
301
|
end
|
286
302
|
|
@@ -296,15 +312,21 @@ module SPQR
|
|
296
312
|
pp "\# Assign values to #{what} parameters"
|
297
313
|
|
298
314
|
(out_params + inout_params).each do |arg|
|
299
|
-
argdisplay = arg.name.to_s
|
300
|
-
|
315
|
+
argdisplay = arg.name.to_s
|
316
|
+
argtype = param_types[argdisplay]
|
317
|
+
raise RuntimeError.new("Can't find type for #{argdisplay} in #{param_types.inspect}") unless argtype
|
318
|
+
pp "#{argdisplay} ||= #{default_val(argtype)}"
|
301
319
|
end
|
320
|
+
|
321
|
+
pp "\# Return value"
|
322
|
+
pp "return #{actuals_out}"
|
323
|
+
|
302
324
|
end
|
303
325
|
end
|
304
326
|
|
305
327
|
|
306
328
|
pp ""
|
307
|
-
pp_decl :
|
329
|
+
pp_decl :expose, "#{method.name.to_sym.inspect} do |args|" do
|
308
330
|
{:in => in_params, :inout => inout_params, :out => out_params}.each do |dir,coll|
|
309
331
|
coll.each do |arg|
|
310
332
|
arg_nm = arg.name
|
@@ -315,6 +337,19 @@ module SPQR
|
|
315
337
|
end
|
316
338
|
end
|
317
339
|
end
|
340
|
+
|
341
|
+
def default_val(ty)
|
342
|
+
case ty
|
343
|
+
when 'array', 'list' then [].inspect
|
344
|
+
when 'bool' then false.inspect
|
345
|
+
when 'double', 'float' then 0.0.inspect
|
346
|
+
when 'absTime', 'deltaTime', 'int16', 'int32', 'int64', 'int', 'int8', 'uint16', 'uint32', 'uint64', 'uint', 'uint8' then 0.inspect
|
347
|
+
when 'lstr', 'string', 'sstr', 'uuid' then "".inspect
|
348
|
+
when 'map' then {}.inspect
|
349
|
+
when 'objId' then nil.inspect
|
350
|
+
else raise RuntimeError.new("Unknown type #{ty.inspect}")
|
351
|
+
end
|
352
|
+
end
|
318
353
|
end
|
319
354
|
|
320
355
|
class AppBoilerplateGenerator
|
data/lib/spqr/manageable.rb
CHANGED
@@ -19,16 +19,19 @@ module SPQR
|
|
19
19
|
self.options = (({} unless self.options) or self.options.dup)
|
20
20
|
self.statistics = [] unless self.statistics
|
21
21
|
self.properties = [] unless self.properties
|
22
|
-
self.mmethods ||=
|
22
|
+
self.mmethods ||= {}
|
23
23
|
end
|
24
24
|
|
25
25
|
def declare_method(name, desc, options, blk=nil)
|
26
26
|
result = MethodMeta.new name, desc, options
|
27
27
|
blk.call(result.args) if blk
|
28
|
-
self.mmethods
|
29
|
-
self.mmethods[-1]
|
28
|
+
self.mmethods[name] = result
|
30
29
|
end
|
31
30
|
|
31
|
+
def manageable_methods
|
32
|
+
self.mmethods.values
|
33
|
+
end
|
34
|
+
|
32
35
|
def declare_statistic(name, kind, options)
|
33
36
|
declare_basic(:statistic, name, kind, options)
|
34
37
|
end
|
@@ -57,6 +60,34 @@ module SPQR
|
|
57
60
|
self.args = gen_args
|
58
61
|
end
|
59
62
|
|
63
|
+
def formals_in
|
64
|
+
self.args.select {|arg| arg.direction == :in or arg.direction == :inout}.collect{|arg| arg.name.to_s}
|
65
|
+
end
|
66
|
+
|
67
|
+
def formals_out
|
68
|
+
self.args.select {|arg| arg.direction == :inout or arg.direction == :out}.collect{|arg| arg.name.to_s}
|
69
|
+
end
|
70
|
+
|
71
|
+
def types_in
|
72
|
+
self.args.select {|arg| arg.direction == :in or arg.direction == :inout}.collect{|arg| arg.kind.to_s}
|
73
|
+
end
|
74
|
+
|
75
|
+
def types_out
|
76
|
+
self.args.select {|arg| arg.direction == :inout or arg.direction == :out}.collect{|arg| arg.kind.to_s}
|
77
|
+
end
|
78
|
+
|
79
|
+
def type_of(param)
|
80
|
+
@types_for ||= self.args.inject({}) do |acc,arg|
|
81
|
+
k = arg.name
|
82
|
+
v = arg.kind.to_s
|
83
|
+
acc[k] = v
|
84
|
+
acc[k.to_s] = v
|
85
|
+
acc
|
86
|
+
end
|
87
|
+
|
88
|
+
@types_for[param]
|
89
|
+
end
|
90
|
+
|
60
91
|
private
|
61
92
|
def gen_args
|
62
93
|
result = []
|
@@ -97,36 +128,36 @@ module SPQR
|
|
97
128
|
@spqr_meta ||= ::SPQR::ManageableMeta.new
|
98
129
|
end
|
99
130
|
|
100
|
-
def
|
131
|
+
def log=(logger)
|
101
132
|
@spqr_log = logger
|
102
133
|
end
|
103
134
|
|
104
|
-
def
|
135
|
+
def log
|
105
136
|
@spqr_log || ::SPQR::Sink.new
|
106
137
|
end
|
107
138
|
|
108
139
|
# Exposes a method to QMF
|
109
|
-
def
|
140
|
+
def expose(name, description=nil, options=nil, &blk)
|
110
141
|
spqr_meta.declare_method(name, description, options, blk)
|
111
142
|
end
|
112
143
|
|
113
|
-
def
|
144
|
+
def qmf_package_name(nm)
|
114
145
|
spqr_meta.package = nm
|
115
146
|
end
|
116
147
|
|
117
|
-
def
|
148
|
+
def qmf_class_name(nm)
|
118
149
|
spqr_meta.classname = nm
|
119
150
|
end
|
120
151
|
|
121
|
-
def
|
152
|
+
def qmf_description(d)
|
122
153
|
spqr_meta.description = d
|
123
154
|
end
|
124
155
|
|
125
|
-
def
|
156
|
+
def qmf_options(opts)
|
126
157
|
spqr_meta.options = opts.dup
|
127
158
|
end
|
128
159
|
|
129
|
-
def
|
160
|
+
def qmf_statistic(name, kind, options=nil)
|
130
161
|
spqr_meta.declare_statistic(name, kind, options)
|
131
162
|
|
132
163
|
self.class_eval do
|
@@ -142,7 +173,7 @@ module SPQR
|
|
142
173
|
end
|
143
174
|
end
|
144
175
|
|
145
|
-
def
|
176
|
+
def qmf_property(name, kind, options=nil)
|
146
177
|
spqr_meta.declare_property(name, kind, options)
|
147
178
|
|
148
179
|
# add a property accessor to instances of other
|
@@ -188,7 +219,7 @@ module SPQR
|
|
188
219
|
end
|
189
220
|
|
190
221
|
def log
|
191
|
-
self.class.
|
222
|
+
self.class.log
|
192
223
|
end
|
193
224
|
|
194
225
|
def self.included(other)
|
@@ -216,7 +247,7 @@ module SPQR
|
|
216
247
|
end
|
217
248
|
end
|
218
249
|
|
219
|
-
other.
|
250
|
+
other.qmf_class_name other.name.to_sym
|
220
251
|
end
|
221
252
|
end
|
222
253
|
end
|
data/test/example-apps.rb
CHANGED
@@ -15,17 +15,17 @@ class QmfClicker
|
|
15
15
|
@clicks = 0
|
16
16
|
end
|
17
17
|
|
18
|
-
def click
|
18
|
+
def click
|
19
19
|
@clicks = @clicks.succ
|
20
20
|
end
|
21
21
|
|
22
|
-
|
22
|
+
expose :click do |args|
|
23
23
|
end
|
24
24
|
|
25
|
-
|
25
|
+
qmf_statistic :clicks, :int
|
26
26
|
|
27
|
-
|
28
|
-
|
27
|
+
qmf_package_name :example
|
28
|
+
qmf_class_name :QmfClicker
|
29
29
|
end
|
30
30
|
|
31
31
|
class QmfHello
|
@@ -41,17 +41,17 @@ class QmfHello
|
|
41
41
|
@qmf_hellos
|
42
42
|
end
|
43
43
|
|
44
|
-
def hello(
|
45
|
-
|
44
|
+
def hello(name)
|
45
|
+
"Hello, #{name}!"
|
46
46
|
end
|
47
47
|
|
48
|
-
|
48
|
+
expose :hello do |args|
|
49
49
|
args.declare :name, :lstr, :in
|
50
50
|
args.declare :result, :lstr, :out
|
51
51
|
end
|
52
52
|
|
53
|
-
|
54
|
-
|
53
|
+
qmf_package_name :example
|
54
|
+
qmf_class_name :QmfHello
|
55
55
|
end
|
56
56
|
|
57
57
|
class QmfDummyProp
|
@@ -71,10 +71,10 @@ class QmfDummyProp
|
|
71
71
|
"DummyPropService"
|
72
72
|
end
|
73
73
|
|
74
|
-
|
74
|
+
qmf_property :service_name, :lstr
|
75
75
|
|
76
|
-
|
77
|
-
|
76
|
+
qmf_class_name :QmfDummyProp
|
77
|
+
qmf_package_name :example
|
78
78
|
end
|
79
79
|
|
80
80
|
|
@@ -109,18 +109,18 @@ class QmfIntegerProp
|
|
109
109
|
@qmf_ips
|
110
110
|
end
|
111
111
|
|
112
|
-
def next
|
113
|
-
|
112
|
+
def next
|
113
|
+
QmfIntegerProp.find_by_id((@int_id + 1) % QmfIntegerProp::SIZE)
|
114
114
|
end
|
115
115
|
|
116
|
-
|
116
|
+
expose :next do |args|
|
117
117
|
args.declare :result, :objId, :out
|
118
118
|
end
|
119
119
|
|
120
|
-
|
120
|
+
qmf_property :int_id, :int, :index=>true
|
121
121
|
|
122
|
-
|
123
|
-
|
122
|
+
qmf_class_name :QmfIntegerProp
|
123
|
+
qmf_package_name :example
|
124
124
|
end
|
125
125
|
|
126
126
|
|
data/test/test_spqr_clicker.rb
CHANGED
@@ -15,7 +15,7 @@ class TestSpqrClicker < Test::Unit::TestCase
|
|
15
15
|
assert_nothing_raised do
|
16
16
|
obj = $console.objects(:class=>"QmfClicker", :agent=>@ag)[0]
|
17
17
|
|
18
|
-
obj.click
|
18
|
+
obj.click
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -36,7 +36,7 @@ class TestSpqrClicker < Test::Unit::TestCase
|
|
36
36
|
obj = $console.objects(:class=>"QmfClicker", :agent=>@ag)[0]
|
37
37
|
assert_equal x, obj[:clicks]
|
38
38
|
|
39
|
-
obj.click
|
39
|
+
obj.click
|
40
40
|
x = x.succ
|
41
41
|
end
|
42
42
|
end
|
@@ -51,7 +51,7 @@ class TestSpqrClicker < Test::Unit::TestCase
|
|
51
51
|
obj.update
|
52
52
|
assert_equal x, obj[:clicks]
|
53
53
|
|
54
|
-
obj.click
|
54
|
+
obj.click
|
55
55
|
x = x.succ
|
56
56
|
end
|
57
57
|
end
|
data/test/test_spqr_hello.rb
CHANGED
@@ -18,12 +18,9 @@ class TestSpqrHello < Test::Unit::TestCase
|
|
18
18
|
def test_hello_call
|
19
19
|
app_setup QmfHello
|
20
20
|
obj = $console.objects(:class=>"QmfHello", :agent=>@ag)[0]
|
21
|
-
|
22
21
|
val = obj.hello("ruby").result
|
23
|
-
args = { 'name' => 'ruby' }
|
24
|
-
QmfHello.find_by_id(0).hello(args)
|
25
22
|
|
26
|
-
expected =
|
23
|
+
expected = QmfHello.find_by_id(0).hello("ruby")
|
27
24
|
|
28
25
|
assert_equal expected, val
|
29
26
|
end
|
@@ -16,7 +16,10 @@ class TestSpqrIntegerProp < Test::Unit::TestCase
|
|
16
16
|
|
17
17
|
objs.size.times do |x|
|
18
18
|
expected = objs[(x + 1) % QmfIntegerProp::SIZE]
|
19
|
-
|
19
|
+
o = objs[x]
|
20
|
+
next_o = o.next.result
|
21
|
+
puts ("next_o: #{next_o}")
|
22
|
+
actual = $console.object(:object_id=>next_o)
|
20
23
|
assert_equal expected.int_id, actual.int_id
|
21
24
|
end
|
22
25
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spqr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- William Benton
|
@@ -101,5 +101,7 @@ test_files:
|
|
101
101
|
- test/test_spqr_integerprop.rb
|
102
102
|
- test/test_rhubarb.rb
|
103
103
|
- test/test_spqr_hello.rb
|
104
|
+
- examples/agent-app.rb
|
105
|
+
- examples/examples/codegen/EchoAgent.rb
|
104
106
|
- examples/hello.rb
|
105
107
|
- examples/logservice.rb
|