vcs 0.1 → 0.2.148
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/Rakefile +17 -3
- data/bin/vcs +57 -34
- data/doc/jamis.rb +564 -0
- data/ruby_ex/abstract.rb +254 -0
- data/ruby_ex/abstract_node.rb +85 -0
- data/ruby_ex/algorithms/simulated_annealing.rb +140 -0
- data/ruby_ex/array_each_pair.rb +18 -0
- data/ruby_ex/ask.rb +101 -0
- data/ruby_ex/attributed_class.rb +302 -0
- data/ruby_ex/cache.rb +373 -0
- data/ruby_ex/checkout.rb +12 -0
- data/ruby_ex/choose.rb +271 -0
- data/ruby_ex/commands.rb +18 -0
- data/ruby_ex/commands/command.rb +401 -0
- data/ruby_ex/commands/datas.rb +16 -0
- data/ruby_ex/commands/datas/data.rb +33 -0
- data/ruby_ex/commands/datas/factory.rb +66 -0
- data/ruby_ex/commands/factory.rb +66 -0
- data/ruby_ex/commands/helpers.rb +67 -0
- data/ruby_ex/commands/pipe.rb +64 -0
- data/ruby_ex/commands/runners.rb +17 -0
- data/ruby_ex/commands/runners/exec.rb +49 -0
- data/ruby_ex/commands/runners/fork.rb +97 -0
- data/ruby_ex/commands/runners/runner.rb +107 -0
- data/ruby_ex/commands/seq.rb +27 -0
- data/ruby_ex/config_file.rb +96 -0
- data/ruby_ex/const_regexp.rb +59 -0
- data/ruby_ex/daemon.rb +134 -0
- data/ruby_ex/diff.rb +667 -0
- data/ruby_ex/dlogger.rb +62 -0
- data/ruby_ex/drb/dispatcher.rb +252 -0
- data/ruby_ex/drb/dispatcher_server_test.rb +29 -0
- data/ruby_ex/drb/drb_observable.rb +97 -0
- data/ruby_ex/drb/drb_observable_pool.rb +27 -0
- data/ruby_ex/drb/drb_service.rb +43 -0
- data/ruby_ex/drb/drb_undumped_attributes.rb +55 -0
- data/ruby_ex/drb/drb_undumped_indexed_object.rb +54 -0
- data/ruby_ex/drb/insecure_protected_methods.rb +103 -0
- data/ruby_ex/drb/session_client_test.rb +40 -0
- data/ruby_ex/drb/session_manager.rb +246 -0
- data/ruby_ex/drb/session_server.rb +53 -0
- data/ruby_ex/dtime.rb +143 -0
- data/ruby_ex/dumpable_proc.rb +63 -0
- data/ruby_ex/exception.rb +32 -0
- data/ruby_ex/filetype.rb +229 -0
- data/ruby_ex/fileutils_ex.rb +44 -0
- data/ruby_ex/fold.rb +58 -0
- data/ruby_ex/generate_id.rb +44 -0
- data/ruby_ex/hookable.rb +262 -0
- data/ruby_ex/hooker.rb +54 -0
- data/ruby_ex/inactive_timeout.rb +137 -0
- data/ruby_ex/indexed_node.rb +66 -0
- data/ruby_ex/io_marshal.rb +100 -0
- data/ruby_ex/ioo.rb +194 -0
- data/ruby_ex/labeled_node.rb +63 -0
- data/ruby_ex/logger_observer.rb +23 -0
- data/ruby_ex/md5sum.rb +66 -0
- data/ruby_ex/mktemp.rb +208 -0
- data/ruby_ex/module/attr_once.rb +36 -0
- data/ruby_ex/module/autoload_tree.rb +75 -0
- data/ruby_ex/module/hierarchy.rb +335 -0
- data/ruby_ex/module/instance_method_visibility.rb +73 -0
- data/ruby_ex/module_ex.rb +11 -0
- data/ruby_ex/node.rb +80 -0
- data/ruby_ex/object_monitor.rb +145 -0
- data/ruby_ex/object_monitor_activity.rb +33 -0
- data/ruby_ex/observable.rb +140 -0
- data/ruby_ex/observable_pool.rb +293 -0
- data/ruby_ex/orderedhash.rb +252 -0
- data/ruby_ex/pathname_ex.rb +152 -0
- data/ruby_ex/pp_hierarchy.rb +29 -0
- data/ruby_ex/pseudo_cache.rb +190 -0
- data/ruby_ex/queue.rb +56 -0
- data/ruby_ex/random_generators.rb +25 -0
- data/ruby_ex/random_generators/random_generator.rb +31 -0
- data/ruby_ex/random_generators/ruby.rb +23 -0
- data/ruby_ex/safe_eval.rb +348 -0
- data/ruby_ex/sendmail.rb +215 -0
- data/ruby_ex/service_manager.rb +121 -0
- data/ruby_ex/session/administrable.rb +120 -0
- data/ruby_ex/session/client.rb +153 -0
- data/ruby_ex/session/const.rb +18 -0
- data/ruby_ex/session/dispatcher.rb +184 -0
- data/ruby_ex/session/error.rb +21 -0
- data/ruby_ex/session/fetchable.rb +57 -0
- data/ruby_ex/session/fetcher.rb +62 -0
- data/ruby_ex/session/hookable.rb +26 -0
- data/ruby_ex/session/profile.rb +110 -0
- data/ruby_ex/session/server.rb +582 -0
- data/ruby_ex/session/test/administrable_test.rb +337 -0
- data/ruby_ex/session/test/basic_test.rb +523 -0
- data/ruby_ex/session/test/dispatcher_test.rb +409 -0
- data/ruby_ex/session/test/fetchable_test.rb +119 -0
- data/ruby_ex/session/test/sub_server_test.rb +188 -0
- data/ruby_ex/shuffle.rb +30 -0
- data/ruby_ex/spring.rb +136 -0
- data/ruby_ex/spring_set.rb +137 -0
- data/ruby_ex/string_ex.rb +28 -0
- data/ruby_ex/symtbl.rb +106 -0
- data/ruby_ex/synflow.rb +474 -0
- data/ruby_ex/test/unit/ui/yaml/testrunner.rb +164 -0
- data/ruby_ex/thread_mutex.rb +10 -0
- data/ruby_ex/timeout_ex.rb +81 -0
- data/ruby_ex/top_down.rb +73 -0
- data/ruby_ex/trace.rb +26 -0
- data/ruby_ex/uri/druby.rb +81 -0
- data/ruby_ex/uri/file.rb +65 -0
- data/ruby_ex/uri/ftp_ex.rb +37 -0
- data/ruby_ex/uri/http_ex.rb +43 -0
- data/ruby_ex/uri/ssh.rb +92 -0
- data/ruby_ex/uri/svn.rb +118 -0
- data/ruby_ex/uri_ex.rb +45 -0
- data/ruby_ex/verbose_object.rb +30 -0
- data/ruby_ex/version.rb +66 -0
- data/ruby_ex/yaml/basenode_ext.rb +63 -0
- data/ruby_ex/yaml/chop_header.rb +23 -0
- data/ruby_ex/yaml/transform.rb +449 -0
- data/ruby_ex/yaml/yregexpath.rb +76 -0
- data/src/changelog.rb +28 -18
- data/src/conflict.rb +20 -0
- data/src/diff.rb +18 -0
- data/src/diffstat.rb +9 -3
- data/src/last_changed_date.rb +18 -0
- data/src/mail.rb +33 -65
- data/src/message.rb +15 -9
- data/src/mycommit.rb +29 -14
- data/src/news.rb +24 -3
- data/src/status.rb +17 -0
- data/src/svn.rb +2 -2
- data/src/vcs.rb +24 -3
- metadata +124 -5
- data/lrdetools.rb +0 -12
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Author:: Nicolas Pouillard <ertai@lrde.epita.fr>.
|
|
2
|
+
# Copyright:: Copyright (c) 2004, 2005 Nicolas Pouillard. All rights reserved.
|
|
3
|
+
# License:: GNU General Public License (GPL).
|
|
4
|
+
# Revision:: $Id$
|
|
5
|
+
|
|
6
|
+
class String
|
|
7
|
+
|
|
8
|
+
#
|
|
9
|
+
# Provide an helper to cut strings.
|
|
10
|
+
#
|
|
11
|
+
# Example:
|
|
12
|
+
#
|
|
13
|
+
# puts "
|
|
14
|
+
# | A very complex
|
|
15
|
+
# | string
|
|
16
|
+
# | with a specific indentation.
|
|
17
|
+
# |
|
|
18
|
+
# |I prefer that instead of a HERE doc
|
|
19
|
+
# | because I keep my indentation.
|
|
20
|
+
# |".head_cut!
|
|
21
|
+
#
|
|
22
|
+
def head_cut! ( sep='\|' )
|
|
23
|
+
gsub!(/^\s*#{sep}/, '')
|
|
24
|
+
self
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end # class String
|
|
28
|
+
|
data/ruby_ex/symtbl.rb
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Author: Nicolas Pouillard <ertai@lrde.epita.fr>.
|
|
2
|
+
# Copyright: Copyright (c) 2004 Nicolas Pouillard. All rights reserved.
|
|
3
|
+
# License: Ruby license.
|
|
4
|
+
|
|
5
|
+
# $LastChangedBy: ertai $
|
|
6
|
+
# $Id: symtbl.rb 189 2005-04-03 00:33:40Z ertai $
|
|
7
|
+
|
|
8
|
+
require 'set'
|
|
9
|
+
|
|
10
|
+
class SymTbl
|
|
11
|
+
|
|
12
|
+
@@sid = -1
|
|
13
|
+
|
|
14
|
+
attr_reader :sid, :local, :father
|
|
15
|
+
|
|
16
|
+
def initialize ( father_env=nil, default=nil )
|
|
17
|
+
@father = father_env
|
|
18
|
+
@sid = (@@sid += 1)
|
|
19
|
+
@local = Hash.new(default)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def [] ( aKey )
|
|
23
|
+
if @local.has_key? aKey
|
|
24
|
+
@local[aKey]
|
|
25
|
+
elsif @father.nil?
|
|
26
|
+
@local.default
|
|
27
|
+
else
|
|
28
|
+
@father[aKey]
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def []= ( aKey, aValue )
|
|
33
|
+
@local[aKey] = aValue
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# FIXME
|
|
37
|
+
def each ( &block )
|
|
38
|
+
key_set = Set.new
|
|
39
|
+
blk = lambda do |k,v|
|
|
40
|
+
block[k, v] unless key_set.include? k
|
|
41
|
+
key_set << k
|
|
42
|
+
end
|
|
43
|
+
@local.each(&blk)
|
|
44
|
+
@father.each(&blk) unless @father.nil?
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def ancestors
|
|
48
|
+
(@father.is_a?(SymTbl))? [self] + @father.ancestors : [self]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def desc_one
|
|
52
|
+
if defined? @already_described
|
|
53
|
+
return sid
|
|
54
|
+
else
|
|
55
|
+
@already_described = true
|
|
56
|
+
return { sid => @local }
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def desc
|
|
61
|
+
ancestors.map{ |s| s.desc_one }.to_yaml
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
end # class SymTbl
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
if defined? TEST_MODE or __FILE__ == $0
|
|
69
|
+
|
|
70
|
+
require 'test/unit'
|
|
71
|
+
class SymTblTest < Test::Unit::TestCase
|
|
72
|
+
|
|
73
|
+
def test1
|
|
74
|
+
root = SymTbl.new
|
|
75
|
+
|
|
76
|
+
root[:a] = 0
|
|
77
|
+
root[:b] = 1
|
|
78
|
+
|
|
79
|
+
assert_equal(1, root[:b], 't1')
|
|
80
|
+
assert_equal(0, root[:a], 't2')
|
|
81
|
+
|
|
82
|
+
sub1 = SymTbl.new(root)
|
|
83
|
+
|
|
84
|
+
sub1[:a] = 2
|
|
85
|
+
sub1[:c] = 3
|
|
86
|
+
|
|
87
|
+
assert_equal(1, sub1[:b], 't3')
|
|
88
|
+
assert_equal(2, sub1[:a], 't4')
|
|
89
|
+
assert_equal(3, sub1[:c], 't5')
|
|
90
|
+
|
|
91
|
+
assert_equal(0, root[:a], 't6')
|
|
92
|
+
|
|
93
|
+
sub2 = SymTbl.new(sub1)
|
|
94
|
+
|
|
95
|
+
assert_equal(2, sub2[:a], 't7')
|
|
96
|
+
|
|
97
|
+
sub2[:a] = 42
|
|
98
|
+
|
|
99
|
+
assert_equal(42, sub2[:a], 't8')
|
|
100
|
+
|
|
101
|
+
assert_equal([], sub2.desc)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
end # class SymTblTest
|
|
105
|
+
|
|
106
|
+
end
|
data/ruby_ex/synflow.rb
ADDED
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
# Copyright: Copyright (c) 2004 Nicolas Pouillard. All rights reserved.
|
|
2
|
+
# Author: Nicolas Pouillard <ertai@lrde.epita.fr>.
|
|
3
|
+
# License: Gnu General Public License.
|
|
4
|
+
|
|
5
|
+
# $LastChangedBy$
|
|
6
|
+
# $Id$
|
|
7
|
+
|
|
8
|
+
#
|
|
9
|
+
# Efficients control flows for synchronisation (and mutual exclusion) in
|
|
10
|
+
# parallel systems.
|
|
11
|
+
#
|
|
12
|
+
|
|
13
|
+
require 'thread'
|
|
14
|
+
require 'set'
|
|
15
|
+
|
|
16
|
+
#
|
|
17
|
+
# The +SynFlowFactory+ define the common part for a set of flows.
|
|
18
|
+
#
|
|
19
|
+
# A SynFlow is like an automaton (finite state machine):
|
|
20
|
+
# * states
|
|
21
|
+
# * transitions
|
|
22
|
+
# * an alphabet
|
|
23
|
+
# * an initial state
|
|
24
|
+
# * a set of final states
|
|
25
|
+
#
|
|
26
|
+
# With this automaton (diagram, graph...) you can easily describe important
|
|
27
|
+
# steps of your program control flow.
|
|
28
|
+
#
|
|
29
|
+
# Your automaton describe a model of execution and constraint every execution
|
|
30
|
+
# to it.
|
|
31
|
+
#
|
|
32
|
+
# When a thread want to change the state of its flow it proceed like that:
|
|
33
|
+
# flow << :a_symbol_of_the_alphabet
|
|
34
|
+
#
|
|
35
|
+
# If a transition between the _current_ state and a state _destination_ is
|
|
36
|
+
# labeled by _symbol_, then the state is updated to _destination_.
|
|
37
|
+
# Otherwise the thread is constraint to wait the modification of the _current_
|
|
38
|
+
# state.
|
|
39
|
+
#
|
|
40
|
+
# See examples below to know how to use these class.
|
|
41
|
+
#
|
|
42
|
+
class SynFlowFactory
|
|
43
|
+
|
|
44
|
+
class Transition
|
|
45
|
+
attr_reader :src, :dest, :label
|
|
46
|
+
|
|
47
|
+
def initialize ( src, label, dest )
|
|
48
|
+
@src, @label, @dest = src, label, dest
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def to_a
|
|
52
|
+
[@src, @label, @dest]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def == ( rhs )
|
|
56
|
+
rhs.is_a? self.class and
|
|
57
|
+
@label == rhs.label and
|
|
58
|
+
@dest == rhs.dest and
|
|
59
|
+
@src == rhs.src
|
|
60
|
+
end
|
|
61
|
+
end # class Transition
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class TransitionSet
|
|
65
|
+
|
|
66
|
+
def initialize
|
|
67
|
+
@val = {}
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def include? ( *a )
|
|
71
|
+
case a.size
|
|
72
|
+
when 1
|
|
73
|
+
t = a[0]
|
|
74
|
+
case t
|
|
75
|
+
when Array
|
|
76
|
+
return include?(*t)
|
|
77
|
+
else
|
|
78
|
+
return delta(t.src, t.label) == t.dest
|
|
79
|
+
end
|
|
80
|
+
when 2
|
|
81
|
+
state, label = a
|
|
82
|
+
return ! delta(state, label).nil?
|
|
83
|
+
when 3
|
|
84
|
+
state, label, dest = a
|
|
85
|
+
return delta(state, label) == dest
|
|
86
|
+
else
|
|
87
|
+
raise ArgumentError, 'bad transition'
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def add ( src, label, dest )
|
|
92
|
+
@val[src] ||= {}
|
|
93
|
+
@val[src][label] = dest
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def add_transition ( t )
|
|
97
|
+
add(t.src, t.label, t.dest)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def delta ( src, label )
|
|
101
|
+
@val[src] ||= {}
|
|
102
|
+
@val[src][label]
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def << ( transition )
|
|
106
|
+
case transition
|
|
107
|
+
when Array
|
|
108
|
+
add(*transition)
|
|
109
|
+
when Hash
|
|
110
|
+
transition.each do |src, x|
|
|
111
|
+
unless x.is_a? Hash
|
|
112
|
+
raise TypeError, "bad transtion: #{transition.inspect}"
|
|
113
|
+
end
|
|
114
|
+
x.each do |label, dest|
|
|
115
|
+
add(src, label, dest)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
when Transition
|
|
119
|
+
add_transition(transition)
|
|
120
|
+
else
|
|
121
|
+
raise TypeError, "bad transtion: #{transition.inspect}"
|
|
122
|
+
end
|
|
123
|
+
self
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
end # class TransitionSet
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
attr_accessor :initial, :transitions
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def initialize
|
|
133
|
+
@transitions = TransitionSet.new
|
|
134
|
+
@initial = nil
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def << ( transition )
|
|
139
|
+
@transitions << transition
|
|
140
|
+
self
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def include? ( *transition )
|
|
145
|
+
@transitions.include?(*transition)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def delta ( src, label )
|
|
150
|
+
@transitions.delta(src, label)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def new_flow
|
|
155
|
+
SynFlow.new(self, @initial)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def initial? ( state )
|
|
160
|
+
state == @initial
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
end # class SynFlowFactory
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class SynFlow
|
|
167
|
+
|
|
168
|
+
class Error < Exception
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
attr_reader :state
|
|
172
|
+
attr_reader :i
|
|
173
|
+
|
|
174
|
+
@@i = -1
|
|
175
|
+
def initialize ( factory, initial_state )
|
|
176
|
+
@i = (@@i += 1)
|
|
177
|
+
super()
|
|
178
|
+
@mutex = Mutex.new
|
|
179
|
+
@condition = ConditionVariable.new
|
|
180
|
+
@factory = factory
|
|
181
|
+
@state = initial_state
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def feed ( label )
|
|
186
|
+
D "#@i: Want read label #{label} (#@state)"
|
|
187
|
+
@mutex.synchronize do
|
|
188
|
+
while not @factory.include?(@state, label)
|
|
189
|
+
begin
|
|
190
|
+
@condition.wait(@mutex)
|
|
191
|
+
rescue ThreadError
|
|
192
|
+
raise Error,
|
|
193
|
+
'Cannot wait for change state because only one thread is running'
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
dest = @factory.delta(@state, label)
|
|
197
|
+
D "#@i: Ok change state with label #{label} (#@state -> #{dest})"
|
|
198
|
+
@state = dest
|
|
199
|
+
@condition.broadcast
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
alias advance feed
|
|
204
|
+
alias << feed
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def try_feed ( label )
|
|
208
|
+
D "#@i: Try read label #{label} (#@state)"
|
|
209
|
+
if @mutex.try_lock
|
|
210
|
+
begin
|
|
211
|
+
if @factory.include?(@state, label)
|
|
212
|
+
dest = @factory.delta(@state, label)
|
|
213
|
+
D "#@i: Ok change state with label #{label} (#@state -> #{dest})"
|
|
214
|
+
@state = dest
|
|
215
|
+
@condition.broadcast
|
|
216
|
+
return true
|
|
217
|
+
end
|
|
218
|
+
ensure
|
|
219
|
+
@mutex.unlock
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
D "#@i: Ko you cannot change state"
|
|
223
|
+
return false
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
alias try_advance try_feed
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def destroy
|
|
230
|
+
@i = @mutex = @condition = @factory = @state = nil
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
@@out = []
|
|
235
|
+
|
|
236
|
+
def self.debug_out
|
|
237
|
+
@@out
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def D ( msg )
|
|
241
|
+
# @@out << msg
|
|
242
|
+
# STDERR.puts msg
|
|
243
|
+
end
|
|
244
|
+
private :D
|
|
245
|
+
|
|
246
|
+
end # class SynFlow
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
if $0 == __FILE__
|
|
251
|
+
|
|
252
|
+
require 'test/unit'
|
|
253
|
+
require 'timeout'
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
class SynFlowTest < Test::Unit::TestCase
|
|
257
|
+
|
|
258
|
+
T = SynFlowFactory::Transition
|
|
259
|
+
TSet = SynFlowFactory::TransitionSet
|
|
260
|
+
|
|
261
|
+
def test_aa_simple_transition
|
|
262
|
+
assert_equal(T.new(:a, :b, :c), T.new(:a, :b, :c))
|
|
263
|
+
assert_not_equal(T.new(:b, :a, :c), T.new(:a, :b, :d))
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def test_ab_simple_transition_set
|
|
267
|
+
s = TSet.new
|
|
268
|
+
s << T.new(:a, :b, :c) << T.new(:b, :a, :d) << [:e, :f, :g]
|
|
269
|
+
assert(s.include?(:a, :b))
|
|
270
|
+
assert(s.include?(T.new(:a, :b, :c)))
|
|
271
|
+
assert(s.include?(:b, :a, :d))
|
|
272
|
+
assert(s.include?([:e, :f]))
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def test_ac_bad_transition_set
|
|
276
|
+
s = TSet.new
|
|
277
|
+
s << T.new(:a, :b, :c) << T.new(:b, :a, :d)
|
|
278
|
+
assert(! s.include?(T.new(:b, :b, :c)))
|
|
279
|
+
assert(! s.include?(:a, :d, :c))
|
|
280
|
+
assert(! s.include?([:c, :b]))
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
#
|
|
284
|
+
# g
|
|
285
|
+
# +---------------------------+
|
|
286
|
+
# | |
|
|
287
|
+
# v a b c d |
|
|
288
|
+
# 1 ---> 2 ---> 3 ---> 4 ---> 5
|
|
289
|
+
# | ^
|
|
290
|
+
# | e f |
|
|
291
|
+
# +----> 6 -----+
|
|
292
|
+
#
|
|
293
|
+
def make_simple_factory
|
|
294
|
+
f = SynFlowFactory.new
|
|
295
|
+
f << [1, :a, 2] \
|
|
296
|
+
<< [6, :f, 4] \
|
|
297
|
+
<< SynFlowFactory::Transition.new(3, :c, 4)
|
|
298
|
+
f << { 2 => { :e => 6, :b => 3 },
|
|
299
|
+
4 => { :d => 5 },
|
|
300
|
+
5 => { :g => 1 }
|
|
301
|
+
}
|
|
302
|
+
f.initial = 1
|
|
303
|
+
return f
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def test_ad_simple_factory
|
|
307
|
+
f = nil
|
|
308
|
+
assert_nothing_raised do
|
|
309
|
+
f = make_simple_factory
|
|
310
|
+
end
|
|
311
|
+
transitions =
|
|
312
|
+
[[1, :a, 2],
|
|
313
|
+
[6, :f, 4],
|
|
314
|
+
[3, :c, 4],
|
|
315
|
+
[2, :e, 6],
|
|
316
|
+
[2, :b, 3],
|
|
317
|
+
[4, :d, 5],
|
|
318
|
+
[5, :g, 1]]
|
|
319
|
+
transitions.each do |s, l, d|
|
|
320
|
+
assert(f.transitions.include?(s, l, d))
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
assert(! f.transitions.include?(1, :a, 3))
|
|
324
|
+
assert(! f.transitions.include?(2, :a))
|
|
325
|
+
assert(! f.transitions.include?(1, :a, 1))
|
|
326
|
+
|
|
327
|
+
assert(f.initial?(1))
|
|
328
|
+
assert(! f.initial?(2))
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
def test_ba_simple_flow
|
|
332
|
+
f = make_simple_factory
|
|
333
|
+
m = nil
|
|
334
|
+
assert_nothing_raised { m = f.new_flow }
|
|
335
|
+
assert_nothing_raised do
|
|
336
|
+
Timeout.timeout(2) do
|
|
337
|
+
assert_equal(1, m.state)
|
|
338
|
+
m << :a
|
|
339
|
+
assert_equal(2, m.state)
|
|
340
|
+
m << :b
|
|
341
|
+
assert_equal(3, m.state)
|
|
342
|
+
m << :c
|
|
343
|
+
assert_equal(4, m.state)
|
|
344
|
+
m << :d
|
|
345
|
+
assert_equal(5, m.state)
|
|
346
|
+
m << :g
|
|
347
|
+
assert_equal(1, m.state)
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
def test_bb_simple_loop
|
|
353
|
+
f = make_simple_factory
|
|
354
|
+
f << [6, :e, 6]
|
|
355
|
+
m = f.new_flow
|
|
356
|
+
assert_nothing_raised do
|
|
357
|
+
Timeout.timeout(2) do
|
|
358
|
+
assert_equal(1, m.state)
|
|
359
|
+
m << :a
|
|
360
|
+
assert_equal(2, m.state)
|
|
361
|
+
m << :e
|
|
362
|
+
assert_equal(6, m.state)
|
|
363
|
+
m << :e
|
|
364
|
+
assert_equal(6, m.state)
|
|
365
|
+
m << :f
|
|
366
|
+
assert_equal(4, m.state)
|
|
367
|
+
end
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
def test_bc_simple_try_advance
|
|
372
|
+
f = make_simple_factory
|
|
373
|
+
m = f.new_flow
|
|
374
|
+
assert_nothing_raised do
|
|
375
|
+
Timeout.timeout(2) do
|
|
376
|
+
assert(m.try_advance(:a))
|
|
377
|
+
assert_equal(2, m.state)
|
|
378
|
+
m << :b
|
|
379
|
+
assert_equal(3, m.state)
|
|
380
|
+
assert(! m.try_advance(:e))
|
|
381
|
+
assert_equal(3, m.state)
|
|
382
|
+
m << :c
|
|
383
|
+
assert_equal(4, m.state)
|
|
384
|
+
end
|
|
385
|
+
end
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
def test_c_avanced_flow
|
|
389
|
+
f = make_simple_factory
|
|
390
|
+
m = f.new_flow
|
|
391
|
+
th = Thread.new { sleep ; m << :e }
|
|
392
|
+
assert_raise(Timeout::Error) do
|
|
393
|
+
Timeout.timeout(0.2) do
|
|
394
|
+
th.wakeup
|
|
395
|
+
th.join
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
assert_nothing_raised do
|
|
399
|
+
Timeout.timeout(2) do
|
|
400
|
+
m << :a
|
|
401
|
+
sleep 0.1
|
|
402
|
+
assert_equal(6, m.state)
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
assert_nothing_raised do
|
|
406
|
+
Timeout.timeout(2) do
|
|
407
|
+
m << :f
|
|
408
|
+
assert_equal(4, m.state)
|
|
409
|
+
m << :d
|
|
410
|
+
assert_equal(5, m.state)
|
|
411
|
+
m << :g
|
|
412
|
+
assert_equal(1, m.state)
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
def test_d_multi_threads
|
|
418
|
+
f = make_simple_factory
|
|
419
|
+
m = f.new_flow
|
|
420
|
+
|
|
421
|
+
assert_nothing_raised do
|
|
422
|
+
Timeout.timeout(5) do
|
|
423
|
+
t = []
|
|
424
|
+
t << Thread.new { m << :d }
|
|
425
|
+
t << Thread.new { m << :c }
|
|
426
|
+
t << Thread.new { m << :a }
|
|
427
|
+
t << Thread.new { m << :b }
|
|
428
|
+
t.each { |t| t.join }
|
|
429
|
+
end
|
|
430
|
+
end
|
|
431
|
+
assert_equal(5, m.state)
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
class E < Exception
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
def test_e_with_block
|
|
438
|
+
f = make_simple_factory
|
|
439
|
+
m = f.new_flow
|
|
440
|
+
|
|
441
|
+
assert_nothing_raised do
|
|
442
|
+
Timeout.timeout(5) do
|
|
443
|
+
t1 = Thread.new do
|
|
444
|
+
sleep
|
|
445
|
+
m << :a
|
|
446
|
+
sleep
|
|
447
|
+
end
|
|
448
|
+
t2 = Thread.new do
|
|
449
|
+
m << :e
|
|
450
|
+
t1.raise E
|
|
451
|
+
end
|
|
452
|
+
t1.wakeup
|
|
453
|
+
t2.join
|
|
454
|
+
assert_raise(E) { t1.join }
|
|
455
|
+
end
|
|
456
|
+
end
|
|
457
|
+
assert_equal(6, m.state)
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
def test_f_dumpable
|
|
461
|
+
f = make_simple_factory
|
|
462
|
+
m = f.new_flow
|
|
463
|
+
|
|
464
|
+
assert_nothing_raised do
|
|
465
|
+
Marshal.load(Marshal.dump(m))
|
|
466
|
+
end
|
|
467
|
+
assert_nothing_raised do
|
|
468
|
+
Marshal.load(Marshal.dump(f))
|
|
469
|
+
end
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
end # class SynFlowTest
|
|
473
|
+
|
|
474
|
+
end
|