stella 0.7.1 → 0.7.2
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.txt +16 -0
- data/Rudyfile +63 -27
- data/bin/stella +1 -0
- data/examples/essentials/plan.rb +1 -1
- data/examples/exceptions/plan.rb +1 -1
- data/lib/stella.rb +5 -1
- data/lib/stella/cli.rb +1 -1
- data/lib/stella/client.rb +119 -53
- data/lib/stella/client/container.rb +264 -14
- data/lib/stella/client/modifiers.rb +1 -0
- data/lib/stella/data.rb +182 -61
- data/lib/stella/data/http/request.rb +20 -2
- data/lib/stella/engine.rb +6 -2
- data/lib/stella/engine/functional.rb +35 -20
- data/lib/stella/engine/load_create.rb +2 -0
- data/lib/stella/engine/load_queue.rb +27 -7
- data/lib/stella/engine/loadbase.rb +22 -12
- data/lib/stella/testplan.rb +8 -1
- data/lib/stella/testplan/usecase.rb +14 -1
- data/lib/stella/version.rb +2 -2
- data/stella.gemspec +3 -1
- data/support/sample_webapp/app.rb +0 -1
- data/tryouts/configs/failed_requests.rb +31 -0
- data/tryouts/configs/global_sequential.rb +18 -0
- data/vendor/httpclient-2.1.5.2/httpclient.rb +2 -2
- metadata +5 -3
@@ -3,36 +3,146 @@
|
|
3
3
|
class Stella::Client
|
4
4
|
|
5
5
|
class Container
|
6
|
+
MUTEX = Mutex.new
|
7
|
+
|
8
|
+
@sequential_offset = {}
|
9
|
+
@rsequential_offset = {}
|
10
|
+
class << self
|
11
|
+
def sequential_offset(resid, max)
|
12
|
+
MUTEX.synchronize do
|
13
|
+
@sequential_offset[resid] ||= -1
|
14
|
+
if @sequential_offset[resid] >= max
|
15
|
+
@sequential_offset[resid] = 0
|
16
|
+
else
|
17
|
+
@sequential_offset[resid] += 1
|
18
|
+
end
|
19
|
+
@sequential_offset[resid]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
## TODO: BROKEN?
|
23
|
+
##def rsequential_offset(resid, max)
|
24
|
+
## MUTEX.synchronize do
|
25
|
+
## @rsequential_offset[resid] ||= max+1
|
26
|
+
## if @rsequential_offset[resid] <= 0
|
27
|
+
## @rsequential_offset[resid] = max
|
28
|
+
## else
|
29
|
+
## @rsequential_offset[resid] -= 1
|
30
|
+
## end
|
31
|
+
## @rsequential_offset[resid]
|
32
|
+
## end
|
33
|
+
##end
|
34
|
+
end
|
35
|
+
|
36
|
+
# This is used to handle custom exception in usecases.
|
37
|
+
# See examples/exceptions/plan.rb
|
38
|
+
#
|
39
|
+
def self.const_missing(custom_error)
|
40
|
+
ResponseError.new custom_error
|
41
|
+
end
|
42
|
+
|
6
43
|
|
7
44
|
attr_accessor :usecase
|
45
|
+
attr_accessor :params
|
46
|
+
attr_accessor :headers
|
8
47
|
attr_accessor :response
|
9
48
|
attr_reader :resources
|
10
|
-
|
49
|
+
attr_reader :client_id
|
50
|
+
attr_reader :assets
|
51
|
+
|
52
|
+
def initialize(client_id, usecase)
|
53
|
+
@client_id = client_id
|
11
54
|
@usecase, @resources = usecase, {}
|
12
55
|
@base_path = usecase.base_path
|
56
|
+
@assets = []
|
13
57
|
@random_value = {}
|
14
58
|
end
|
15
59
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
60
|
+
def params(key=nil)
|
61
|
+
key.nil? ? @params : @params[key]
|
62
|
+
end
|
63
|
+
alias_method :param, :params
|
64
|
+
|
65
|
+
def headers(key=nil)
|
66
|
+
key.nil? ? @headers : @headers[key]
|
67
|
+
end
|
68
|
+
alias_method :header, :headers
|
69
|
+
|
70
|
+
# This is intended to be called in between requests.
|
71
|
+
def reset_temp_vars
|
72
|
+
@random_value = {}
|
73
|
+
@sequential_value = {}
|
74
|
+
@rsequential_value = {}
|
75
|
+
@doc, @forms, @assets = nil, nil, []
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
def fetch(*args)
|
81
|
+
@assets.push *args.flatten
|
82
|
+
end
|
83
|
+
|
84
|
+
def parse_template(t)
|
85
|
+
# ERB BUG?: Under heavy threading, some calls
|
86
|
+
# produce the error:
|
87
|
+
# wrong number of arguments(1 for 0)
|
88
|
+
template = ERB.new(t)
|
89
|
+
v = template.result(binding)
|
90
|
+
rescue
|
91
|
+
t
|
21
92
|
end
|
22
93
|
|
23
94
|
def doc
|
95
|
+
return @doc unless @doc.nil?
|
24
96
|
# NOTE: It's important to parse the document on every
|
25
97
|
# request because this container is available for the
|
26
98
|
# entire life of a usecase.
|
27
|
-
case (@response.header['Content-Type'] || []).first
|
99
|
+
@doc = case (@response.header['Content-Type'] || []).first
|
28
100
|
when /text\/html/
|
29
101
|
Nokogiri::HTML(body)
|
30
102
|
when /text\/xml/
|
31
103
|
Nokogiri::XML(body)
|
32
104
|
when /text\/yaml/
|
33
105
|
YAML.load(body)
|
106
|
+
when /application\/json/
|
107
|
+
JSON.load(body)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
class Form < Hash
|
112
|
+
def fields(key)
|
113
|
+
self['input'] ||= {}
|
114
|
+
self['input'][key]
|
115
|
+
end
|
116
|
+
alias_method :field, :fields
|
117
|
+
class << self
|
118
|
+
# Create an instance from a Nokogiri::HTML::Document
|
119
|
+
def from_doc(doc)
|
120
|
+
f = new
|
121
|
+
doc.each { |n,v| f[n] = v }
|
122
|
+
f['input'] = {}
|
123
|
+
(doc.css('input') || []).each do |input|
|
124
|
+
f['input'][input['name']] = input['value']
|
125
|
+
end
|
126
|
+
f
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
def forms(fid=nil)
|
133
|
+
if @forms.nil? && Nokogiri::HTML::Document === doc
|
134
|
+
@forms, index = {}, 0
|
135
|
+
(doc.css('form') || []).each do |html|
|
136
|
+
name = html['id'] || html['name'] || html['class']
|
137
|
+
Stella.ld [:form, name, index].inspect
|
138
|
+
# Store the form by the name and index in the document
|
139
|
+
@forms[name] = @forms[index] = Form.from_doc(html)
|
140
|
+
index += 1
|
141
|
+
end
|
34
142
|
end
|
143
|
+
(fid.nil? ? @forms : @forms[fid])
|
35
144
|
end
|
145
|
+
alias_method :form, :forms
|
36
146
|
|
37
147
|
# Return a resource from the usecase or from this
|
38
148
|
# container (in that order).
|
@@ -41,21 +151,161 @@ class Stella::Client
|
|
41
151
|
return @resources[n] if @resources.has_key? n
|
42
152
|
nil
|
43
153
|
end
|
44
|
-
|
45
|
-
def reset_temp_vars
|
46
|
-
@random_value = {}
|
47
|
-
@sequential_value = {}
|
48
|
-
@rsequential_value = {}
|
49
|
-
end
|
50
154
|
|
51
155
|
def body; @response.body.content; end
|
52
156
|
def headers; @response.header; end
|
53
157
|
alias_method :header, :headers
|
54
158
|
def status; @response.status; end
|
55
|
-
def set(
|
159
|
+
def set(*args)
|
160
|
+
h = Hash === args[0] ? args[0] : {args[0]=> args[1]}
|
161
|
+
@resources.merge! h
|
162
|
+
end
|
56
163
|
def wait(t); sleep t; end
|
57
164
|
def quit(msg=nil); Quit.new(msg); end
|
165
|
+
def fail(msg=nil); Fail.new(msg); end
|
58
166
|
def repeat(t=1); Repeat.new(t); end
|
167
|
+
|
168
|
+
|
169
|
+
|
170
|
+
#
|
171
|
+
# QUICK HACK ALERT:
|
172
|
+
# Copied from Stella::Data::Helpers, removed Proc.new, just return the value
|
173
|
+
#
|
174
|
+
|
175
|
+
|
176
|
+
# Can include glob
|
177
|
+
#
|
178
|
+
# e.g.
|
179
|
+
# random_file('avatar*')
|
180
|
+
def random_file(*args)
|
181
|
+
input = args.size > 1 ? args : args.first
|
182
|
+
|
183
|
+
value = case input.class.to_s
|
184
|
+
when "String"
|
185
|
+
Stella.ld "FILE: #{input}"
|
186
|
+
path = File.exists?(input) ? input : File.join(@base_path, input)
|
187
|
+
files = Dir.glob(path)
|
188
|
+
path = files[ rand(files.size) ]
|
189
|
+
Stella.ld "Creating file object: #{path}"
|
190
|
+
File.new(path)
|
191
|
+
when "Proc"
|
192
|
+
input.call
|
193
|
+
else
|
194
|
+
input
|
195
|
+
end
|
196
|
+
raise Stella::Testplan::Usecase::UnknownResource, input if value.nil?
|
197
|
+
Stella.ld "FILE: #{value}"
|
198
|
+
value
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
def file(*args)
|
203
|
+
input = args.size > 1 ? args : args.first
|
204
|
+
|
205
|
+
value = case input.class.to_s
|
206
|
+
when "String"
|
207
|
+
Stella.ld "FILE: #{input}"
|
208
|
+
path = File.exists?(input) ? input : File.join(@base_path, input)
|
209
|
+
Stella.ld "Creating file object: #{path}"
|
210
|
+
File.new(path)
|
211
|
+
when "Proc"
|
212
|
+
input.call
|
213
|
+
else
|
214
|
+
input
|
215
|
+
end
|
216
|
+
raise Stella::Testplan::Usecase::UnknownResource, input if value.nil?
|
217
|
+
Stella.ld "FILE: #{value}"
|
218
|
+
value
|
219
|
+
|
220
|
+
end
|
221
|
+
|
222
|
+
def random(*args)
|
223
|
+
if Symbol === args.first
|
224
|
+
input, index = *args
|
225
|
+
elsif Array === args.first || args.size == 1
|
226
|
+
input = args.first
|
227
|
+
else
|
228
|
+
input = args
|
229
|
+
end
|
230
|
+
|
231
|
+
|
232
|
+
if @random_value[input.object_id]
|
233
|
+
value = @random_value[input.object_id]
|
234
|
+
else
|
235
|
+
value = case input.class.to_s
|
236
|
+
when "Symbol"
|
237
|
+
resource(input)
|
238
|
+
when "Array"
|
239
|
+
input
|
240
|
+
when "Range"
|
241
|
+
input.to_a
|
242
|
+
when "Proc"
|
243
|
+
input.call
|
244
|
+
when "Fixnum"
|
245
|
+
Stella::Utils.strand( input )
|
246
|
+
when "NilClass"
|
247
|
+
Stella::Utils.strand( rand(100) )
|
248
|
+
end
|
249
|
+
raise Stella::Testplan::Usecase::UnknownResource, input if value.nil?
|
250
|
+
Stella.ld "RANDVALUES: #{input} #{value.class} #{value.inspect}"
|
251
|
+
value = value[ rand(value.size) ] if value.is_a?(Array)
|
252
|
+
Stella.ld "SELECTED: #{value.class} #{value} "
|
253
|
+
@random_value[input.object_id] = value
|
254
|
+
end
|
255
|
+
|
256
|
+
# The resource may be an Array of Arrays (e.g. a CSV file)
|
257
|
+
if value.is_a?(Array) && !index.nil?
|
258
|
+
value = value[ index ]
|
259
|
+
Stella.ld "SELECTED INDEX: #{index} #{value.inspect} "
|
260
|
+
end
|
261
|
+
|
262
|
+
value
|
263
|
+
|
264
|
+
end
|
265
|
+
|
266
|
+
|
267
|
+
# NOTE: This is global across all users
|
268
|
+
def sequential(*args)
|
269
|
+
if Symbol === args.first
|
270
|
+
input, index = *args
|
271
|
+
elsif Array === args.first || args.size == 1
|
272
|
+
input = args.first
|
273
|
+
else
|
274
|
+
input = args
|
275
|
+
end
|
276
|
+
|
277
|
+
if @sequential_value[input.object_id]
|
278
|
+
value = @sequential_value[input.object_id]
|
279
|
+
else
|
280
|
+
value = case input.class.to_s
|
281
|
+
when "Symbol"
|
282
|
+
ret = resource(input)
|
283
|
+
ret
|
284
|
+
when "Array"
|
285
|
+
input
|
286
|
+
when "Range"
|
287
|
+
input.to_a
|
288
|
+
when "Proc"
|
289
|
+
input.call
|
290
|
+
end
|
291
|
+
digest = value.object_id
|
292
|
+
if value.is_a?(Array)
|
293
|
+
index = Container.sequential_offset(digest, value.size-1)
|
294
|
+
value = value[ index ]
|
295
|
+
end
|
296
|
+
Stella.ld "SELECTED(SEQ): #{value} #{index} #{input} #{digest}"
|
297
|
+
# I think this needs to be updated for global_sequential:
|
298
|
+
@sequential_value[input.object_id] = value
|
299
|
+
end
|
300
|
+
# The resource may be an Array of Arrays (e.g. a CSV file)
|
301
|
+
if value.is_a?(Array) && !index.nil?
|
302
|
+
value = value[ index ]
|
303
|
+
Stella.ld "SELECTED INDEX: #{index} #{value.inspect} "
|
304
|
+
end
|
305
|
+
value
|
306
|
+
|
307
|
+
end
|
308
|
+
|
59
309
|
end
|
60
310
|
|
61
311
|
end
|
data/lib/stella/data.rb
CHANGED
@@ -9,6 +9,32 @@ module Stella::Data
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
+
# Can include glob
|
13
|
+
#
|
14
|
+
# e.g.
|
15
|
+
# random_file('avatar*')
|
16
|
+
def random_file(*args)
|
17
|
+
input = args.size > 1 ? args : args.first
|
18
|
+
Proc.new do
|
19
|
+
value = case input.class.to_s
|
20
|
+
when "String"
|
21
|
+
Stella.ld "FILE: #{input}"
|
22
|
+
path = File.exists?(input) ? input : File.join(@base_path, input)
|
23
|
+
files = Dir.glob(path)
|
24
|
+
path = files[ rand(files.size) ]
|
25
|
+
Stella.ld "Creating file object: #{path}"
|
26
|
+
File.new(path)
|
27
|
+
when "Proc"
|
28
|
+
input.call
|
29
|
+
else
|
30
|
+
input
|
31
|
+
end
|
32
|
+
raise Stella::Testplan::Usecase::UnknownResource, input if value.nil?
|
33
|
+
Stella.ld "FILE: #{value}"
|
34
|
+
value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
12
38
|
def file(*args)
|
13
39
|
input = args.size > 1 ? args : args.first
|
14
40
|
Proc.new do
|
@@ -39,8 +65,8 @@ module Stella::Data
|
|
39
65
|
end
|
40
66
|
|
41
67
|
Proc.new do
|
42
|
-
if @random_value[input]
|
43
|
-
value = @random_value[input]
|
68
|
+
if @random_value[input.object_id]
|
69
|
+
value = @random_value[input.object_id]
|
44
70
|
else
|
45
71
|
value = case input.class.to_s
|
46
72
|
when "Symbol"
|
@@ -60,7 +86,7 @@ module Stella::Data
|
|
60
86
|
Stella.ld "RANDVALUES: #{input} #{value.class} #{value.inspect}"
|
61
87
|
value = value[ rand(value.size) ] if value.is_a?(Array)
|
62
88
|
Stella.ld "SELECTED: #{value.class} #{value} "
|
63
|
-
@random_value[input] = value
|
89
|
+
@random_value[input.object_id] = value
|
64
90
|
end
|
65
91
|
|
66
92
|
# The resource may be an Array of Arrays (e.g. a CSV file)
|
@@ -73,6 +99,8 @@ module Stella::Data
|
|
73
99
|
end
|
74
100
|
end
|
75
101
|
|
102
|
+
|
103
|
+
# NOTE: This is global across all users
|
76
104
|
def sequential(*args)
|
77
105
|
if Symbol === args.first
|
78
106
|
input, index = *args
|
@@ -82,8 +110,8 @@ module Stella::Data
|
|
82
110
|
input = args
|
83
111
|
end
|
84
112
|
Proc.new do
|
85
|
-
if @sequential_value[input]
|
86
|
-
value = @sequential_value[input]
|
113
|
+
if @sequential_value[input.object_id]
|
114
|
+
value = @sequential_value[input.object_id]
|
87
115
|
else
|
88
116
|
value = case input.class.to_s
|
89
117
|
when "Symbol"
|
@@ -96,18 +124,14 @@ module Stella::Data
|
|
96
124
|
when "Proc"
|
97
125
|
input.call
|
98
126
|
end
|
99
|
-
digest = value.
|
100
|
-
@sequential_offset ||= {}
|
101
|
-
@sequential_offset[digest] ||= 0
|
102
|
-
Stella.ld "SEQVALUES: #{input} #{value.inspect} #{@sequential_offset[digest]}"
|
127
|
+
digest = value.object_id
|
103
128
|
if value.is_a?(Array)
|
104
|
-
|
105
|
-
|
106
|
-
value = value[ @sequential_offset[digest] ]
|
107
|
-
@sequential_offset[digest] += 1
|
129
|
+
index = Container.sequential_offset(digest, value.size-1)
|
130
|
+
value = value[ index ]
|
108
131
|
end
|
109
|
-
Stella.ld "SELECTED: #{value}"
|
110
|
-
|
132
|
+
Stella.ld "SELECTED(SEQ): #{value} #{index} #{input} #{digest}"
|
133
|
+
# I think this needs to be updated for global_sequential:
|
134
|
+
@sequential_value[input.object_id] = value
|
111
135
|
end
|
112
136
|
# The resource may be an Array of Arrays (e.g. a CSV file)
|
113
137
|
if value.is_a?(Array) && !index.nil?
|
@@ -118,53 +142,150 @@ module Stella::Data
|
|
118
142
|
end
|
119
143
|
end
|
120
144
|
|
121
|
-
def rsequential(*args)
|
122
|
-
if Symbol === args.first
|
123
|
-
input, index = *args
|
124
|
-
elsif Array === args.first || args.size == 1
|
125
|
-
input = args.first
|
126
|
-
else
|
127
|
-
input = args
|
128
|
-
end
|
129
|
-
Proc.new do
|
130
|
-
if @rsequential_value[input.digest]
|
131
|
-
value = @rsequential_value[input.digest]
|
132
|
-
else
|
133
|
-
value = case input.class.to_s
|
134
|
-
when "Symbol"
|
135
|
-
ret = resource(input)
|
136
|
-
ret
|
137
|
-
when "Array"
|
138
|
-
input
|
139
|
-
when "Range"
|
140
|
-
input.to_a
|
141
|
-
when "Proc"
|
142
|
-
input.call
|
143
|
-
end
|
144
|
-
digest = value.gibbler
|
145
|
-
@rsequential_offset ||= {}
|
146
|
-
@rsequential_offset[digest] ||= value.size-1 rescue 1
|
147
|
-
Stella.ld "RSEQVALUES: #{input} #{value.inspect} #{@rsequential_offset[digest]}"
|
148
|
-
if value.is_a?(Array)
|
149
|
-
size = value.size
|
150
|
-
@rsequential_offset[digest] = size-1 if @rsequential_offset[digest] < 0
|
151
|
-
value = value[ @rsequential_offset[digest] ]
|
152
|
-
@rsequential_offset[digest] -= 1
|
153
|
-
end
|
154
|
-
Stella.ld "SELECTED: #{value}"
|
155
|
-
@rsequential_value[input.digest] = value
|
156
|
-
end
|
157
|
-
|
158
|
-
# The resource may be an Array of Arrays (e.g. a CSV file)
|
159
|
-
if value.is_a?(Array) && !index.nil?
|
160
|
-
value = value[ index ]
|
161
|
-
Stella.ld "SELECTED INDEX: #{index} #{value.inspect} "
|
162
|
-
end
|
163
|
-
|
164
|
-
value
|
165
|
-
end
|
166
|
-
end
|
167
145
|
|
146
|
+
###
|
147
|
+
### Disabled b/c it doesn't work anymore since a
|
148
|
+
### new Container is created for every repetition.
|
149
|
+
###
|
150
|
+
##def sequential(*args)
|
151
|
+
## if Symbol === args.first
|
152
|
+
## input, index = *args
|
153
|
+
## elsif Array === args.first || args.size == 1
|
154
|
+
## input = args.first
|
155
|
+
## else
|
156
|
+
## input = args
|
157
|
+
## end
|
158
|
+
## Proc.new do
|
159
|
+
## if @sequential_value[input]
|
160
|
+
## value = @sequential_value[input]
|
161
|
+
## else
|
162
|
+
## value = case input.class.to_s
|
163
|
+
## when "Symbol"
|
164
|
+
## ret = resource(input)
|
165
|
+
## ret
|
166
|
+
## when "Array"
|
167
|
+
## input
|
168
|
+
## when "Range"
|
169
|
+
## input.to_a
|
170
|
+
## when "Proc"
|
171
|
+
## input.call
|
172
|
+
## end
|
173
|
+
## digest = value.object_id
|
174
|
+
## @sequential_offset ||= {}
|
175
|
+
## @sequential_offset[digest] ||= 0
|
176
|
+
## Stella.ld "SEQVALUES: #{@sequential_offset.object_id} #{value.inspect} #{@sequential_offset[digest]}"
|
177
|
+
## if value.is_a?(Array)
|
178
|
+
## size = value.size
|
179
|
+
## @sequential_offset[digest] = 0 if @sequential_offset[digest] >= size
|
180
|
+
## value = value[ @sequential_offset[digest] ]
|
181
|
+
## Stella.li "WHAY: #{value} (#{@sequential_offset[digest]})"
|
182
|
+
## @sequential_offset[digest] += 1
|
183
|
+
## end
|
184
|
+
## Stella.ld "SELECTED: #{value}"
|
185
|
+
## @sequential_value[input] = value
|
186
|
+
## end
|
187
|
+
## # The resource may be an Array of Arrays (e.g. a CSV file)
|
188
|
+
## if value.is_a?(Array) && !index.nil?
|
189
|
+
## value = value[ index ]
|
190
|
+
## Stella.ld "SELECTED INDEX: #{index} #{value.inspect} "
|
191
|
+
## end
|
192
|
+
## value
|
193
|
+
## end
|
194
|
+
##end
|
195
|
+
##
|
196
|
+
##def rsequential(*args)
|
197
|
+
## if Symbol === args.first
|
198
|
+
## input, index = *args
|
199
|
+
## elsif Array === args.first || args.size == 1
|
200
|
+
## input = args.first
|
201
|
+
## else
|
202
|
+
## input = args
|
203
|
+
## end
|
204
|
+
## Proc.new do
|
205
|
+
## if @rsequential_value[input.digest]
|
206
|
+
## value = @rsequential_value[input.digest]
|
207
|
+
## else
|
208
|
+
## value = case input.class.to_s
|
209
|
+
## when "Symbol"
|
210
|
+
## ret = resource(input)
|
211
|
+
## ret
|
212
|
+
## when "Array"
|
213
|
+
## input
|
214
|
+
## when "Range"
|
215
|
+
## input.to_a
|
216
|
+
## when "Proc"
|
217
|
+
## input.call
|
218
|
+
## end
|
219
|
+
## digest = value.object_id
|
220
|
+
## @rsequential_offset ||= {}
|
221
|
+
## Stella.ld "RSEQVALUES: #{input} #{value.inspect}"
|
222
|
+
## if value.is_a?(Array)
|
223
|
+
## size = value.size
|
224
|
+
## @rsequential_offset[digest] ||= size-1
|
225
|
+
## @rsequential_offset[digest] = size-1 if @rsequential_offset[digest] < 0
|
226
|
+
## value = value[ @rsequential_offset[digest] ]
|
227
|
+
## @rsequential_offset[digest] -= 1
|
228
|
+
## end
|
229
|
+
## Stella.ld "SELECTED: #{value}"
|
230
|
+
## @rsequential_value[input.digest] = value
|
231
|
+
## end
|
232
|
+
##
|
233
|
+
## # The resource may be an Array of Arrays (e.g. a CSV file)
|
234
|
+
## if value.is_a?(Array) && !index.nil?
|
235
|
+
## value = value[ index ]
|
236
|
+
## Stella.ld "SELECTED INDEX: #{index} #{value.inspect} "
|
237
|
+
## end
|
238
|
+
##
|
239
|
+
## value
|
240
|
+
## end
|
241
|
+
##end
|
242
|
+
|
243
|
+
|
244
|
+
|
245
|
+
# NOTE: This is global across all users
|
246
|
+
## TODO: Broken??
|
247
|
+
##def rsequential(*args)
|
248
|
+
## if Symbol === args.first
|
249
|
+
## input, index = *args
|
250
|
+
## elsif Array === args.first || args.size == 1
|
251
|
+
## input = args.first
|
252
|
+
## else
|
253
|
+
## input = args
|
254
|
+
## end
|
255
|
+
## Proc.new do
|
256
|
+
## if @rsequential_value[input.object_id]
|
257
|
+
## value = @rsequential_value[input.object_id]
|
258
|
+
## else
|
259
|
+
## value = case input.class.to_s
|
260
|
+
## when "Symbol"
|
261
|
+
## ret = resource(input)
|
262
|
+
## ret
|
263
|
+
## when "Array"
|
264
|
+
## input
|
265
|
+
## when "Range"
|
266
|
+
## input.to_a
|
267
|
+
## when "Proc"
|
268
|
+
## input.call
|
269
|
+
## end
|
270
|
+
## digest = value.object_id
|
271
|
+
## if value.is_a?(Array)
|
272
|
+
## index = Container.rsequential_offset(digest, value.size-1)
|
273
|
+
## value = value[ index ]
|
274
|
+
## end
|
275
|
+
## Stella.ld "SELECTED(RSEQ): #{value} #{index} #{input} #{digest}"
|
276
|
+
## # I think this needs to be updated for global_rsequential:
|
277
|
+
## @rsequential_value[input.object_id] = value
|
278
|
+
## end
|
279
|
+
##
|
280
|
+
## # The resource may be an Array of Arrays (e.g. a CSV file)
|
281
|
+
## if value.is_a?(Array) && !index.nil?
|
282
|
+
## value = value[ index ]
|
283
|
+
## Stella.ld "SELECTED INDEX: #{index} #{value.inspect} #{input} #{digest}"
|
284
|
+
## end
|
285
|
+
##
|
286
|
+
## value
|
287
|
+
## end
|
288
|
+
##end
|
168
289
|
end
|
169
290
|
|
170
291
|
end
|