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,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
|