redshift 1.3.15
Sign up to get free protection for your applications and to get access to all the features.
- 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,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'redshift'
|
4
|
+
|
5
|
+
include RedShift
|
6
|
+
|
7
|
+
require 'test/unit'
|
8
|
+
|
9
|
+
# See also test_strict_continuity.rb.
|
10
|
+
|
11
|
+
class TestStrictnessError < Test::Unit::TestCase
|
12
|
+
|
13
|
+
class T < Component
|
14
|
+
|
15
|
+
strictly_continuous :x
|
16
|
+
|
17
|
+
transition do
|
18
|
+
reset :x => 1
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
# This is the only test that can appear in this file.
|
24
|
+
def test_strict_reset_error
|
25
|
+
assert_raises(RedShift::StrictnessError) do
|
26
|
+
World.new
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'redshift'
|
4
|
+
|
5
|
+
include RedShift
|
6
|
+
|
7
|
+
require 'test/unit'
|
8
|
+
|
9
|
+
# See also test_strict_continuity.rb.
|
10
|
+
|
11
|
+
class TestStrictnessError < Test::Unit::TestCase
|
12
|
+
|
13
|
+
class T < Component
|
14
|
+
|
15
|
+
strictly_continuous :x
|
16
|
+
continuous :y
|
17
|
+
link :lnk => T
|
18
|
+
|
19
|
+
flow {
|
20
|
+
alg "x = lnk.y+1"
|
21
|
+
}
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
# This is the only test that can appear in this file.
|
26
|
+
def test_strictness_error
|
27
|
+
assert_raises(RedShift::StrictnessError) do
|
28
|
+
World.new
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
data/test/test_sync.rb
ADDED
@@ -0,0 +1,185 @@
|
|
1
|
+
# test chains of asymmetric sync
|
2
|
+
# when guard not enabled at root, ...
|
3
|
+
|
4
|
+
# test chains of symmetric sync
|
5
|
+
|
6
|
+
require 'redshift'
|
7
|
+
require 'test/unit'
|
8
|
+
|
9
|
+
class DebugSyncWorld #< RedShift::World
|
10
|
+
def hook_begin
|
11
|
+
puts "===== begin discrete update ====="
|
12
|
+
end
|
13
|
+
|
14
|
+
def hook_enter_sync_phase
|
15
|
+
puts "enter sync phase"
|
16
|
+
end
|
17
|
+
|
18
|
+
def hook_can_sync comp, can_sync
|
19
|
+
puts " #{comp.inspect}: can_sync=#{can_sync.inspect}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def hook_sync_step syncers, changed
|
23
|
+
puts " sync step, changed=#{changed.inspect}"
|
24
|
+
puts " syncers = #{syncers.inspect}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class TestSync < Test::Unit::TestCase
|
29
|
+
class Relay < RedShift::Component
|
30
|
+
link :next
|
31
|
+
|
32
|
+
transition Enter => Exit do
|
33
|
+
sync :next => :e
|
34
|
+
event :e
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Emitter < RedShift::Component
|
39
|
+
transition Enter => Exit do
|
40
|
+
event :e
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class Emitter_f < RedShift::Component
|
45
|
+
transition Enter => Exit do
|
46
|
+
event :f
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Ground < RedShift::Component
|
51
|
+
link :next
|
52
|
+
|
53
|
+
transition Enter => Exit do
|
54
|
+
sync :next => :e
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class EmitTwo < RedShift::Component
|
59
|
+
state :EmitE, :EmitF, :EmitEF
|
60
|
+
transition Enter => EmitE do
|
61
|
+
event :e
|
62
|
+
end
|
63
|
+
transition EmitE => EmitF do
|
64
|
+
event :f
|
65
|
+
end
|
66
|
+
transition EmitF => EmitEF do
|
67
|
+
event :e, :f
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class SyncTwo < RedShift::Component
|
72
|
+
link :next
|
73
|
+
setup {self.next = create(EmitTwo)}
|
74
|
+
transition Enter => Exit do
|
75
|
+
sync :next => :e
|
76
|
+
sync :next => :f
|
77
|
+
action do
|
78
|
+
@worked = (self.next.state == EmitTwo::EmitF)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
attr_reader :worked
|
82
|
+
end
|
83
|
+
|
84
|
+
class SyncRetry < RedShift::Component
|
85
|
+
state :Ok
|
86
|
+
link :next
|
87
|
+
setup {self.next = nil}
|
88
|
+
transition Enter => Exit do
|
89
|
+
sync :next => :no_such_event
|
90
|
+
end
|
91
|
+
transition Enter => Ok
|
92
|
+
end
|
93
|
+
|
94
|
+
def setup
|
95
|
+
@w = RedShift::World.new
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_sync_self
|
99
|
+
r = @w.create Relay
|
100
|
+
r.next = r
|
101
|
+
g = @w.create Ground
|
102
|
+
@w.run 1
|
103
|
+
assert_equal(RedShift::Component::Exit, r.state)
|
104
|
+
assert_equal(RedShift::Component::Enter, g.state)
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_sync_nil
|
108
|
+
r = @w.create Relay
|
109
|
+
r.next = nil
|
110
|
+
@w.run 1
|
111
|
+
assert_equal(RedShift::Component::Enter, r.state)
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_sync_no_event
|
115
|
+
r = @w.create Relay
|
116
|
+
r.next = @w.create Relay
|
117
|
+
@w.run 10
|
118
|
+
assert_equal(RedShift::Component::Enter, r.state)
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_sync_wrong_event
|
122
|
+
r = @w.create Relay
|
123
|
+
r.next = @w.create Emitter_f
|
124
|
+
@w.run 10
|
125
|
+
assert_equal(RedShift::Component::Enter, r.state)
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_sync_two_events
|
129
|
+
s2 = @w.create(SyncTwo)
|
130
|
+
assert_equal(nil, s2.worked)
|
131
|
+
@w.run 1
|
132
|
+
assert_equal(true, s2.worked)
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_cyclic
|
136
|
+
a = (0..4).map do
|
137
|
+
@w.create Relay
|
138
|
+
end
|
139
|
+
|
140
|
+
# connect them in an order different from creation order
|
141
|
+
a[4].next = a[3]
|
142
|
+
a[3].next = a[1]
|
143
|
+
a[1].next = a[2]
|
144
|
+
a[2].next = a[0]
|
145
|
+
a[0].next = a[4]
|
146
|
+
|
147
|
+
@w.run 1
|
148
|
+
a.each do |relay|
|
149
|
+
assert_equal(RedShift::Component::Exit, relay.state)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_acyclic
|
154
|
+
a = (0..4).map do
|
155
|
+
@w.create Relay
|
156
|
+
end
|
157
|
+
|
158
|
+
# connect them in an order different from creation order
|
159
|
+
a[4].next = a[3]
|
160
|
+
a[3].next = a[1]
|
161
|
+
a[1].next = a[2]
|
162
|
+
a[2].next = a[0]
|
163
|
+
a[0].next = nil
|
164
|
+
|
165
|
+
@w.run 1
|
166
|
+
a.each do |relay|
|
167
|
+
assert_equal(RedShift::Component::Enter, relay.state)
|
168
|
+
end
|
169
|
+
|
170
|
+
emitter = @w.create Emitter
|
171
|
+
a[0].next = emitter
|
172
|
+
|
173
|
+
@w.run 1
|
174
|
+
(a + [emitter]).each do |relay|
|
175
|
+
assert_equal(RedShift::Component::Exit, relay.state)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
# see also examples/sync-retry.rb
|
180
|
+
def test_sync_retry
|
181
|
+
c = @w.create SyncRetry
|
182
|
+
@w.run 1
|
183
|
+
assert_equal(SyncRetry::Ok, c.state)
|
184
|
+
end
|
185
|
+
end
|
data/test/test_world.rb
ADDED
@@ -0,0 +1,328 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'redshift'
|
4
|
+
|
5
|
+
include RedShift
|
6
|
+
|
7
|
+
# test setup and default clauses in world class and in world instance
|
8
|
+
# test World#started?
|
9
|
+
|
10
|
+
class World_1 < World
|
11
|
+
default { @d = 6 }
|
12
|
+
setup { @x = 1 }; setup { @y = 2 }
|
13
|
+
def initialize
|
14
|
+
super {
|
15
|
+
@e = @d + 1
|
16
|
+
@z = 3
|
17
|
+
}
|
18
|
+
setup { @t = 4 }; setup { @u = 5 }
|
19
|
+
end
|
20
|
+
def assert_consistent_before test
|
21
|
+
test.assert(!started?)
|
22
|
+
test.assert_equal([nil,nil,3,nil,nil,6,7], [@x,@y,@z,@t,@u,@d,@e])
|
23
|
+
end
|
24
|
+
def assert_consistent_after test
|
25
|
+
test.assert(started?)
|
26
|
+
test.assert_equal([1,2,3,4,5,6,7], [@x,@y,@z,@t,@u,@d,@e])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# test inheritance of setup clauses
|
31
|
+
|
32
|
+
class World_1_1 < World_1
|
33
|
+
setup { @y = 2.1; @r = 6 }
|
34
|
+
def initialize
|
35
|
+
super
|
36
|
+
setup { @u = 5.1; @s = 7 }
|
37
|
+
end
|
38
|
+
def assert_consistent_before test
|
39
|
+
test.assert_equal([nil,nil,3,nil,nil,nil,nil], [@x,@y,@z,@t,@u,@r,@s])
|
40
|
+
end
|
41
|
+
def assert_consistent_after test
|
42
|
+
test.assert_equal([1,2.1,3,4,5.1,6,7], [@x,@y,@z,@t,@u,@r,@s])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# test world clock, time step, clock start, clock finish
|
47
|
+
|
48
|
+
class World_2 < World
|
49
|
+
class Timer < Component
|
50
|
+
flow {diff "t' = 1"}
|
51
|
+
end
|
52
|
+
|
53
|
+
def run
|
54
|
+
super 1_000_000
|
55
|
+
end
|
56
|
+
|
57
|
+
def initialize
|
58
|
+
super do
|
59
|
+
self.time_step = 1.01
|
60
|
+
self.clock_start = 90.001
|
61
|
+
self.clock_finish = 100
|
62
|
+
end
|
63
|
+
|
64
|
+
setup do
|
65
|
+
@timer = create(Timer) {|timer| timer.t = 90.001}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def assert_consistent_before test
|
70
|
+
test.assert_equal(90.001, clock)
|
71
|
+
end
|
72
|
+
def assert_consistent_after test
|
73
|
+
test.assert_in_delta(@timer.t, clock, 1.0E-13)
|
74
|
+
test.assert_equal(100.101, clock)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# test integer time step
|
79
|
+
|
80
|
+
class World_2_1 < World_2
|
81
|
+
def initialize
|
82
|
+
super
|
83
|
+
self.time_step = 5
|
84
|
+
end
|
85
|
+
def assert_consistent_before test
|
86
|
+
test.assert_equal(90.001, clock)
|
87
|
+
end
|
88
|
+
def assert_consistent_after test
|
89
|
+
test.assert_in_delta(@timer.t, clock, 1.0E-13)
|
90
|
+
test.assert_equal(100.001, clock)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# test create and remove
|
95
|
+
|
96
|
+
puts "World#remove TEST DISABLED **************************"
|
97
|
+
if false && World.instance_methods.include?("remove")
|
98
|
+
class World_3 < World
|
99
|
+
setup do @x = create(Component) end
|
100
|
+
def run
|
101
|
+
super
|
102
|
+
remove @x
|
103
|
+
end
|
104
|
+
|
105
|
+
def assert_consistent_after test
|
106
|
+
test.assert_equal(0, size)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# test garbage collection
|
112
|
+
|
113
|
+
puts "GC TEST DISABLED **************************"
|
114
|
+
if false
|
115
|
+
class World_4 < World
|
116
|
+
setup do
|
117
|
+
@x = create(Component)
|
118
|
+
5.times do create(Component) end
|
119
|
+
end
|
120
|
+
|
121
|
+
def run
|
122
|
+
super
|
123
|
+
@before_size = size
|
124
|
+
garbage_collect
|
125
|
+
@after_size = size
|
126
|
+
end
|
127
|
+
|
128
|
+
def assert_consistent_after test
|
129
|
+
test.assert_equal(6, @before_size)
|
130
|
+
test.assert_equal(1, @after_size)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# test zeno detection
|
136
|
+
|
137
|
+
class World_5 < World
|
138
|
+
class Zeno < Component
|
139
|
+
transition Enter => Enter
|
140
|
+
end
|
141
|
+
|
142
|
+
setup do create(Zeno) end
|
143
|
+
|
144
|
+
def initialize
|
145
|
+
super
|
146
|
+
self.zeno_limit = 100
|
147
|
+
end
|
148
|
+
|
149
|
+
def step_zeno
|
150
|
+
@zeno_step_reached = true
|
151
|
+
super # raise ZenoError
|
152
|
+
end
|
153
|
+
|
154
|
+
def run
|
155
|
+
super
|
156
|
+
rescue => @e
|
157
|
+
end
|
158
|
+
|
159
|
+
def assert_consistent_after test
|
160
|
+
test.assert_kind_of(ZenoError, @e)
|
161
|
+
test.assert(@zeno_step_reached)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# test "run 0"
|
166
|
+
|
167
|
+
class World_6 < World
|
168
|
+
class Thing < Component
|
169
|
+
state :A, :B
|
170
|
+
default do
|
171
|
+
start A
|
172
|
+
@x = 0
|
173
|
+
end
|
174
|
+
flow A do
|
175
|
+
diff "x' = 1"
|
176
|
+
end
|
177
|
+
transition A => B do
|
178
|
+
guard {x < 0} # won't happen normally
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
setup {@thing = create Thing}
|
183
|
+
|
184
|
+
def run
|
185
|
+
super 0 ## do_setup and step_discrete -- test this
|
186
|
+
super 1
|
187
|
+
super 0 ## should do nothing -- repeat and test this
|
188
|
+
@thing.x = -1 # enables a guard
|
189
|
+
super 0
|
190
|
+
end
|
191
|
+
|
192
|
+
def assert_consistent_before test
|
193
|
+
test.assert_equal(0, size)
|
194
|
+
end
|
195
|
+
def assert_consistent_after test
|
196
|
+
test.assert_equal(1, size)
|
197
|
+
test.assert_equal(Thing::B, @thing.state)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
# test persistence
|
202
|
+
|
203
|
+
class World_7 < World
|
204
|
+
def make_copy
|
205
|
+
filename = File.join($REDSHIFT_WORK_DIR, $REDSHIFT_CLIB_NAME,
|
206
|
+
"test_world_persist.dat")
|
207
|
+
save(filename)
|
208
|
+
World.open(filename) # copy of world (with the same name)
|
209
|
+
ensure
|
210
|
+
# File.delete(filename) rescue SystemCallError
|
211
|
+
end
|
212
|
+
|
213
|
+
class Thing < Component
|
214
|
+
attr_reader :x_start
|
215
|
+
state :A, :B, :C; default {start A}
|
216
|
+
setup do
|
217
|
+
@x_start = self.x = 123
|
218
|
+
end
|
219
|
+
transition A => B
|
220
|
+
transition B => C do
|
221
|
+
guard { x > 200 }
|
222
|
+
end
|
223
|
+
flow B, C do
|
224
|
+
diff "x' = 1"
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
attr_accessor :thing
|
229
|
+
|
230
|
+
setup do
|
231
|
+
@thing = create Thing
|
232
|
+
end
|
233
|
+
|
234
|
+
def run n = nil
|
235
|
+
if n
|
236
|
+
super n
|
237
|
+
else
|
238
|
+
@start_copy = make_copy
|
239
|
+
super 0 # do_setup and step_discrete
|
240
|
+
@t0_copy = make_copy
|
241
|
+
super 1 # run the same world after saving
|
242
|
+
@t1_copy = make_copy
|
243
|
+
super 999
|
244
|
+
@t1000_copy = make_copy
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def assert_consistent_after test
|
249
|
+
test.assert_equal(nil, @start_copy.thing)
|
250
|
+
test.assert_equal(Thing::B, @t0_copy.thing.state)
|
251
|
+
test.assert_equal(Thing::B, @t1_copy.thing.state)
|
252
|
+
test.assert_equal(Thing::C, @t1000_copy.thing.state)
|
253
|
+
test.assert_equal(Thing::C, thing.state)
|
254
|
+
|
255
|
+
other_thing = create Thing
|
256
|
+
|
257
|
+
test.assert_equal(thing.x_start, @t0_copy.thing.x_start)
|
258
|
+
test.assert_equal(thing.x_start, @t1_copy.thing.x_start)
|
259
|
+
test.assert_equal(thing.x_start, @t1000_copy.thing.x_start)
|
260
|
+
test.assert_equal(thing.x_start, thing.x_start)
|
261
|
+
|
262
|
+
x_t0 = thing.x_start
|
263
|
+
x_t1 = thing.x_start + time_step
|
264
|
+
x_t1000 = thing.x_start + 1000 * time_step
|
265
|
+
|
266
|
+
test.assert_in_delta(x_t0, @t0_copy.thing.x, 1E-10)
|
267
|
+
test.assert_in_delta(x_t1, @t1_copy.thing.x, 1E-10)
|
268
|
+
test.assert_in_delta(x_t1000, @t1000_copy.thing.x, 1E-10)
|
269
|
+
test.assert_in_delta(x_t1000, thing.x, 1E-10)
|
270
|
+
|
271
|
+
# continue running with @t1_copy
|
272
|
+
@t1_copy.run 999
|
273
|
+
test.assert_equal(Thing::C, @t1_copy.thing.state)
|
274
|
+
test.assert_in_delta(x_t1000, @t1_copy.thing.x, 1E-10)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
=begin
|
279
|
+
|
280
|
+
tests:
|
281
|
+
can you set time step et al during setup? No. Should this be allowed?
|
282
|
+
run methods, debug tools
|
283
|
+
|
284
|
+
=end
|
285
|
+
|
286
|
+
#-----#
|
287
|
+
|
288
|
+
require 'test/unit'
|
289
|
+
|
290
|
+
class TestWorld < Test::Unit::TestCase
|
291
|
+
|
292
|
+
def test_world
|
293
|
+
testers = []
|
294
|
+
ObjectSpace.each_object(Class) do |cl|
|
295
|
+
if cl <= World and ## cl.instance_methods.grep /\Aassert_consistent/
|
296
|
+
(cl.instance_methods.include? "assert_consistent_before" or
|
297
|
+
cl.instance_methods.include? "assert_consistent_after")
|
298
|
+
testers << cl.new
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
for t in testers
|
303
|
+
t.assert_consistent_before self if t.respond_to? :assert_consistent_before
|
304
|
+
t.run
|
305
|
+
t.assert_consistent_after self if t.respond_to? :assert_consistent_after
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
def test_var_time_step
|
310
|
+
w = World.new
|
311
|
+
|
312
|
+
w.time_step = 0.01
|
313
|
+
w.evolve 1.0
|
314
|
+
assert_in_delta(1.0, w.clock, 1.0e-9)
|
315
|
+
|
316
|
+
w.time_step = 0.1
|
317
|
+
w.evolve 1.0
|
318
|
+
assert_in_delta(2.0, w.clock, 1.0e-9)
|
319
|
+
|
320
|
+
w.time_step = 0.05
|
321
|
+
w.evolve 1.0
|
322
|
+
assert_in_delta(3.0, w.clock, 1.0e-9)
|
323
|
+
|
324
|
+
w.time_step = 0.25
|
325
|
+
w.evolve 1.0
|
326
|
+
assert_in_delta(4.0, w.clock, 1.0e-9)
|
327
|
+
end
|
328
|
+
end
|