ruote 2.1.5 → 2.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +7 -0
- data/Rakefile +3 -3
- data/TODO.txt +4 -0
- data/examples/barley.rb +390 -0
- data/lib/ruote/engine.rb +16 -2
- data/lib/ruote/exp/flowexpression.rb +13 -2
- data/lib/ruote/fei.rb +1 -1
- data/lib/ruote/part/block_participant.rb +4 -1
- data/lib/ruote/part/engine_participant.rb +19 -19
- data/lib/ruote/part/storage_participant.rb +2 -2
- data/lib/ruote/version.rb +28 -0
- data/lib/ruote/worker.rb +0 -2
- data/ruote.gemspec +5 -3
- data/test/functional/base.rb +2 -0
- data/test/functional/ct_0_concurrence.rb +2 -2
- data/test/functional/ft_14_re_apply.rb +108 -20
- data/test/functional/ft_20_storage_participant.rb +21 -1
- data/test/functional/ft_24_block_participants.rb +21 -7
- data/test/functional/test.rb +1 -1
- data/test/unit/{ut_17_storage.rb → storage.rb} +30 -0
- data/test/unit/storages.rb +7 -3
- data/test/unit/test.rb +2 -0
- metadata +5 -3
data/CHANGELOG.txt
CHANGED
@@ -2,6 +2,13 @@
|
|
2
2
|
= ruote - CHANGELOG.txt
|
3
3
|
|
4
4
|
|
5
|
+
== ruote - 2.1.6 released 2010/02/08
|
6
|
+
|
7
|
+
- welcoming ruote-dm (datamapper persistency)
|
8
|
+
- Engine#re_apply(fei, opts) where opts in [ :tree, :fields, :merge_in_fields ]
|
9
|
+
- fixed issue about StorageParticipant#update, thanks Torsten
|
10
|
+
|
11
|
+
|
5
12
|
== ruote - 2.1.5 released 2010/01/28
|
6
13
|
|
7
14
|
- fixed StorageParticipant a to b flow, fix by Torsten
|
data/Rakefile
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
|
2
|
+
require 'lib/ruote/version.rb'
|
3
|
+
|
2
4
|
require 'rubygems'
|
3
5
|
require 'rake'
|
4
6
|
|
5
|
-
$:.unshift( File.join(File.dirname(__FILE__), 'lib') )
|
6
|
-
require File.join(File.dirname(__FILE__), %w[ lib ruote worker.rb ])
|
7
7
|
|
8
8
|
begin
|
9
9
|
|
@@ -60,7 +60,7 @@ CLEAN.include('pkg', 'rdoc', 'work', 'logs')
|
|
60
60
|
task :default => [ :clean ]
|
61
61
|
|
62
62
|
desc 'Upload the documentation to rubyforge'
|
63
|
-
task :upload_rdoc => :
|
63
|
+
task :upload_rdoc => :yard do
|
64
64
|
sh %{
|
65
65
|
rsync -azv -e ssh \
|
66
66
|
ruote_rdoc \
|
data/TODO.txt
CHANGED
data/examples/barley.rb
ADDED
@@ -0,0 +1,390 @@
|
|
1
|
+
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2010, John Mettraux, jmettraux@gmail.com
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
# featured in
|
25
|
+
# http://jmettraux.wordpress.com/2010/01/29/barley/
|
26
|
+
|
27
|
+
|
28
|
+
require 'rubygems'
|
29
|
+
|
30
|
+
#
|
31
|
+
# the users
|
32
|
+
#
|
33
|
+
|
34
|
+
USERS = {
|
35
|
+
'_none_' => 'http://s.twimg.com/a/1264550348/images/default_profile_0_normal.png',
|
36
|
+
'john' => 'http://www.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f',
|
37
|
+
'kenneth' => 'http://www.gravatar.com/avatar/8e033d0007374b14f6c213ede64d470b',
|
38
|
+
'torsten' => 'http://www.gravatar.com/avatar/3fa5d7edd1f21da184964146e062c8da',
|
39
|
+
'postmodern' => 'http://a3.twimg.com/profile_images/261097869/postmodern_bigger.jpg',
|
40
|
+
'amedeo' => 'http://a1.twimg.com/profile_images/99817242/me_bigger.png',
|
41
|
+
'radlepunktde' => 'http://a1.twimg.com/profile_images/303265014/radlepunktde_bigger.jpg'
|
42
|
+
}
|
43
|
+
|
44
|
+
|
45
|
+
#
|
46
|
+
# the workflow engine
|
47
|
+
#
|
48
|
+
|
49
|
+
require 'ruote'
|
50
|
+
require 'ruote/part/storage_participant'
|
51
|
+
require 'ruote/storage/fs_storage'
|
52
|
+
|
53
|
+
ENGINE = Ruote::Engine.new(
|
54
|
+
Ruote::Worker.new(Ruote::FsStorage.new('ruote_data')))
|
55
|
+
|
56
|
+
|
57
|
+
#
|
58
|
+
# the workflow participants
|
59
|
+
#
|
60
|
+
|
61
|
+
ENGINE.register_participant('trace') do |workitem|
|
62
|
+
(workitem.fields['trace'] ||= []) << [
|
63
|
+
Time.now.strftime('%Y-%m-%d %H:%M:%S'),
|
64
|
+
workitem.fields['next'],
|
65
|
+
workitem.fields['task'] ]
|
66
|
+
end
|
67
|
+
|
68
|
+
ENGINE.register_participant('.+', Ruote::StorageParticipant)
|
69
|
+
|
70
|
+
PART = Ruote::StorageParticipant.new(ENGINE)
|
71
|
+
# a handy pointer into the workitems
|
72
|
+
|
73
|
+
|
74
|
+
#
|
75
|
+
# the (only) process definition
|
76
|
+
#
|
77
|
+
|
78
|
+
PDEF = Ruote.process_definition :name => 'barely' do
|
79
|
+
cursor do
|
80
|
+
trace
|
81
|
+
participant '${f:next}'
|
82
|
+
rewind :if => '${f:next}'
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
# web resources (thanks to Sinatra)
|
88
|
+
#
|
89
|
+
|
90
|
+
require 'cgi'
|
91
|
+
require 'sinatra'
|
92
|
+
require 'haml'
|
93
|
+
|
94
|
+
use_in_file_templates!
|
95
|
+
|
96
|
+
def h (s)
|
97
|
+
Rack::Utils.escape_html(s)
|
98
|
+
end
|
99
|
+
|
100
|
+
def sort (workitems)
|
101
|
+
workitems.sort! do |wi0, wi1|
|
102
|
+
(wi0.fields['last'] || '') <=> (wi1.fields['last'] || '')
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
set :haml, { :format => :html5 }
|
107
|
+
|
108
|
+
get '/' do
|
109
|
+
redirect '/work'
|
110
|
+
end
|
111
|
+
|
112
|
+
get '/work' do
|
113
|
+
|
114
|
+
@workitems = PART.all
|
115
|
+
sort(@workitems)
|
116
|
+
|
117
|
+
haml :work
|
118
|
+
end
|
119
|
+
|
120
|
+
get '/work/:thing' do
|
121
|
+
|
122
|
+
t = params[:thing]
|
123
|
+
|
124
|
+
@workitems = if USERS[t]
|
125
|
+
PART.by_participant(t)
|
126
|
+
else
|
127
|
+
PART.by_field('subject', t)
|
128
|
+
end
|
129
|
+
sort(@workitems)
|
130
|
+
|
131
|
+
haml :work
|
132
|
+
end
|
133
|
+
|
134
|
+
post '/new' do
|
135
|
+
|
136
|
+
if n = params['next']
|
137
|
+
wfid = ENGINE.launch(
|
138
|
+
PDEF,
|
139
|
+
'next' => n,
|
140
|
+
'subject' => params['subject'],
|
141
|
+
'task' => params['task'],
|
142
|
+
'last' => Ruote.now_to_utc_s)
|
143
|
+
end
|
144
|
+
|
145
|
+
sleep 0.5
|
146
|
+
|
147
|
+
redirect '/work'
|
148
|
+
end
|
149
|
+
|
150
|
+
post '/work' do
|
151
|
+
|
152
|
+
fei = params['fei']
|
153
|
+
fei = Ruote::FlowExpressionId.from_id(fei, ENGINE.context.engine_id)
|
154
|
+
|
155
|
+
workitem = PART[fei]
|
156
|
+
# fetch workitem from storage
|
157
|
+
|
158
|
+
if params['action'] == 'resume'
|
159
|
+
workitem.fields['next'] = params['next']
|
160
|
+
workitem.fields['task'] = params['task']
|
161
|
+
workitem.fields['last'] = Ruote.now_to_utc_s
|
162
|
+
PART.reply(workitem)
|
163
|
+
else # params['action'] == 'terminate'
|
164
|
+
workitem.fields.delete('next')
|
165
|
+
PART.reply(workitem)
|
166
|
+
end
|
167
|
+
|
168
|
+
sleep 0.5
|
169
|
+
|
170
|
+
redirect '/work'
|
171
|
+
end
|
172
|
+
|
173
|
+
__END__
|
174
|
+
|
175
|
+
@@work
|
176
|
+
|
177
|
+
%html
|
178
|
+
%head
|
179
|
+
%title barley
|
180
|
+
|
181
|
+
%script( src='http://code.jquery.com/jquery-1.4.1.min.js' )
|
182
|
+
|
183
|
+
%link( href='http://barley.s3.amazonaws.com/reset.css' type='text/css' rel='stylesheet' )
|
184
|
+
%link( href='http://ruote.rubyforge.org/images/ruote.png' type='image/png' rel='icon' )
|
185
|
+
|
186
|
+
%style
|
187
|
+
:sass
|
188
|
+
body
|
189
|
+
font-family: "helvetica neue", helvetica
|
190
|
+
font-size: 14pt
|
191
|
+
margin-left: 20%
|
192
|
+
margin-right: 20%
|
193
|
+
margin-top: 20pt
|
194
|
+
|
195
|
+
background: #C0DEED url('http://a3.twimg.com/a/1264550348/images/bg-clouds.png') repeat-x
|
196
|
+
p
|
197
|
+
margin-bottom: 5pt
|
198
|
+
input[type='text']
|
199
|
+
width: 100%
|
200
|
+
img
|
201
|
+
width: 38px
|
202
|
+
a
|
203
|
+
color: black
|
204
|
+
text-decoration: none
|
205
|
+
a:visited
|
206
|
+
color: black
|
207
|
+
text-decoration: none
|
208
|
+
a:active
|
209
|
+
color: black
|
210
|
+
text-decoration: none
|
211
|
+
#barley
|
212
|
+
font-size: 350%
|
213
|
+
font-weight: lighter
|
214
|
+
color: white
|
215
|
+
padding-left: 2pt
|
216
|
+
padding-bottom: 7pt
|
217
|
+
#buttons
|
218
|
+
font-size: 90%
|
219
|
+
color: white
|
220
|
+
margin-bottom: 14pt
|
221
|
+
#buttons a
|
222
|
+
color: white
|
223
|
+
#buttons a:visited
|
224
|
+
color: white
|
225
|
+
.workitem
|
226
|
+
margin-bottom: 7pt
|
227
|
+
.workitem > *
|
228
|
+
float: left
|
229
|
+
.workitem:after
|
230
|
+
display: block
|
231
|
+
clear: both
|
232
|
+
visibility: hidden
|
233
|
+
content: ''
|
234
|
+
.wi_info
|
235
|
+
margin-left: 3pt
|
236
|
+
.wi_user
|
237
|
+
font-weight: bold
|
238
|
+
.wi_task
|
239
|
+
opacity: 0.37
|
240
|
+
cursor: pointer
|
241
|
+
.wi_wfid
|
242
|
+
font-size: 70%
|
243
|
+
vertical-align: middle
|
244
|
+
font-weight: lighter
|
245
|
+
table
|
246
|
+
width: 100%
|
247
|
+
tr.buttons > td
|
248
|
+
text-align: center
|
249
|
+
padding-top: 4pt
|
250
|
+
td
|
251
|
+
vertical-align: middle
|
252
|
+
td.constrained
|
253
|
+
width: 1%
|
254
|
+
padding-right: 1em
|
255
|
+
td.label
|
256
|
+
font-weight: lighter
|
257
|
+
.trace
|
258
|
+
opacity: 0.37
|
259
|
+
margin-bottom: 4pt
|
260
|
+
cursor: pointer
|
261
|
+
.trace_detail
|
262
|
+
padding-left: 2pt
|
263
|
+
border-left: 2.5pt solid #8EC1DA
|
264
|
+
.trace_step
|
265
|
+
width: 100%
|
266
|
+
.trace_step_time
|
267
|
+
font-size: 70%
|
268
|
+
.trace_step_user
|
269
|
+
font-weight: bold
|
270
|
+
opacity: 0.6
|
271
|
+
.trace_step_task
|
272
|
+
opacity: 0.37
|
273
|
+
|
274
|
+
%body
|
275
|
+
|
276
|
+
#barley
|
277
|
+
%span{ :onclick => "document.location.href = '/work';", :style => 'cursor: pointer;' } barley
|
278
|
+
|
279
|
+
#message
|
280
|
+
#{@message}
|
281
|
+
|
282
|
+
#buttons
|
283
|
+
|
284
|
+
%a{ :href => '', :onclick => "$('#new_form').slideToggle(); $('#new_next').focus(); return false;" } new
|
285
|
+
|
|
286
|
+
%a{ :href => '/work' } all
|
287
|
+
|
288
|
+
#new_form{ :style => 'display: none;' }
|
289
|
+
%form{ :action => '/new', :method => 'POST' }
|
290
|
+
%table
|
291
|
+
%tr
|
292
|
+
%td.constrained{ :rowspan => 2 }
|
293
|
+
%select#new_next{ :name => 'next', :onchange => "this.options[selectedIndex].select();" }
|
294
|
+
- USERS.keys.sort.each do |uname|
|
295
|
+
- uavatar = USERS[uname]
|
296
|
+
%option{ :id => "new_#{uname}" } #{uname}
|
297
|
+
:javascript
|
298
|
+
document.getElementById('new_#{uname}').select = function () {
|
299
|
+
$('#new_avatar').get(0).src = '#{uavatar}';
|
300
|
+
$('#new_subject').focus();
|
301
|
+
}
|
302
|
+
:javascript
|
303
|
+
$('#new_next').get(0).value = '_none_';
|
304
|
+
%td.constrained{ :rowspan => 2 }
|
305
|
+
%img#new_avatar{ :src => USERS['_none_'] }
|
306
|
+
%td.constrained.label
|
307
|
+
subject
|
308
|
+
%td
|
309
|
+
%input{ :id => 'new_subject', :type => 'text', :name => 'subject', :value => '' }
|
310
|
+
%tr
|
311
|
+
%td.constrained.label
|
312
|
+
task
|
313
|
+
%td
|
314
|
+
%input{ :type => 'text', :name => 'task', :value => '' }
|
315
|
+
%tr.buttons
|
316
|
+
%td{ :colspan => 4 }
|
317
|
+
%input{ :type => 'submit', :value => 'launch' }
|
318
|
+
|
319
|
+
#work
|
320
|
+
- @workitems.each do |workitem|
|
321
|
+
|
322
|
+
- wid = "workitem#{workitem.fei.hash.to_s}"
|
323
|
+
|
324
|
+
.workitem
|
325
|
+
.wi_user_image
|
326
|
+
%img{ :src => USERS[workitem.participant_name], :class => 'wi_user' }
|
327
|
+
.wi_info
|
328
|
+
.wi_first_line
|
329
|
+
%span.wi_user
|
330
|
+
%a{ :href => "/work/#{h workitem.participant_name}" } #{h workitem.participant_name}
|
331
|
+
%span.wi_subject
|
332
|
+
%a{ :href => "/work/#{CGI.escape(workitem.fields['subject'])}" } #{h workitem.fields['subject']}
|
333
|
+
%span.wi_task{ :onclick => "$('##{wid}').slideToggle(); $('#next_#{wid}').focus();" }
|
334
|
+
#{h workitem.fields['task']}
|
335
|
+
.wi_second_line
|
336
|
+
%span.wi_wfid
|
337
|
+
#{workitem.fei.wfid}
|
338
|
+
- t = Rufus.to_ruby_time(workitem.fields['last'])
|
339
|
+
- ago = Rufus.to_duration_string(Time.now - t.to_time, :drop_seconds => true)
|
340
|
+
- ago = (ago.strip == '') ? 'a few seconds' : ago
|
341
|
+
(#{ago} ago)
|
342
|
+
|
343
|
+
.workitem_form{ :style => 'display: none;', :id => wid }
|
344
|
+
|
345
|
+
.trace{ :onclick => "$('#trace#{wid}').slideToggle();" }
|
346
|
+
- names = workitem.fields['trace'].collect { |e| e[1] }
|
347
|
+
#{names.join(' » ')}
|
348
|
+
|
349
|
+
.trace_detail{ :id => "trace#{wid}", :style => 'display: none;' }
|
350
|
+
- workitem.fields['trace'].each do |time, user, task|
|
351
|
+
- t = Rufus.to_ruby_time(time)
|
352
|
+
- ago = Rufus.to_duration_string(Time.now - t.to_time, :drop_seconds => true)
|
353
|
+
%p.trace_step
|
354
|
+
%span.trace_step_time #{h time} (#{ago} ago)
|
355
|
+
%span.trace_step_user #{h user}
|
356
|
+
%span.trace_step_task #{h task}
|
357
|
+
|
358
|
+
%form{ :action => '/work', :method => 'POST' }
|
359
|
+
%input{ :type => 'hidden', :name => 'fei', :value => workitem.fei.to_storage_id }
|
360
|
+
%table
|
361
|
+
%tr
|
362
|
+
%td.constrained{ :rowspan => 2 }
|
363
|
+
%select{ :id => "next_#{wid}", :name => 'next', :onchange => "this.options[selectedIndex].select();" }
|
364
|
+
- USERS.keys.sort.each do |uname|
|
365
|
+
- uavatar = USERS[uname]
|
366
|
+
%option{ :id => "#{uname}_#{wid}" } #{uname}
|
367
|
+
:javascript
|
368
|
+
document.getElementById('#{uname}_#{wid}').select = function () {
|
369
|
+
$('#avatar_#{wid}').get(0).src = '#{uavatar}';
|
370
|
+
$('#task_#{wid}').focus();
|
371
|
+
}
|
372
|
+
:javascript
|
373
|
+
$('#next_#{wid}').get(0).value = '#{workitem.participant_name}';
|
374
|
+
%td.constrained{ :rowspan => 2 }
|
375
|
+
%img{ :src => USERS[workitem.participant_name], :id => "avatar_#{wid}" }
|
376
|
+
%td.constrained.label
|
377
|
+
subject
|
378
|
+
%td
|
379
|
+
#{h workitem.fields['subject']}
|
380
|
+
%tr
|
381
|
+
%td.constrained.label
|
382
|
+
task
|
383
|
+
%td
|
384
|
+
%input{ :id => "task_#{wid}", :type => 'text', :name => 'task', :value => workitem.fields['task'] }
|
385
|
+
%tr.buttons
|
386
|
+
%td{ :colspan => 4 }
|
387
|
+
%input{ :type => 'submit', :name => 'action', :value => 'resume' }
|
388
|
+
or
|
389
|
+
%input{ :type => 'submit', :name => 'action', :value => 'terminate' }
|
390
|
+
|
data/lib/ruote/engine.rb
CHANGED
@@ -124,9 +124,23 @@ module Ruote
|
|
124
124
|
# (all the children have been cancelled), the expression will get
|
125
125
|
# re-applied.
|
126
126
|
#
|
127
|
-
|
127
|
+
# == options
|
128
|
+
#
|
129
|
+
# :tree is used to completely change the tree of the expression at re_apply
|
130
|
+
#
|
131
|
+
# engine.re_apply(fei, :tree => [ 'participant', { 'ref' => 'bob' }, [] ])
|
132
|
+
#
|
133
|
+
# :fields is used to replace the fields of the workitem at re_apply
|
134
|
+
#
|
135
|
+
# engine.re_apply(fei, :fields => { 'customer' => 'bob' })
|
136
|
+
#
|
137
|
+
# :merge_in_fields is used to add / override fields
|
138
|
+
#
|
139
|
+
# engine.re_apply(fei, :merge_in_fields => { 'customer' => 'bob' })
|
140
|
+
#
|
141
|
+
def re_apply (fei, opts={})
|
128
142
|
|
129
|
-
@context.storage.put_msg('cancel', 'fei' => fei.to_h, 're_apply' =>
|
143
|
+
@context.storage.put_msg('cancel', 'fei' => fei.to_h, 're_apply' => opts)
|
130
144
|
end
|
131
145
|
|
132
146
|
# Returns a ProcessStatus instance describing the current status of
|
@@ -318,10 +318,21 @@ module Ruote::Exp
|
|
318
318
|
] if h.state == 'timing_out'
|
319
319
|
|
320
320
|
if h.state == 'cancelling'
|
321
|
+
|
321
322
|
if t = msg['on_cancel']
|
323
|
+
|
322
324
|
h.on_cancel = t
|
323
|
-
|
324
|
-
|
325
|
+
|
326
|
+
elsif hra = msg['re_apply']
|
327
|
+
|
328
|
+
hra = {} if hra == true
|
329
|
+
h.on_cancel = hra['tree'] || tree
|
330
|
+
if fs = hra['fields']
|
331
|
+
h.applied_workitem['fields'] = fs
|
332
|
+
end
|
333
|
+
if mfs = hra['merge_in_fields']
|
334
|
+
h.applied_workitem['fields'].merge!(mfs)
|
335
|
+
end
|
325
336
|
end
|
326
337
|
end
|
327
338
|
|
data/lib/ruote/fei.rb
CHANGED
@@ -87,7 +87,10 @@ module Ruote
|
|
87
87
|
workitem, Ruote::Exp::FlowExpression.fetch(@context, workitem.h.fei))
|
88
88
|
end
|
89
89
|
|
90
|
-
|
90
|
+
if r != nil && r != workitem
|
91
|
+
#workitem.result = r
|
92
|
+
workitem.result = (Rufus::Json.dup(r) rescue nil)
|
93
|
+
end
|
91
94
|
|
92
95
|
reply_to_engine(workitem)
|
93
96
|
end
|
@@ -37,25 +37,25 @@ module Ruote
|
|
37
37
|
#
|
38
38
|
# For instance :
|
39
39
|
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
40
|
+
# engine0 =
|
41
|
+
# Ruote::Engine.new(
|
42
|
+
# Ruote::Worker.new(
|
43
|
+
# Ruote::FsStorage.new('work0', 'engine_id' => 'engine0')))
|
44
|
+
# engine1 =
|
45
|
+
# Ruote::Engine.new(
|
46
|
+
# Ruote::Worker.new(
|
47
|
+
# Ruote::FsStorage.new('work1', 'engine_id' => 'engine1')))
|
48
|
+
#
|
49
|
+
# engine0.register_participant('engine1',
|
50
|
+
# Ruote::EngineParticipant,
|
51
|
+
# 'storage_class' => Ruote::FsStorage,
|
52
|
+
# 'storage_path' => 'ruote/storage/fs_storage',
|
53
|
+
# 'storage_args' => 'work1')
|
54
|
+
# engine1.register_participant('engine0',
|
55
|
+
# Ruote::EngineParticipant,
|
56
|
+
# 'storage_class' => Ruote::FsStorage,
|
57
|
+
# 'storage_path' => 'ruote/storage/fs_storage',
|
58
|
+
# 'storage_args' => 'work0')
|
59
59
|
#
|
60
60
|
# In this example, two engines are created (note that their 'engine_id' is
|
61
61
|
# explicitely set (else it would default to 'engine')). Each engine is then
|
@@ -61,8 +61,6 @@ module Ruote
|
|
61
61
|
|
62
62
|
doc = workitem.to_h
|
63
63
|
|
64
|
-
doc.delete('_rev')
|
65
|
-
|
66
64
|
doc.merge!(
|
67
65
|
'type' => 'workitems',
|
68
66
|
'_id' => to_id(doc['fei']),
|
@@ -110,6 +108,8 @@ module Ruote
|
|
110
108
|
|
111
109
|
return reply(workitem) if r != nil
|
112
110
|
|
111
|
+
workitem.h.delete('_rev')
|
112
|
+
|
113
113
|
reply_to_engine(workitem)
|
114
114
|
end
|
115
115
|
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2005-2010, John Mettraux, jmettraux@gmail.com
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
#
|
22
|
+
# Made in Japan.
|
23
|
+
#++
|
24
|
+
|
25
|
+
module Ruote
|
26
|
+
VERSION = '2.1.6'
|
27
|
+
end
|
28
|
+
|
data/lib/ruote/worker.rb
CHANGED
data/ruote.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{ruote}
|
8
|
-
s.version = "2.1.
|
8
|
+
s.version = "2.1.6"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["John Mettraux", "Kenneth Kalmer"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-02-08}
|
13
13
|
s.description = %q{
|
14
14
|
ruote is an open source ruby workflow engine.
|
15
15
|
}
|
@@ -26,6 +26,7 @@ ruote is an open source ruby workflow engine.
|
|
26
26
|
"README.rdoc",
|
27
27
|
"Rakefile",
|
28
28
|
"TODO.txt",
|
29
|
+
"examples/barley.rb",
|
29
30
|
"examples/flickr_report.rb",
|
30
31
|
"examples/ruote_quickstart.rb",
|
31
32
|
"examples/web_first_page.rb",
|
@@ -113,6 +114,7 @@ ruote is an open source ruby workflow engine.
|
|
113
114
|
"lib/ruote/util/time.rb",
|
114
115
|
"lib/ruote/util/tree.rb",
|
115
116
|
"lib/ruote/util/treechecker.rb",
|
117
|
+
"lib/ruote/version.rb",
|
116
118
|
"lib/ruote/worker.rb",
|
117
119
|
"lib/ruote/workitem.rb",
|
118
120
|
"phil.txt",
|
@@ -214,6 +216,7 @@ ruote is an open source ruby workflow engine.
|
|
214
216
|
"test/pdef.xml",
|
215
217
|
"test/test.rb",
|
216
218
|
"test/test_helper.rb",
|
219
|
+
"test/unit/storage.rb",
|
217
220
|
"test/unit/storages.rb",
|
218
221
|
"test/unit/test.rb",
|
219
222
|
"test/unit/ut_0_ruby_parser.rb",
|
@@ -222,7 +225,6 @@ ruote is an open source ruby workflow engine.
|
|
222
225
|
"test/unit/ut_14_is_uri.rb",
|
223
226
|
"test/unit/ut_15_util.rb",
|
224
227
|
"test/unit/ut_16_parser.rb",
|
225
|
-
"test/unit/ut_17_storage.rb",
|
226
228
|
"test/unit/ut_18_engine.rb",
|
227
229
|
"test/unit/ut_1_fei.rb",
|
228
230
|
"test/unit/ut_2_wfidgen.rb",
|
data/test/functional/base.rb
CHANGED
@@ -50,9 +50,9 @@ class CtConcurrenceTest < Test::Unit::TestCase
|
|
50
50
|
msgs.each do |m|
|
51
51
|
|
52
52
|
fei = m['fei'] ?
|
53
|
-
Ruote::FlowExpressionId.
|
53
|
+
Ruote::FlowExpressionId.to_storage_id(m['fei']) : ''
|
54
54
|
wi_fei = m['workitem'] ?
|
55
|
-
Ruote::FlowExpressionId.
|
55
|
+
Ruote::FlowExpressionId.to_storage_id(m['workitem']['fei']) : ''
|
56
56
|
|
57
57
|
p [ m['action'], fei, wi_fei ]
|
58
58
|
end
|
@@ -13,20 +13,21 @@ require 'ruote/part/hash_participant'
|
|
13
13
|
class FtReApplyTest < Test::Unit::TestCase
|
14
14
|
include FunctionalBase
|
15
15
|
|
16
|
+
PDEF = Ruote.process_definition do
|
17
|
+
sequence do
|
18
|
+
alpha
|
19
|
+
echo 'done.'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
16
23
|
def test_re_apply
|
17
24
|
|
18
|
-
pdef = Ruote.process_definition do
|
19
|
-
sequence do
|
20
|
-
alpha
|
21
|
-
echo 'done.'
|
22
|
-
end
|
23
|
-
end
|
24
25
|
|
25
26
|
alpha = @engine.register_participant :alpha, Ruote::HashParticipant.new
|
26
27
|
|
27
28
|
#noisy
|
28
29
|
|
29
|
-
wfid = @engine.launch(
|
30
|
+
wfid = @engine.launch(PDEF)
|
30
31
|
wait_for(:alpha)
|
31
32
|
|
32
33
|
id0 = alpha.first.object_id
|
@@ -53,10 +54,75 @@ class FtReApplyTest < Test::Unit::TestCase
|
|
53
54
|
|
54
55
|
def test_cancel_and_re_apply
|
55
56
|
|
57
|
+
alpha = @engine.register_participant :alpha, Ruote::HashParticipant.new
|
58
|
+
|
59
|
+
#noisy
|
60
|
+
|
61
|
+
wfid = @engine.launch(PDEF)
|
62
|
+
wait_for(:alpha)
|
63
|
+
|
64
|
+
id0 = alpha.first.object_id
|
65
|
+
|
66
|
+
# ... flow stalled ...
|
67
|
+
|
68
|
+
ps = @engine.process(wfid)
|
69
|
+
|
70
|
+
stalled_exp = ps.expressions.find { |fexp| fexp.fei.expid == '0_0_0' }
|
71
|
+
|
72
|
+
@engine.re_apply(stalled_exp.fei)
|
73
|
+
|
74
|
+
wait_for(:alpha)
|
75
|
+
|
76
|
+
assert_equal 1, alpha.size
|
77
|
+
assert_not_equal id0, alpha.first.object_id
|
78
|
+
|
79
|
+
alpha.reply(alpha.first)
|
80
|
+
|
81
|
+
wait_for(wfid)
|
82
|
+
|
83
|
+
assert_equal 'done.', @tracer.to_s
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_update_expression_and_re_apply
|
87
|
+
|
88
|
+
alpha = @engine.register_participant :alpha, Ruote::HashParticipant.new
|
89
|
+
|
90
|
+
#noisy
|
91
|
+
|
92
|
+
wfid = @engine.launch(PDEF)
|
93
|
+
wait_for(:alpha)
|
94
|
+
|
95
|
+
id0 = alpha.first.object_id
|
96
|
+
|
97
|
+
# ... flow stalled ...
|
98
|
+
|
99
|
+
ps = @engine.process(wfid)
|
100
|
+
|
101
|
+
stalled_exp = ps.expressions.find { |fexp| fexp.fei.expid == '0_0_0' }
|
102
|
+
|
103
|
+
stalled_exp.update_tree([
|
104
|
+
'participant', { 'ref' => 'alpha', 'activity' => 'mow lawn' }, [] ])
|
105
|
+
stalled_exp.persist
|
106
|
+
|
107
|
+
@engine.re_apply(stalled_exp.fei)
|
108
|
+
|
109
|
+
wait_for(:alpha)
|
110
|
+
|
111
|
+
assert_equal 'mow lawn', alpha.first.fields['params']['activity']
|
112
|
+
|
113
|
+
alpha.reply(alpha.first)
|
114
|
+
|
115
|
+
wait_for(wfid)
|
116
|
+
|
117
|
+
assert_equal 'done.', @tracer.to_s
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_re_apply_with_new_workitem_fields
|
121
|
+
|
56
122
|
pdef = Ruote.process_definition do
|
57
123
|
sequence do
|
58
124
|
alpha
|
59
|
-
echo 'done.'
|
125
|
+
echo 'done for ${f:x}.'
|
60
126
|
end
|
61
127
|
end
|
62
128
|
|
@@ -75,7 +141,7 @@ class FtReApplyTest < Test::Unit::TestCase
|
|
75
141
|
|
76
142
|
stalled_exp = ps.expressions.find { |fexp| fexp.fei.expid == '0_0_0' }
|
77
143
|
|
78
|
-
@engine.re_apply(stalled_exp.fei)
|
144
|
+
@engine.re_apply(stalled_exp.fei, :fields => { 'x' => 'nada' })
|
79
145
|
|
80
146
|
wait_for(:alpha)
|
81
147
|
|
@@ -86,15 +152,15 @@ class FtReApplyTest < Test::Unit::TestCase
|
|
86
152
|
|
87
153
|
wait_for(wfid)
|
88
154
|
|
89
|
-
assert_equal 'done.', @tracer.to_s
|
155
|
+
assert_equal 'done for nada.', @tracer.to_s
|
90
156
|
end
|
91
157
|
|
92
|
-
def
|
158
|
+
def test_re_apply_with_merged_workitem_fields
|
93
159
|
|
94
160
|
pdef = Ruote.process_definition do
|
95
161
|
sequence do
|
96
162
|
alpha
|
97
|
-
echo 'done.'
|
163
|
+
echo 'done for ${f:x} and ${f:y}.'
|
98
164
|
end
|
99
165
|
end
|
100
166
|
|
@@ -102,7 +168,7 @@ class FtReApplyTest < Test::Unit::TestCase
|
|
102
168
|
|
103
169
|
#noisy
|
104
170
|
|
105
|
-
wfid = @engine.launch(pdef)
|
171
|
+
wfid = @engine.launch(pdef, { 'y' => 'nemo' })
|
106
172
|
wait_for(:alpha)
|
107
173
|
|
108
174
|
id0 = alpha.first.object_id
|
@@ -113,21 +179,43 @@ class FtReApplyTest < Test::Unit::TestCase
|
|
113
179
|
|
114
180
|
stalled_exp = ps.expressions.find { |fexp| fexp.fei.expid == '0_0_0' }
|
115
181
|
|
116
|
-
stalled_exp.
|
117
|
-
'participant', { 'ref' => 'alpha', 'activity' => 'mow lawn' }, [] ])
|
118
|
-
stalled_exp.persist
|
119
|
-
|
120
|
-
@engine.re_apply(stalled_exp.fei)
|
182
|
+
@engine.re_apply(stalled_exp.fei, :merge_in_fields => { 'x' => 'nada' })
|
121
183
|
|
122
184
|
wait_for(:alpha)
|
123
185
|
|
124
|
-
assert_equal
|
186
|
+
assert_equal 1, alpha.size
|
187
|
+
assert_not_equal id0, alpha.first.object_id
|
125
188
|
|
126
189
|
alpha.reply(alpha.first)
|
127
190
|
|
128
191
|
wait_for(wfid)
|
129
192
|
|
130
|
-
assert_equal 'done.', @tracer.to_s
|
193
|
+
assert_equal 'done for nada and nemo.', @tracer.to_s
|
194
|
+
end
|
195
|
+
|
196
|
+
def test_re_apply_with_new_tree
|
197
|
+
|
198
|
+
alpha = @engine.register_participant :alpha, Ruote::HashParticipant.new
|
199
|
+
|
200
|
+
#noisy
|
201
|
+
|
202
|
+
wfid = @engine.launch(PDEF)
|
203
|
+
wait_for(:alpha)
|
204
|
+
|
205
|
+
id0 = alpha.first.object_id
|
206
|
+
|
207
|
+
# ... flow stalled ...
|
208
|
+
|
209
|
+
ps = @engine.process(wfid)
|
210
|
+
|
211
|
+
stalled_exp = ps.expressions.find { |fexp| fexp.fei.expid == '0_0_0' }
|
212
|
+
|
213
|
+
@engine.re_apply(
|
214
|
+
stalled_exp.fei, :tree => [ 'echo', { 're_applied' => nil }, [] ])
|
215
|
+
|
216
|
+
wait_for(wfid)
|
217
|
+
|
218
|
+
assert_equal "re_applied\ndone.", @tracer.to_s
|
131
219
|
end
|
132
220
|
end
|
133
221
|
|
@@ -112,7 +112,7 @@ class FtStorageParticipantTest < Test::Unit::TestCase
|
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
115
|
-
def
|
115
|
+
def test_by_participant
|
116
116
|
|
117
117
|
@engine.register_participant :alpha, Ruote::StorageParticipant
|
118
118
|
@engine.register_participant :bravo, Ruote::StorageParticipant
|
@@ -125,6 +125,7 @@ class FtStorageParticipantTest < Test::Unit::TestCase
|
|
125
125
|
part.context = @engine.context
|
126
126
|
|
127
127
|
assert_equal 2, part.size
|
128
|
+
#part.by_participant('alpha').each { |wi| p wi }
|
128
129
|
assert_equal 1, part.by_participant('alpha').size
|
129
130
|
assert_equal 1, part.by_participant('bravo').size
|
130
131
|
end
|
@@ -235,5 +236,24 @@ class FtStorageParticipantTest < Test::Unit::TestCase
|
|
235
236
|
|
236
237
|
assert_nil @engine.process(wfid)
|
237
238
|
end
|
239
|
+
|
240
|
+
def test_update_workitem
|
241
|
+
|
242
|
+
@engine.register_participant 'alpha', Ruote::StorageParticipant
|
243
|
+
|
244
|
+
wfid = @engine.launch(Ruote.process_definition { alpha })
|
245
|
+
|
246
|
+
alpha = Ruote::StorageParticipant.new(@engine)
|
247
|
+
|
248
|
+
wait_for(:alpha)
|
249
|
+
|
250
|
+
wi = alpha.first
|
251
|
+
|
252
|
+
wi.fields['jidai'] = 'heian'
|
253
|
+
|
254
|
+
alpha.update(wi)
|
255
|
+
|
256
|
+
assert_equal 'heian', alpha.first.fields['jidai']
|
257
|
+
end
|
238
258
|
end
|
239
259
|
|
@@ -38,22 +38,36 @@ class FtBlockParticipantTest < Test::Unit::TestCase
|
|
38
38
|
assert_trace pdef, "a\nb:f0:f0val\nc:f0:f0val:v0val"
|
39
39
|
end
|
40
40
|
|
41
|
+
TEST_BLOCK = Ruote.process_definition do
|
42
|
+
sequence do
|
43
|
+
alpha
|
44
|
+
echo '${f:__result__}'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
41
48
|
def test_block_result
|
42
49
|
|
43
|
-
|
44
|
-
|
45
|
-
alpha
|
46
|
-
echo '${f:__result__}'
|
47
|
-
end
|
50
|
+
@engine.register_participant :alpha do |workitem|
|
51
|
+
'seen'
|
48
52
|
end
|
49
53
|
|
54
|
+
#noisy
|
55
|
+
|
56
|
+
assert_trace TEST_BLOCK, 'seen'
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_non_jsonfiable_result
|
60
|
+
|
61
|
+
t = Time.now
|
62
|
+
|
50
63
|
@engine.register_participant :alpha do |workitem|
|
51
|
-
|
64
|
+
t
|
52
65
|
end
|
53
66
|
|
54
67
|
#noisy
|
55
68
|
|
56
|
-
assert_trace
|
69
|
+
#assert_trace TEST_BLOCK, Ruote.time_to_utc_s(t)
|
70
|
+
assert_trace TEST_BLOCK, defined?(DataMapper) ? '' : t.to_s
|
57
71
|
end
|
58
72
|
end
|
59
73
|
|
data/test/functional/test.rb
CHANGED
@@ -61,6 +61,7 @@ class UtStorage < Test::Unit::TestCase
|
|
61
61
|
h = @s.get('dogfood', 'nada')
|
62
62
|
|
63
63
|
assert_not_nil h['_rev']
|
64
|
+
assert_not_nil h['put_at']
|
64
65
|
end
|
65
66
|
|
66
67
|
def test_put_fail
|
@@ -80,6 +81,24 @@ class UtStorage < Test::Unit::TestCase
|
|
80
81
|
assert_not_nil doc['_rev']
|
81
82
|
end
|
82
83
|
|
84
|
+
def test_put_put_and_put
|
85
|
+
|
86
|
+
doc = { '_id' => 'whiskas', 'type' => 'dogfood', 'message' => 'miam' }
|
87
|
+
|
88
|
+
r = @s.put(doc)
|
89
|
+
doc = @s.get('dogfood', 'whiskas')
|
90
|
+
|
91
|
+
r = @s.put(doc)
|
92
|
+
assert_nil r
|
93
|
+
|
94
|
+
doc = @s.get('dogfood', 'whiskas')
|
95
|
+
|
96
|
+
assert_not_nil doc['put_at']
|
97
|
+
|
98
|
+
r = @s.put(doc)
|
99
|
+
assert_nil r
|
100
|
+
end
|
101
|
+
|
83
102
|
def test_delete_fail
|
84
103
|
|
85
104
|
assert_raise(ArgumentError) do
|
@@ -150,5 +169,16 @@ class UtStorage < Test::Unit::TestCase
|
|
150
169
|
|
151
170
|
assert_equal %w[ estereo nada ouinouin toto ], @s.ids('dogfood')
|
152
171
|
end
|
172
|
+
|
173
|
+
def test_get_many
|
174
|
+
|
175
|
+
30.times do |i|
|
176
|
+
@s.put('_id' => "xx!#{i}", 'type' => 'dogfood', 'msg' => "whatever #{i}")
|
177
|
+
end
|
178
|
+
|
179
|
+
assert_equal 31, @s.get_many('dogfood').size
|
180
|
+
assert_equal 10, @s.get_many('dogfood', nil, :limit => 10).size
|
181
|
+
assert_equal 1, @s.get_many('dogfood', /!7$/).size
|
182
|
+
end
|
153
183
|
end
|
154
184
|
|
data/test/unit/storages.rb
CHANGED
@@ -1,13 +1,17 @@
|
|
1
1
|
|
2
2
|
puts "\n\n\n== in memory"
|
3
3
|
puts
|
4
|
-
puts `ruby test/unit/
|
4
|
+
puts `ruby test/unit/storage.rb`
|
5
5
|
|
6
6
|
puts "\n\n\n== fs_storage"
|
7
7
|
puts
|
8
|
-
puts `ruby test/unit/
|
8
|
+
puts `ruby test/unit/storage.rb --fs`
|
9
9
|
|
10
10
|
puts "\n\n\n== couch_storage"
|
11
11
|
puts
|
12
|
-
puts `ruby -r patron -r yajl test/unit/
|
12
|
+
puts `ruby -r patron -r yajl test/unit/storage.rb --couch`
|
13
|
+
|
14
|
+
puts "\n\n\n== dm_storage"
|
15
|
+
puts
|
16
|
+
puts `ruby -r yajl test/unit/storage.rb --dm`
|
13
17
|
|
data/test/unit/test.rb
CHANGED
@@ -5,6 +5,8 @@
|
|
5
5
|
# since Mon Oct 9 22:19:44 JST 2006
|
6
6
|
#
|
7
7
|
|
8
|
+
load File.join(File.dirname(__FILE__), 'storage.rb')
|
9
|
+
|
8
10
|
Dir.glob(File.join(File.dirname(__FILE__), 'ut_*.rb')).sort.each { |t| load(t) }
|
9
11
|
Dir.glob(File.join(File.dirname(__FILE__), 'hut_*.rb')).sort.each { |t| load(t) }
|
10
12
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruote
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Mettraux
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2010-
|
13
|
+
date: 2010-02-08 00:00:00 +09:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -141,6 +141,7 @@ files:
|
|
141
141
|
- README.rdoc
|
142
142
|
- Rakefile
|
143
143
|
- TODO.txt
|
144
|
+
- examples/barley.rb
|
144
145
|
- examples/flickr_report.rb
|
145
146
|
- examples/ruote_quickstart.rb
|
146
147
|
- examples/web_first_page.rb
|
@@ -228,6 +229,7 @@ files:
|
|
228
229
|
- lib/ruote/util/time.rb
|
229
230
|
- lib/ruote/util/tree.rb
|
230
231
|
- lib/ruote/util/treechecker.rb
|
232
|
+
- lib/ruote/version.rb
|
231
233
|
- lib/ruote/worker.rb
|
232
234
|
- lib/ruote/workitem.rb
|
233
235
|
- phil.txt
|
@@ -329,6 +331,7 @@ files:
|
|
329
331
|
- test/pdef.xml
|
330
332
|
- test/test.rb
|
331
333
|
- test/test_helper.rb
|
334
|
+
- test/unit/storage.rb
|
332
335
|
- test/unit/storages.rb
|
333
336
|
- test/unit/test.rb
|
334
337
|
- test/unit/ut_0_ruby_parser.rb
|
@@ -337,7 +340,6 @@ files:
|
|
337
340
|
- test/unit/ut_14_is_uri.rb
|
338
341
|
- test/unit/ut_15_util.rb
|
339
342
|
- test/unit/ut_16_parser.rb
|
340
|
-
- test/unit/ut_17_storage.rb
|
341
343
|
- test/unit/ut_18_engine.rb
|
342
344
|
- test/unit/ut_1_fei.rb
|
343
345
|
- test/unit/ut_2_wfidgen.rb
|