redshift 1.3.15
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/.gitignore +8 -0
- data/README +5 -0
- data/RELEASE-NOTES +455 -0
- data/TODO +431 -0
- data/bench/alg-state.rb +61 -0
- data/bench/bench +26 -0
- data/bench/bench.rb +10 -0
- data/bench/continuous.rb +76 -0
- data/bench/diff-bench +86 -0
- data/bench/discrete.rb +101 -0
- data/bench/euler.rb +50 -0
- data/bench/formula.rb +78 -0
- data/bench/half-strict.rb +103 -0
- data/bench/inertness.rb +116 -0
- data/bench/queue.rb +92 -0
- data/bench/run +66 -0
- data/bench/simple.rb +74 -0
- data/bench/strictness.rb +86 -0
- data/examples/ball-tkar.rb +72 -0
- data/examples/ball.rb +123 -0
- data/examples/collide.rb +70 -0
- data/examples/connect-parallel.rb +48 -0
- data/examples/connect.rb +109 -0
- data/examples/constants.rb +27 -0
- data/examples/delay.rb +80 -0
- data/examples/derivative.rb +77 -0
- data/examples/euler.rb +46 -0
- data/examples/external-lib.rb +33 -0
- data/examples/guard-debugger.rb +77 -0
- data/examples/lotka-volterra.rb +33 -0
- data/examples/persist-ball.rb +68 -0
- data/examples/pid.rb +87 -0
- data/examples/ports.rb +60 -0
- data/examples/queue.rb +56 -0
- data/examples/queue2.rb +98 -0
- data/examples/reset-with-event-val.rb +28 -0
- data/examples/scheduler.rb +104 -0
- data/examples/set-dest.rb +23 -0
- data/examples/simulink/README +1 -0
- data/examples/simulink/delay.mdl +827 -0
- data/examples/simulink/derivative.mdl +655 -0
- data/examples/step-discrete-profiler.rb +103 -0
- data/examples/subsystem.rb +109 -0
- data/examples/sync-deadlock.rb +32 -0
- data/examples/sync-queue.rb +91 -0
- data/examples/sync-retry.rb +20 -0
- data/examples/sync.rb +51 -0
- data/examples/thermostat.rb +53 -0
- data/examples/zeno.rb +53 -0
- data/lib/accessible-index.rb +47 -0
- data/lib/redshift.rb +1 -0
- data/lib/redshift/component.rb +412 -0
- data/lib/redshift/meta.rb +183 -0
- data/lib/redshift/mixins/zeno-debugger.rb +69 -0
- data/lib/redshift/port.rb +57 -0
- data/lib/redshift/queue.rb +104 -0
- data/lib/redshift/redshift.rb +111 -0
- data/lib/redshift/state.rb +31 -0
- data/lib/redshift/syntax.rb +558 -0
- data/lib/redshift/target/c.rb +37 -0
- data/lib/redshift/target/c/component-gen.rb +1303 -0
- data/lib/redshift/target/c/flow-gen.rb +325 -0
- data/lib/redshift/target/c/flow/algebraic.rb +85 -0
- data/lib/redshift/target/c/flow/buffer.rb +74 -0
- data/lib/redshift/target/c/flow/delay.rb +203 -0
- data/lib/redshift/target/c/flow/derivative.rb +101 -0
- data/lib/redshift/target/c/flow/euler.rb +67 -0
- data/lib/redshift/target/c/flow/expr.rb +113 -0
- data/lib/redshift/target/c/flow/rk4.rb +80 -0
- data/lib/redshift/target/c/library.rb +85 -0
- data/lib/redshift/target/c/world-gen.rb +1370 -0
- data/lib/redshift/target/spec.rb +34 -0
- data/lib/redshift/world.rb +300 -0
- data/rakefile +37 -0
- data/test/test.rb +52 -0
- data/test/test_buffer.rb +58 -0
- data/test/test_connect.rb +242 -0
- data/test/test_connect_parallel.rb +47 -0
- data/test/test_connect_strict.rb +135 -0
- data/test/test_constant.rb +74 -0
- data/test/test_delay.rb +145 -0
- data/test/test_derivative.rb +48 -0
- data/test/test_discrete.rb +592 -0
- data/test/test_discrete_isolated.rb +92 -0
- data/test/test_exit.rb +59 -0
- data/test/test_flow.rb +200 -0
- data/test/test_flow_link.rb +288 -0
- data/test/test_flow_sub.rb +100 -0
- data/test/test_flow_trans.rb +292 -0
- data/test/test_inherit.rb +127 -0
- data/test/test_inherit_event.rb +74 -0
- data/test/test_inherit_flow.rb +139 -0
- data/test/test_inherit_link.rb +65 -0
- data/test/test_inherit_setup.rb +56 -0
- data/test/test_inherit_state.rb +66 -0
- data/test/test_inherit_transition.rb +168 -0
- data/test/test_numerics.rb +34 -0
- data/test/test_queue.rb +90 -0
- data/test/test_queue_alone.rb +115 -0
- data/test/test_reset.rb +209 -0
- data/test/test_setup.rb +119 -0
- data/test/test_strict_continuity.rb +410 -0
- data/test/test_strict_reset_error.rb +30 -0
- data/test/test_strictness_error.rb +32 -0
- data/test/test_sync.rb +185 -0
- data/test/test_world.rb +328 -0
- metadata +204 -0
@@ -0,0 +1,74 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'redshift'
|
4
|
+
|
5
|
+
include RedShift
|
6
|
+
|
7
|
+
=begin
|
8
|
+
|
9
|
+
Tests events with inheritance.
|
10
|
+
|
11
|
+
=end
|
12
|
+
|
13
|
+
class Super < Component
|
14
|
+
state :S1
|
15
|
+
transition Enter => S1 do
|
16
|
+
event :e1 => 1
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Sub < Super
|
21
|
+
state :S2
|
22
|
+
transition S1 => S2 do
|
23
|
+
event :e2 => 2
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class EventTestComponent < Component
|
28
|
+
link :sub => Sub
|
29
|
+
state :T1, :T2
|
30
|
+
setup {@result = []; self.sub = create(Sub)}
|
31
|
+
transition Enter => T1 do
|
32
|
+
sync :sub => :e1
|
33
|
+
action {@result << sub.e1}
|
34
|
+
end
|
35
|
+
transition T1 => T2 do
|
36
|
+
sync :sub => :e2
|
37
|
+
action {@result << sub.e2}
|
38
|
+
end
|
39
|
+
|
40
|
+
def assert_consistent test
|
41
|
+
test.assert_equal([1,2], @result)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
#-----#
|
46
|
+
|
47
|
+
require 'test/unit'
|
48
|
+
|
49
|
+
class TestInheritEvent < Test::Unit::TestCase
|
50
|
+
def setup
|
51
|
+
@world = World.new
|
52
|
+
@world.time_step = 0.1
|
53
|
+
end
|
54
|
+
|
55
|
+
def teardown
|
56
|
+
@world = nil
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_inherit_event
|
60
|
+
testers = []
|
61
|
+
ObjectSpace.each_object(Class) do |cl|
|
62
|
+
if cl <= EventTestComponent and
|
63
|
+
cl.instance_methods.include? "assert_consistent"
|
64
|
+
testers << @world.create(cl)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
@world.run
|
69
|
+
|
70
|
+
for t in testers
|
71
|
+
t.assert_consistent self
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'redshift'
|
4
|
+
|
5
|
+
include RedShift
|
6
|
+
|
7
|
+
#-- Flow-specific test classes --#
|
8
|
+
|
9
|
+
class FlowTestComponent < Component
|
10
|
+
def initialize(*args)
|
11
|
+
super
|
12
|
+
@start_time = world.clock
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# ------------------------
|
17
|
+
# Per equation granularity
|
18
|
+
|
19
|
+
class Flow_1 < FlowTestComponent
|
20
|
+
flow { alg "x = 0", "y = 1", "z = 2" }
|
21
|
+
end
|
22
|
+
|
23
|
+
class Flow_1_1 < Flow_1
|
24
|
+
flow { alg "x = 3" } # override one of several flows
|
25
|
+
def assert_consistent test
|
26
|
+
test.assert_equal([3,1,2], [x,y,z])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Flow_1_2 < Flow_1
|
31
|
+
flow { alg "w = 4" } # add a new, unrelated flow
|
32
|
+
def assert_consistent test
|
33
|
+
test.assert_equal([0,1,2,4], [x,y,z,w])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class Flow_1_2_1 < Flow_1_2
|
38
|
+
flow { alg "w = 5" } # ...and override it in a subclass
|
39
|
+
def assert_consistent test
|
40
|
+
test.assert_equal([0,1,2,5], [x,y,z,w])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# ----------------------------------
|
45
|
+
# Overriding the type of an equation
|
46
|
+
|
47
|
+
class Flow_2 < FlowTestComponent
|
48
|
+
flow { alg "x = 0" }
|
49
|
+
end
|
50
|
+
|
51
|
+
class Flow_2_1 < Flow_2
|
52
|
+
flow { diff "x' = 1" }
|
53
|
+
def assert_consistent test
|
54
|
+
test.assert_in_delta(world.clock - @start_time, x, 0.00001)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class Flow_2_1_1 < Flow_2_1
|
59
|
+
flow { alg "x = -1" }
|
60
|
+
def assert_consistent test
|
61
|
+
test.assert_in_delta(-1, x, 0.00001)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# ---------------------
|
66
|
+
# Per state granularity
|
67
|
+
|
68
|
+
class Flow_3 < FlowTestComponent
|
69
|
+
state :S1, :S2
|
70
|
+
|
71
|
+
flow S1 do diff "x'=1" end
|
72
|
+
flow S2 do diff "x'=-1" end
|
73
|
+
|
74
|
+
transition Enter => S1
|
75
|
+
transition S1 => S2 do guard {x >= 1} end
|
76
|
+
transition S2 => S1 do guard {x <= 0} end
|
77
|
+
|
78
|
+
def assert_consistent test
|
79
|
+
test.assert_in_delta(0.5, x, 0.5 + world.time_step)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class Flow_3_1 < Flow_3
|
84
|
+
flow S2 do diff "x'=1" end # override in just one state
|
85
|
+
|
86
|
+
transition Enter => S1
|
87
|
+
transition S1 => S2 do guard {x >= 1} end
|
88
|
+
transition S2 => S1 do guard {x <= 0} end
|
89
|
+
|
90
|
+
def assert_consistent test
|
91
|
+
test.assert(state == S2 || world.clock <= 1)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# ---------------------
|
96
|
+
# Overriding a flow referenced in a flow in the parent class
|
97
|
+
|
98
|
+
class Flow_4 < FlowTestComponent
|
99
|
+
flow do diff "x' = y", "y' = 1" end
|
100
|
+
end
|
101
|
+
|
102
|
+
class Flow_4_1 < Flow_4
|
103
|
+
flow do diff "y' = -1" end
|
104
|
+
def assert_consistent test
|
105
|
+
test.assert_in_delta(-0.5*world.clock**2, x, 1E-10)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
## other kinds of alg and diff flows (cached-alg, euler, cflow, etc.)
|
110
|
+
|
111
|
+
#-----#
|
112
|
+
|
113
|
+
require 'test/unit'
|
114
|
+
|
115
|
+
class TestInheritFlow < Test::Unit::TestCase
|
116
|
+
|
117
|
+
def setup
|
118
|
+
@world = World.new
|
119
|
+
@world.time_step = 0.1
|
120
|
+
end
|
121
|
+
|
122
|
+
def teardown
|
123
|
+
@world = nil
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_inherit_flow
|
127
|
+
testers = []
|
128
|
+
ObjectSpace.each_object(Class) do |cl|
|
129
|
+
if cl <= FlowTestComponent and
|
130
|
+
cl.instance_methods.include? "assert_consistent"
|
131
|
+
testers << @world.create(cl)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
testers.each { |t| t.assert_consistent self }
|
136
|
+
@world.run 100
|
137
|
+
testers.each { |t| t.assert_consistent self }
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'redshift'
|
4
|
+
|
5
|
+
include RedShift
|
6
|
+
|
7
|
+
class LinkTestComponent < Component
|
8
|
+
class Foo < Component; end
|
9
|
+
link :foo => Foo
|
10
|
+
end
|
11
|
+
|
12
|
+
class Link_1 < LinkTestComponent
|
13
|
+
setup {self.foo = create Foo}
|
14
|
+
def assert_consistent test
|
15
|
+
test.assert_equal(LinkTestComponent::Foo, foo.class)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Link_2 < LinkTestComponent
|
20
|
+
class Bar < Foo; end
|
21
|
+
### link :foo => Bar ### ==> "already exists"
|
22
|
+
end
|
23
|
+
|
24
|
+
# test forward references
|
25
|
+
class Link_FwdRef < Component
|
26
|
+
link :fwd => :FwdRefClass
|
27
|
+
setup {self.fwd = create FwdRefClass}
|
28
|
+
def assert_consistent test
|
29
|
+
test.assert_equal(1, fwd.x)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class FwdRefClass < Component
|
34
|
+
flow {alg "x = 1"}
|
35
|
+
end
|
36
|
+
|
37
|
+
#-----#
|
38
|
+
|
39
|
+
require 'test/unit'
|
40
|
+
|
41
|
+
class TestInheritLink < Test::Unit::TestCase
|
42
|
+
|
43
|
+
def setup
|
44
|
+
@world = World.new
|
45
|
+
@world.time_step = 0.1
|
46
|
+
end
|
47
|
+
|
48
|
+
def teardown
|
49
|
+
@world = nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_inherit_link
|
53
|
+
testers = []
|
54
|
+
ObjectSpace.each_object(Class) do |cl|
|
55
|
+
if cl <= LinkTestComponent and
|
56
|
+
cl.instance_methods.include? "assert_consistent"
|
57
|
+
testers << @world.create(cl)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
testers.each { |t| t.assert_consistent self }
|
62
|
+
@world.run 100
|
63
|
+
testers.each { |t| t.assert_consistent self }
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'redshift'
|
4
|
+
|
5
|
+
include RedShift
|
6
|
+
|
7
|
+
#-- Setup and default-specific test classes --#
|
8
|
+
|
9
|
+
class A; end
|
10
|
+
class B < A; end
|
11
|
+
|
12
|
+
class SetupTestComponent < Component
|
13
|
+
attr_reader :x, :y, :z, :xx, :yy, :zz, :other
|
14
|
+
|
15
|
+
setup {@x = 0; @y = 1; @other = make_other}
|
16
|
+
defaults {@xx = 0; @yy = 1}
|
17
|
+
|
18
|
+
def make_other # see inherit.txt
|
19
|
+
A.new
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
class Setup_1 < SetupTestComponent
|
25
|
+
|
26
|
+
setup {@y = 2; @z = 3}
|
27
|
+
defaults {@yy = 2; @zz = 3}
|
28
|
+
|
29
|
+
def make_other
|
30
|
+
B.new
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
#-----#
|
36
|
+
|
37
|
+
require 'test/unit'
|
38
|
+
|
39
|
+
class TestInheritSetup < Test::Unit::TestCase
|
40
|
+
|
41
|
+
def setup
|
42
|
+
@world = World.new
|
43
|
+
@world.time_step = 0.1
|
44
|
+
end
|
45
|
+
|
46
|
+
def teardown
|
47
|
+
@world = nil
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_inherit_setup
|
51
|
+
t = @world.create(Setup_1)
|
52
|
+
assert_equal([0,2,3], [t.x,t.y,t.z])
|
53
|
+
assert_equal([0,2,3], [t.xx,t.yy,t.zz])
|
54
|
+
assert_equal(B, t.other.class)
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'redshift'
|
4
|
+
|
5
|
+
include RedShift
|
6
|
+
|
7
|
+
class StateTestComponent < Component
|
8
|
+
end
|
9
|
+
|
10
|
+
class State_Inherit < StateTestComponent
|
11
|
+
class Sub < self
|
12
|
+
end
|
13
|
+
state :A, :B, :C
|
14
|
+
link :sub => Sub
|
15
|
+
|
16
|
+
def assert_consistent test
|
17
|
+
test.assert_equal(self.states, create(Sub).states)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# repeating a state declaration is an error
|
22
|
+
|
23
|
+
###class State_Duplicate < StateTestComponent
|
24
|
+
### state :A
|
25
|
+
### def assert_consistent test
|
26
|
+
### c = Class.new(self.class)
|
27
|
+
### class << self
|
28
|
+
### undef_method :assert_consistent
|
29
|
+
### end
|
30
|
+
### test.assert_exception(RuntimeError) {
|
31
|
+
### c.state :A
|
32
|
+
### }
|
33
|
+
### end
|
34
|
+
###end
|
35
|
+
|
36
|
+
#-----#
|
37
|
+
|
38
|
+
require 'test/unit'
|
39
|
+
|
40
|
+
class TestInheritState < Test::Unit::TestCase
|
41
|
+
|
42
|
+
def setup
|
43
|
+
@world = World.new
|
44
|
+
@world.time_step = 0.01
|
45
|
+
end
|
46
|
+
|
47
|
+
def teardown
|
48
|
+
@world = nil
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_inherit_state
|
52
|
+
testers = []
|
53
|
+
ObjectSpace.each_object(Class) do |cl|
|
54
|
+
if cl <= StateTestComponent and
|
55
|
+
cl.instance_methods.include? "assert_consistent"
|
56
|
+
testers << @world.create(cl)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
testers.each { |t| t.assert_consistent self }
|
61
|
+
|
62
|
+
# @world.run 1000 do
|
63
|
+
# testers.each { |t| t.assert_consistent self }
|
64
|
+
# end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'redshift'
|
4
|
+
|
5
|
+
include RedShift
|
6
|
+
|
7
|
+
#-- Transition-specific test classes --#
|
8
|
+
|
9
|
+
class TransTestComponent < Component
|
10
|
+
def initialize(*args)
|
11
|
+
super
|
12
|
+
@t = world.clock
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# --------------------
|
17
|
+
# Per edge granularity
|
18
|
+
|
19
|
+
class Trans_1 < TransTestComponent
|
20
|
+
defaults do
|
21
|
+
@x = 0
|
22
|
+
end
|
23
|
+
|
24
|
+
state :A, :B, :C, :D
|
25
|
+
transition Enter => A
|
26
|
+
transition A => B, B => C, C => D do
|
27
|
+
name :foo
|
28
|
+
action { @x += 1 }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Trans_1_1 < Trans_1
|
33
|
+
transition B => C do
|
34
|
+
name :foo
|
35
|
+
action { } # override one of several transitions
|
36
|
+
end
|
37
|
+
def assert_consistent test
|
38
|
+
test.assert_equal(state == Enter ? 0 : 2, @x, "@x = #@x, state = #{state}")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class Trans_1_2 < Trans_1
|
43
|
+
state :F # E is the constant 2.718281828
|
44
|
+
transition D => F do
|
45
|
+
action { @x += 1 } # add one new transition
|
46
|
+
end
|
47
|
+
def assert_consistent test
|
48
|
+
test.assert_equal(state == Enter ? 0 : 4, @x)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class Trans_1_3 < Trans_1
|
53
|
+
transition B => C do
|
54
|
+
name :foo
|
55
|
+
guard { false }
|
56
|
+
action { 1/0 } # this shouldn't happen
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class Trans_1_3_1 < Trans_1_3
|
61
|
+
transition B => C do
|
62
|
+
name :foo
|
63
|
+
# neither the guard nor the action of the superclass is inherited
|
64
|
+
end
|
65
|
+
def assert_consistent test
|
66
|
+
test.assert_equal(state == Enter ? 0 : 2, @x)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# ----------------------------
|
71
|
+
# Redundant state declarations
|
72
|
+
|
73
|
+
class Trans_2 < TransTestComponent
|
74
|
+
state :A, :B, :C, :D
|
75
|
+
transition Enter => A, A => B, C => D
|
76
|
+
end
|
77
|
+
|
78
|
+
class Trans_2_1 < Trans_2
|
79
|
+
transition B => C
|
80
|
+
def assert_consistent test
|
81
|
+
test.assert(state == Enter || state == D,
|
82
|
+
"State is #{state.name}, not Enter or D")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# ------
|
87
|
+
# Events
|
88
|
+
|
89
|
+
# events are inherited
|
90
|
+
|
91
|
+
class Trans_3 < TransTestComponent
|
92
|
+
state :A
|
93
|
+
transition Enter => A do
|
94
|
+
event :e => literal("fred")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
class Trans_3_1 < Trans_3
|
99
|
+
end
|
100
|
+
|
101
|
+
class Trans_3a < TransTestComponent
|
102
|
+
state :A
|
103
|
+
link :c
|
104
|
+
setup {self.c = create(Trans_3_1)}
|
105
|
+
|
106
|
+
transition Enter => A do
|
107
|
+
sync :c => :e
|
108
|
+
action { @worked = (c.e == "fred") }
|
109
|
+
end
|
110
|
+
def assert_consistent test
|
111
|
+
test.assert(world.clock == 0 || @worked)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# priority of transitions is by subclasses first
|
116
|
+
class Trans_4a < TransTestComponent
|
117
|
+
state :A, :B
|
118
|
+
transition Enter => A do name "A" end
|
119
|
+
# Note: assign a name or else B's transition will simply replace A's,
|
120
|
+
# since they will both be named "Always", and that won't be a useful test.
|
121
|
+
def assert_consistent test
|
122
|
+
test.flunk unless state == A or state == Enter
|
123
|
+
end
|
124
|
+
end
|
125
|
+
class Trans_4b < Trans_4a
|
126
|
+
transition Enter => B do name "B" end
|
127
|
+
def assert_consistent test
|
128
|
+
test.flunk("state was #{state}") unless state == B or state == Enter
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
#-----#
|
133
|
+
|
134
|
+
require 'test/unit'
|
135
|
+
|
136
|
+
class TestInheritTrans < Test::Unit::TestCase
|
137
|
+
|
138
|
+
def setup
|
139
|
+
@world = World.new
|
140
|
+
@world.time_step = 0.1
|
141
|
+
end
|
142
|
+
|
143
|
+
def teardown
|
144
|
+
@world = nil
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_inherit_trans
|
148
|
+
testers = []
|
149
|
+
ObjectSpace.each_object(Class) do |cl|
|
150
|
+
if cl <= TransTestComponent and
|
151
|
+
cl.instance_methods.include? "assert_consistent"
|
152
|
+
testers << @world.create(cl)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
for t in testers
|
157
|
+
assert_equal(RedShift::Enter, t.state)
|
158
|
+
t.assert_consistent self
|
159
|
+
end
|
160
|
+
|
161
|
+
@world.run 100
|
162
|
+
|
163
|
+
for t in testers
|
164
|
+
assert(RedShift::Enter != t.state, "#{t.class} didn't leave Enter!")
|
165
|
+
t.assert_consistent self
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|