ruote 2.1.5 → 2.1.6
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/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
|