roby 0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (240) hide show
  1. data/.gitignore +29 -0
  2. data/History.txt +4 -0
  3. data/License-fr.txt +519 -0
  4. data/License.txt +515 -0
  5. data/Manifest.txt +245 -0
  6. data/NOTES +4 -0
  7. data/README.txt +163 -0
  8. data/Rakefile +161 -0
  9. data/TODO.txt +146 -0
  10. data/app/README.txt +24 -0
  11. data/app/Rakefile +8 -0
  12. data/app/config/ROBOT.rb +5 -0
  13. data/app/config/app.yml +91 -0
  14. data/app/config/init.rb +7 -0
  15. data/app/config/roby.yml +3 -0
  16. data/app/controllers/.gitattributes +0 -0
  17. data/app/controllers/ROBOT.rb +2 -0
  18. data/app/data/.gitattributes +0 -0
  19. data/app/planners/ROBOT/main.rb +6 -0
  20. data/app/planners/main.rb +5 -0
  21. data/app/scripts/distributed +3 -0
  22. data/app/scripts/generate/bookmarks +3 -0
  23. data/app/scripts/replay +3 -0
  24. data/app/scripts/results +3 -0
  25. data/app/scripts/run +3 -0
  26. data/app/scripts/server +3 -0
  27. data/app/scripts/shell +3 -0
  28. data/app/scripts/test +3 -0
  29. data/app/tasks/.gitattributes +0 -0
  30. data/app/tasks/ROBOT/.gitattributes +0 -0
  31. data/bin/roby +210 -0
  32. data/bin/roby-log +168 -0
  33. data/bin/roby-shell +25 -0
  34. data/doc/images/event_generalization.png +0 -0
  35. data/doc/images/exception_propagation_1.png +0 -0
  36. data/doc/images/exception_propagation_2.png +0 -0
  37. data/doc/images/exception_propagation_3.png +0 -0
  38. data/doc/images/exception_propagation_4.png +0 -0
  39. data/doc/images/exception_propagation_5.png +0 -0
  40. data/doc/images/replay_handler_error.png +0 -0
  41. data/doc/images/replay_handler_error_0.png +0 -0
  42. data/doc/images/replay_handler_error_1.png +0 -0
  43. data/doc/images/roby_cycle_overview.png +0 -0
  44. data/doc/images/roby_replay_02.png +0 -0
  45. data/doc/images/roby_replay_03.png +0 -0
  46. data/doc/images/roby_replay_04.png +0 -0
  47. data/doc/images/roby_replay_event_representation.png +0 -0
  48. data/doc/images/roby_replay_first_state.png +0 -0
  49. data/doc/images/roby_replay_relations.png +0 -0
  50. data/doc/images/roby_replay_startup.png +0 -0
  51. data/doc/images/task_event_generalization.png +0 -0
  52. data/doc/papers.rdoc +11 -0
  53. data/doc/styles/allison.css +314 -0
  54. data/doc/styles/allison.js +316 -0
  55. data/doc/styles/allison.rb +276 -0
  56. data/doc/styles/jamis.rb +593 -0
  57. data/doc/tutorials/01-GettingStarted.rdoc +86 -0
  58. data/doc/tutorials/02-GoForward.rdoc +220 -0
  59. data/doc/tutorials/03-PlannedPath.rdoc +268 -0
  60. data/doc/tutorials/04-EventPropagation.rdoc +236 -0
  61. data/doc/tutorials/05-ErrorHandling.rdoc +319 -0
  62. data/doc/tutorials/06-Overview.rdoc +40 -0
  63. data/doc/videos.rdoc +69 -0
  64. data/ext/droby/dump.cc +175 -0
  65. data/ext/droby/extconf.rb +3 -0
  66. data/ext/graph/algorithm.cc +746 -0
  67. data/ext/graph/extconf.rb +7 -0
  68. data/ext/graph/graph.cc +529 -0
  69. data/ext/graph/graph.hh +183 -0
  70. data/ext/graph/iterator_sequence.hh +102 -0
  71. data/ext/graph/undirected_dfs.hh +226 -0
  72. data/ext/graph/undirected_graph.hh +421 -0
  73. data/lib/roby.rb +41 -0
  74. data/lib/roby/app.rb +870 -0
  75. data/lib/roby/app/rake.rb +56 -0
  76. data/lib/roby/app/run.rb +14 -0
  77. data/lib/roby/app/scripts/distributed.rb +13 -0
  78. data/lib/roby/app/scripts/generate/bookmarks.rb +162 -0
  79. data/lib/roby/app/scripts/replay.rb +31 -0
  80. data/lib/roby/app/scripts/results.rb +15 -0
  81. data/lib/roby/app/scripts/run.rb +26 -0
  82. data/lib/roby/app/scripts/server.rb +18 -0
  83. data/lib/roby/app/scripts/shell.rb +88 -0
  84. data/lib/roby/app/scripts/test.rb +40 -0
  85. data/lib/roby/basic_object.rb +151 -0
  86. data/lib/roby/config.rb +5 -0
  87. data/lib/roby/control.rb +747 -0
  88. data/lib/roby/decision_control.rb +17 -0
  89. data/lib/roby/distributed.rb +32 -0
  90. data/lib/roby/distributed/base.rb +440 -0
  91. data/lib/roby/distributed/communication.rb +871 -0
  92. data/lib/roby/distributed/connection_space.rb +592 -0
  93. data/lib/roby/distributed/distributed_object.rb +206 -0
  94. data/lib/roby/distributed/drb.rb +62 -0
  95. data/lib/roby/distributed/notifications.rb +539 -0
  96. data/lib/roby/distributed/peer.rb +550 -0
  97. data/lib/roby/distributed/protocol.rb +529 -0
  98. data/lib/roby/distributed/proxy.rb +343 -0
  99. data/lib/roby/distributed/subscription.rb +311 -0
  100. data/lib/roby/distributed/transaction.rb +498 -0
  101. data/lib/roby/event.rb +897 -0
  102. data/lib/roby/exceptions.rb +234 -0
  103. data/lib/roby/executives/simple.rb +30 -0
  104. data/lib/roby/graph.rb +166 -0
  105. data/lib/roby/interface.rb +390 -0
  106. data/lib/roby/log.rb +3 -0
  107. data/lib/roby/log/chronicle.rb +303 -0
  108. data/lib/roby/log/console.rb +72 -0
  109. data/lib/roby/log/data_stream.rb +197 -0
  110. data/lib/roby/log/dot.rb +279 -0
  111. data/lib/roby/log/event_stream.rb +151 -0
  112. data/lib/roby/log/file.rb +340 -0
  113. data/lib/roby/log/gui/basic_display.ui +83 -0
  114. data/lib/roby/log/gui/chronicle.rb +26 -0
  115. data/lib/roby/log/gui/chronicle_view.rb +40 -0
  116. data/lib/roby/log/gui/chronicle_view.ui +70 -0
  117. data/lib/roby/log/gui/data_displays.rb +172 -0
  118. data/lib/roby/log/gui/data_displays.ui +155 -0
  119. data/lib/roby/log/gui/notifications.rb +26 -0
  120. data/lib/roby/log/gui/relations.rb +248 -0
  121. data/lib/roby/log/gui/relations.ui +123 -0
  122. data/lib/roby/log/gui/relations_view.rb +185 -0
  123. data/lib/roby/log/gui/relations_view.ui +149 -0
  124. data/lib/roby/log/gui/replay.rb +327 -0
  125. data/lib/roby/log/gui/replay_controls.rb +200 -0
  126. data/lib/roby/log/gui/replay_controls.ui +259 -0
  127. data/lib/roby/log/gui/runtime.rb +130 -0
  128. data/lib/roby/log/hooks.rb +185 -0
  129. data/lib/roby/log/logger.rb +202 -0
  130. data/lib/roby/log/notifications.rb +244 -0
  131. data/lib/roby/log/plan_rebuilder.rb +470 -0
  132. data/lib/roby/log/relations.rb +1056 -0
  133. data/lib/roby/log/server.rb +550 -0
  134. data/lib/roby/log/sqlite.rb +47 -0
  135. data/lib/roby/log/timings.rb +164 -0
  136. data/lib/roby/plan-object.rb +247 -0
  137. data/lib/roby/plan.rb +762 -0
  138. data/lib/roby/planning.rb +13 -0
  139. data/lib/roby/planning/loops.rb +302 -0
  140. data/lib/roby/planning/model.rb +906 -0
  141. data/lib/roby/planning/task.rb +151 -0
  142. data/lib/roby/propagation.rb +562 -0
  143. data/lib/roby/query.rb +619 -0
  144. data/lib/roby/relations.rb +583 -0
  145. data/lib/roby/relations/conflicts.rb +70 -0
  146. data/lib/roby/relations/ensured.rb +20 -0
  147. data/lib/roby/relations/error_handling.rb +23 -0
  148. data/lib/roby/relations/events.rb +9 -0
  149. data/lib/roby/relations/executed_by.rb +193 -0
  150. data/lib/roby/relations/hierarchy.rb +239 -0
  151. data/lib/roby/relations/influence.rb +10 -0
  152. data/lib/roby/relations/planned_by.rb +63 -0
  153. data/lib/roby/robot.rb +7 -0
  154. data/lib/roby/standard_errors.rb +218 -0
  155. data/lib/roby/state.rb +5 -0
  156. data/lib/roby/state/events.rb +221 -0
  157. data/lib/roby/state/information.rb +55 -0
  158. data/lib/roby/state/pos.rb +110 -0
  159. data/lib/roby/state/shapes.rb +32 -0
  160. data/lib/roby/state/state.rb +353 -0
  161. data/lib/roby/support.rb +92 -0
  162. data/lib/roby/task-operations.rb +182 -0
  163. data/lib/roby/task.rb +1618 -0
  164. data/lib/roby/test/common.rb +399 -0
  165. data/lib/roby/test/distributed.rb +214 -0
  166. data/lib/roby/test/tasks/empty_task.rb +9 -0
  167. data/lib/roby/test/tasks/goto.rb +36 -0
  168. data/lib/roby/test/tasks/simple_task.rb +23 -0
  169. data/lib/roby/test/testcase.rb +519 -0
  170. data/lib/roby/test/tools.rb +160 -0
  171. data/lib/roby/thread_task.rb +87 -0
  172. data/lib/roby/transactions.rb +462 -0
  173. data/lib/roby/transactions/proxy.rb +292 -0
  174. data/lib/roby/transactions/updates.rb +139 -0
  175. data/plugins/fault_injection/History.txt +4 -0
  176. data/plugins/fault_injection/README.txt +37 -0
  177. data/plugins/fault_injection/Rakefile +18 -0
  178. data/plugins/fault_injection/TODO.txt +0 -0
  179. data/plugins/fault_injection/app.rb +52 -0
  180. data/plugins/fault_injection/fault_injection.rb +89 -0
  181. data/plugins/fault_injection/test/test_fault_injection.rb +84 -0
  182. data/plugins/subsystems/README.txt +40 -0
  183. data/plugins/subsystems/Rakefile +18 -0
  184. data/plugins/subsystems/app.rb +171 -0
  185. data/plugins/subsystems/test/app/README +24 -0
  186. data/plugins/subsystems/test/app/Rakefile +8 -0
  187. data/plugins/subsystems/test/app/config/app.yml +71 -0
  188. data/plugins/subsystems/test/app/config/init.rb +9 -0
  189. data/plugins/subsystems/test/app/config/roby.yml +3 -0
  190. data/plugins/subsystems/test/app/planners/main.rb +20 -0
  191. data/plugins/subsystems/test/app/scripts/distributed +3 -0
  192. data/plugins/subsystems/test/app/scripts/replay +3 -0
  193. data/plugins/subsystems/test/app/scripts/results +3 -0
  194. data/plugins/subsystems/test/app/scripts/run +3 -0
  195. data/plugins/subsystems/test/app/scripts/server +3 -0
  196. data/plugins/subsystems/test/app/scripts/shell +3 -0
  197. data/plugins/subsystems/test/app/scripts/test +3 -0
  198. data/plugins/subsystems/test/app/tasks/services.rb +15 -0
  199. data/plugins/subsystems/test/test_subsystems.rb +71 -0
  200. data/test/distributed/test_communication.rb +178 -0
  201. data/test/distributed/test_connection.rb +282 -0
  202. data/test/distributed/test_execution.rb +373 -0
  203. data/test/distributed/test_mixed_plan.rb +341 -0
  204. data/test/distributed/test_plan_notifications.rb +238 -0
  205. data/test/distributed/test_protocol.rb +516 -0
  206. data/test/distributed/test_query.rb +102 -0
  207. data/test/distributed/test_remote_plan.rb +491 -0
  208. data/test/distributed/test_transaction.rb +463 -0
  209. data/test/mockups/tasks.rb +27 -0
  210. data/test/planning/test_loops.rb +380 -0
  211. data/test/planning/test_model.rb +427 -0
  212. data/test/planning/test_task.rb +106 -0
  213. data/test/relations/test_conflicts.rb +42 -0
  214. data/test/relations/test_ensured.rb +38 -0
  215. data/test/relations/test_executed_by.rb +149 -0
  216. data/test/relations/test_hierarchy.rb +158 -0
  217. data/test/relations/test_planned_by.rb +54 -0
  218. data/test/suite_core.rb +24 -0
  219. data/test/suite_distributed.rb +9 -0
  220. data/test/suite_planning.rb +3 -0
  221. data/test/suite_relations.rb +8 -0
  222. data/test/test_bgl.rb +508 -0
  223. data/test/test_control.rb +399 -0
  224. data/test/test_event.rb +894 -0
  225. data/test/test_exceptions.rb +592 -0
  226. data/test/test_interface.rb +37 -0
  227. data/test/test_log.rb +114 -0
  228. data/test/test_log_server.rb +132 -0
  229. data/test/test_plan.rb +584 -0
  230. data/test/test_propagation.rb +210 -0
  231. data/test/test_query.rb +266 -0
  232. data/test/test_relations.rb +180 -0
  233. data/test/test_state.rb +414 -0
  234. data/test/test_support.rb +16 -0
  235. data/test/test_task.rb +938 -0
  236. data/test/test_testcase.rb +122 -0
  237. data/test/test_thread_task.rb +73 -0
  238. data/test/test_transactions.rb +569 -0
  239. data/test/test_transactions_proxy.rb +198 -0
  240. metadata +570 -0
@@ -0,0 +1,180 @@
1
+ $LOAD_PATH.unshift File.expand_path('..', File.dirname(__FILE__))
2
+ require 'roby/test/common'
3
+ require 'flexmock'
4
+
5
+ class TC_Relations < Test::Unit::TestCase
6
+ include Roby::Test
7
+
8
+ def test_definition
9
+ klass = Class.new
10
+
11
+ r1, r2 = nil
12
+ space = Roby::RelationSpace(klass)
13
+ r1 = space.relation :R1
14
+ r2 = space.relation :R2s, :child_name => :child, :parent_name => :parent
15
+ assert(Module === space)
16
+
17
+ n = klass.new
18
+ assert_equal(r2, space.constant('R2s'))
19
+ assert( n.respond_to?(:each_child) )
20
+ assert( n.respond_to?(:add_child) )
21
+ assert( n.respond_to?(:remove_child) )
22
+ assert( n.respond_to?(:each_parent) )
23
+ assert( n.respond_to?(:add_r1) )
24
+ assert( n.respond_to?(:add_child) )
25
+ end
26
+
27
+ def test_directed_relation
28
+ klass = Class.new { include DirectedRelationSupport }
29
+
30
+ r1, r2 = nil
31
+ space = Roby::RelationSpace(klass)
32
+ r1 = space.relation :R1
33
+ r2 = space.relation :Child, :parent_name => :parent
34
+
35
+ n1, n2, n3, n4 = 4.enum_for(:times).map { klass.new }
36
+ n1.add_child_object(n2, r1)
37
+ assert_nothing_raised { n1.add_child_object(n2, r1, false) }
38
+ assert_raises(ArgumentError) { n1.add_child_object(n2, r1, true) }
39
+ n1.remove_child_object n2, r1
40
+ assert_nothing_raised { n1.add_child_object(n2, r1) }
41
+ assert_nothing_raised { n1.add_child_object(n2, r1, true) }
42
+ assert_equal([n2], n1.child_objects(r1).to_a)
43
+ assert_equal([n1], n2.parent_objects(r1).to_a)
44
+
45
+ assert( n1.child_object?(n2) )
46
+ assert( n1.child_object?(n2, r1) )
47
+ assert( !n1.child_object?(n2, r2) )
48
+ assert( n2.parent_object?(n1) )
49
+ assert( n2.parent_object?(n1, r1) )
50
+ assert( !n2.parent_object?(n1, r2) )
51
+ assert_equal( [n1], n2.enum_for(:each_parent_object).to_a )
52
+
53
+ n1.add_r1(n3)
54
+ n2.add_child(n4)
55
+
56
+ assert( n1.child_object?(n2) )
57
+ assert( n1.child_object?(n2, r1) )
58
+ assert( !n1.child_object?(n2, r2) )
59
+ assert( n2.parent_object?(n1) )
60
+ assert( n2.parent_object?(n1, r1) )
61
+ assert( !n2.parent_object?(n1, r2) )
62
+ assert_equal( [], n1.enum_for(:each_parent_object).to_a )
63
+ assert_equal( [], n3.enum_for(:each_child_object).to_a )
64
+ assert_equal( [n2, n3].to_set, n1.enum_for(:each_child_object).to_set )
65
+
66
+ assert( n2.related_object?(n1) )
67
+ assert( n2.related_object?(n4) )
68
+
69
+ n2.remove_child_object(n4, r2)
70
+ assert(! n2.child_object?(n4) )
71
+ assert(! n4.parent_object?(n2) )
72
+
73
+ n1.remove_children(r2)
74
+ assert( n1.child_object?(n2) )
75
+ assert( !n1.child_object?(n4) )
76
+ assert( !n4.parent_object?(n1) )
77
+
78
+ n1.remove_child_object(n2)
79
+ assert( !n1.child_object?(n2) )
80
+ assert( !n2.parent_object?(n1) )
81
+
82
+ end
83
+
84
+ def test_hooks
85
+ FlexMock.use do |mock|
86
+ hooks = Module.new do
87
+ define_method(:added_child_object) { |to, relations, info| mock.add(to, relations, info) }
88
+ define_method(:removed_child_object) { |to, relations| mock.remove(to, relations) }
89
+ end
90
+
91
+ klass = Class.new do
92
+ include DirectedRelationSupport
93
+ include hooks
94
+ end
95
+
96
+ r1 = nil
97
+ space = Roby::RelationSpace(klass)
98
+ r1 = space.relation :R1
99
+
100
+ v1, v2 = klass.new, klass.new
101
+ mock.should_receive(:add).with(v2, [r1], 1).once
102
+ mock.should_receive(:remove).with(v2, [r1]).once
103
+ v1.add_r1(v2, 1)
104
+ v1.remove_r1(v2)
105
+ end
106
+ end
107
+
108
+ def test_subsets
109
+ FlexMock.use do |mock|
110
+ klass = Class.new do
111
+ def initialize(index); @index = index end
112
+ def to_s; "v#{@index.to_s}" end
113
+ include DirectedRelationSupport
114
+ define_method(:added_child_object) do |child, relations, info|
115
+ super if defined? super
116
+ mock.hooked_addition(child, relations)
117
+ end
118
+ define_method(:removed_child_object) do |child, relations|
119
+ super if defined? super
120
+ mock.hooked_removal(child, relations)
121
+ end
122
+ end
123
+
124
+ r1, r2 = nil
125
+ space = Roby::RelationSpace(klass)
126
+ r1 = space.relation :R1
127
+ r2 = space.relation :R2, :subsets => [r1]
128
+ assert_equal(r2, r1.parent)
129
+ assert(! r1.subset?(r2))
130
+ assert(r2.subset?(r1))
131
+ assert(!r1.root_relation?)
132
+ assert(r2.root_relation?)
133
+
134
+ n1, n2, n3 = (1..3).map do |i|
135
+ klass.new(i)
136
+ end
137
+
138
+ mock.should_receive(:hooked_addition).with(n2, [r1, r2]).once
139
+ n1.add_child_object(n2, r1)
140
+ assert(n1.child_object?(n2, r2))
141
+
142
+ mock.should_receive(:hooked_addition).with(n3, [r2]).once
143
+ n1.add_child_object(n3, r2)
144
+ assert_equal([n2], n1.enum_for(:each_child_object, r1).to_a)
145
+ assert_equal([n3, n2].to_set, n1.enum_for(:each_child_object, r2).to_set)
146
+
147
+ mock.should_receive(:hooked_removal).with(n2, [r1, r2]).once
148
+ n1.remove_child_object(n2, r1)
149
+
150
+ mock.should_receive(:hooked_removal).with(n3, [r2]).once
151
+ n1.remove_child_object(n3, r2)
152
+ end
153
+ end
154
+
155
+ def test_dag_checking
156
+ klass = Class.new { include DirectedRelationSupport }
157
+ graph = RelationGraph.new("test", :dag => true)
158
+
159
+ v1, v2, v3 = (1..3).map { v = klass.new; graph.insert(v); v }
160
+ graph.add_relation(v1, v2, nil)
161
+ graph.add_relation(v2, v3, nil)
162
+ assert_raises(CycleFoundError) { graph.add_relation(v3, v1, nil) }
163
+ end
164
+
165
+ def test_single_child
166
+ klass = Class.new { include DirectedRelationSupport }
167
+
168
+ r1 = nil
169
+ space = Roby::RelationSpace(klass)
170
+ r1 = space.relation :R1, :single_child => true
171
+ parent = klass.new
172
+ child = klass.new
173
+ assert_equal(nil, parent.r1)
174
+ parent.add_r1(child)
175
+ assert_equal(child, parent.r1)
176
+ parent.remove_r1(child)
177
+ assert_equal(nil, parent.r1)
178
+ end
179
+ end
180
+
@@ -0,0 +1,414 @@
1
+ $LOAD_PATH.unshift File.expand_path('..', File.dirname(__FILE__))
2
+ require 'roby/test/common'
3
+ require 'roby/state/pos'
4
+ require 'flexmock'
5
+ require 'roby/state/events'
6
+
7
+ class TC_State < Test::Unit::TestCase
8
+ include Roby::Test
9
+
10
+ def test_openstruct_behavior
11
+ s = ExtendedStruct.new
12
+ assert( s.respond_to?(:value=) )
13
+ assert( ! s.respond_to?(:value) )
14
+ s.value = 42
15
+ assert( s.respond_to?(:value) )
16
+ assert_equal(42, s.value)
17
+ end
18
+
19
+ def test_update
20
+ s = ExtendedStruct.new
21
+ s.value.update { |v| v.test = 10 }
22
+ assert_equal(10, s.value.test)
23
+
24
+ s.value { |v| v.test = 10 }
25
+ assert_equal(10, s.value.test)
26
+ end
27
+
28
+ def test_send
29
+ s = ExtendedStruct.new
30
+ s.x = 10
31
+ assert_equal(10, s.send(:x))
32
+ end
33
+
34
+ def test_to_hash
35
+
36
+ s = ExtendedStruct.new
37
+ s.a = 10
38
+ s.b.a = 10
39
+
40
+ assert_equal({:a => 10, :b => { :a => 10 }}, s.to_hash)
41
+ assert_equal({:a => 10, :b => s.b}, s.to_hash(false))
42
+ end
43
+
44
+ # Somebody defines Kernel#y, one thing I try to manage
45
+ module ::Kernel
46
+ def y(i)
47
+ end
48
+ end
49
+ def test_does_not_override
50
+ s = ExtendedStruct.new
51
+ assert_raises(ArgumentError) { s.y }
52
+ s.y = 10
53
+ assert_equal(10, s.y)
54
+ end
55
+
56
+ def test_attach
57
+ s = ExtendedStruct.new
58
+ child = s.child
59
+ assert_not_equal(child, s.child)
60
+ child = s.child
61
+ child.send(:attach)
62
+ assert_equal(child, s.child)
63
+
64
+ s = ExtendedStruct.new
65
+ child = s.child
66
+ assert_equal([s, 'child'], child.send(:attach_as))
67
+ s.child = 10
68
+ # child should NOT attach itself to s
69
+ assert_equal(10, s.child)
70
+ assert( !child.send(:attach_as) )
71
+
72
+ child.test = 20
73
+ assert_not_equal(child, s.child)
74
+ assert_equal(10, s.child)
75
+ end
76
+
77
+ def test_delete
78
+ r = ExtendedStruct.new
79
+ assert_raises(ArgumentError) { r.delete }
80
+
81
+ # Check handling of pending children
82
+ child = r.child
83
+ child.delete
84
+ child.value = 10
85
+ assert(!r.child?)
86
+
87
+ child = r.child
88
+ r.delete(:child)
89
+ child.value = 10
90
+ assert(!r.child?)
91
+
92
+ # Check handling of attached children
93
+ r.child.value = 10
94
+ assert(r.child?)
95
+ r.delete(:child)
96
+ assert(!r.child?)
97
+
98
+ r.child.value = 10
99
+ assert(r.child?)
100
+ r.child.delete
101
+ assert(!r.child?)
102
+
103
+ # Check handling of aliases
104
+ r.child.value = 10
105
+ r.alias(:child, :aliased_child)
106
+ assert(r.aliased_child?)
107
+ r.delete(:aliased_child)
108
+ assert(!r.aliased_child?)
109
+
110
+ # Check handling of aliased-to members
111
+ r.child.value = 10
112
+ r.alias(:child, :aliased_child)
113
+ assert(r.aliased_child?)
114
+ r.child.delete
115
+ assert(!r.aliased_child?)
116
+ assert(!r.child?)
117
+ end
118
+
119
+ def test_empty
120
+ r = ExtendedStruct.new
121
+ c = r.child
122
+ assert(r.empty?)
123
+ r.child = 10
124
+ assert(!r.empty?)
125
+ r.delete(:child)
126
+ assert(r.empty?)
127
+ end
128
+
129
+ def test_child_class
130
+ klass = Class.new(ExtendedStruct)
131
+ root = ExtendedStruct.new(klass)
132
+ assert_equal(klass, root.child.class)
133
+ end
134
+
135
+ def test_export
136
+ s = StateSpace.new
137
+ s.pos.x = 42
138
+ s.speed.x = 0
139
+
140
+ obj = Marshal.load(Marshal.dump(s))
141
+ assert(!obj.respond_to?(:pos))
142
+ assert(!obj.respond_to?(:speed))
143
+
144
+ s.export :pos
145
+ obj = Marshal.load(Marshal.dump(s))
146
+ assert(obj.respond_to?(:pos))
147
+ assert(!obj.respond_to?(:speed))
148
+ assert_equal(42, obj.pos.x)
149
+
150
+ s.export :speed
151
+ obj = Marshal.load(Marshal.dump(s))
152
+ assert(obj.respond_to?(:pos))
153
+ assert(obj.respond_to?(:speed))
154
+ assert_equal(42, obj.pos.x)
155
+ assert_equal(0, obj.speed.x)
156
+ end
157
+
158
+ def test_stable
159
+ s = ExtendedStruct.new
160
+ s.other.attach
161
+
162
+ s.stable!
163
+ assert(s.stable?)
164
+ assert(!s.other.stable?)
165
+ assert_raises(NoMethodError) { s.test }
166
+ assert_raises(NoMethodError) { s.test = 10 }
167
+ assert(! s.respond_to?(:test=))
168
+ assert_nothing_raised { s.other.test }
169
+ assert_nothing_raised { s.other.test = 10 }
170
+
171
+ s.stable!(true)
172
+ assert(s.stable?)
173
+ assert_raises(NoMethodError) { s.test }
174
+ assert_raises(NoMethodError) { s.test = 10 }
175
+ assert(s.other.stable?)
176
+ assert_raises(NoMethodError) { s.other.another_test }
177
+ assert_nothing_raised { s.other.test }
178
+ assert_raises(NoMethodError) { s.other.test = 10 }
179
+
180
+ s.stable!(false, false)
181
+ assert(!s.stable?)
182
+ assert_nothing_raised { s.test }
183
+ assert_nothing_raised { s.test = 10 }
184
+ assert(s.other.stable?)
185
+ assert_raises(NoMethodError) { s.other.another_test }
186
+ assert_nothing_raised { s.other.test }
187
+ assert_raises(NoMethodError) { s.other.test = 10 }
188
+
189
+ s.stable!(true, false)
190
+ assert(!s.stable?)
191
+ assert(!s.other.stable?)
192
+ assert_nothing_raised { s.test }
193
+ assert_nothing_raised { s.test = 10 }
194
+ assert_nothing_raised { s.other.test }
195
+ assert_nothing_raised { s.other.test = 10 }
196
+ end
197
+
198
+ def test_filter
199
+ s = ExtendedStruct.new
200
+ s.filter(:test) { |v| Integer === v }
201
+ assert_raises(ArgumentError) { s.test = "10" }
202
+ assert_nothing_raised { s.test = 10 }
203
+ end
204
+
205
+ def test_alias
206
+ s = ExtendedStruct.new
207
+ s.value = 42
208
+ s.alias(:value, :test)
209
+ assert( s.respond_to?(:test) )
210
+ assert_equal(42, s.value)
211
+ assert_equal(42, s.test)
212
+ s.value = Time.now
213
+ assert_equal(s.test, s.value)
214
+
215
+ # Test alias detach
216
+ s.test = 10
217
+ s.value = 42
218
+ assert_equal(10, s.test)
219
+ end
220
+
221
+ def test_change_notification
222
+ s = ExtendedStruct.new
223
+ FlexMock.use do |mock|
224
+ s.on(:value) { |v| mock.updated(v) }
225
+ mock.should_receive(:updated).with(42).once
226
+ s.value = 42
227
+
228
+ s.on(:substruct) { |v| mock.updated_substruct(v.value) }
229
+ mock.should_receive(:updated_substruct).with(24).once.ordered
230
+ mock.should_receive(:updated_substruct).with(42).once.ordered
231
+ s.substruct.value = 24
232
+ s.substruct.value = 42
233
+ end
234
+ end
235
+
236
+ def test_predicate
237
+ s = ExtendedStruct.new
238
+ s.a = false
239
+ s.b = 1
240
+ assert(!s.foobar?)
241
+ assert(!s.a?)
242
+ assert(s.b?)
243
+ end
244
+
245
+ def test_marshalling
246
+ s = ExtendedStruct.new
247
+ s.value = 42
248
+ s.substruct.value = 24
249
+ s.invalid = Proc.new {}
250
+
251
+ s.on(:substruct) {}
252
+ s.filter(:value) { |v| Numeric === v }
253
+
254
+ str = nil
255
+ assert_nothing_raised { str = Marshal.dump(s) }
256
+ assert_nothing_raised { s = Marshal.load(str) }
257
+ assert_equal(42, s.value)
258
+ assert_equal(24, s.substruct.value)
259
+ assert(!s.respond_to?(:invalid))
260
+ end
261
+
262
+ def test_forbidden_names
263
+ s = ExtendedStruct.new
264
+ assert_raises(NoMethodError) { s.each_blah }
265
+ assert_nothing_raised { s.blato }
266
+ assert_raises(NoMethodError) { s.enum_blah }
267
+ assert_raises(NoMethodError) { s.to_blah }
268
+ end
269
+
270
+ def test_pos_euler3d
271
+ p = Pos::Euler3D.new(30)
272
+ assert_equal(30, p.x)
273
+ assert_equal(0, p.y)
274
+ assert_equal(0, p.z)
275
+
276
+ assert_equal(10, p.distance(30, 10))
277
+ assert_equal(0, p.distance(p))
278
+ assert_equal(0, Pos::Vector3D.new(30, 10, 50).distance2d(30, 10))
279
+
280
+ assert_equal(Pos::Vector3D.new(-30), -p)
281
+ end
282
+
283
+ def test_pos_delta_event
284
+ State.pos = Pos::Euler3D.new
285
+
286
+ plan.discover(d = State.on_delta(:d => 10))
287
+ assert_kind_of(PosDeltaEvent, d)
288
+ d.poll
289
+ assert_equal(State.pos, d.last_value)
290
+ assert(!d.happened?)
291
+
292
+ State.pos.x = 5
293
+ d.poll
294
+ assert(!d.happened?)
295
+
296
+ State.pos.x = 10
297
+ d.poll
298
+ assert(1, d.history.size)
299
+
300
+ d.poll
301
+ assert(1, d.history.size)
302
+
303
+ State.pos.x = 0
304
+ d.poll
305
+ assert(2, d.history.size)
306
+ end
307
+
308
+ def test_yaw_delta_event
309
+ State.pos = Pos::Euler3D.new
310
+
311
+ plan.discover(y = State.on_delta(:yaw => 2))
312
+ assert_kind_of(YawDeltaEvent, y)
313
+ y.poll
314
+ assert_equal(0, y.last_value)
315
+
316
+ assert(!y.happened?)
317
+ State.pos.yaw = 20
318
+ y.poll
319
+ assert(y.happened?)
320
+
321
+ y.poll
322
+ assert(1, y.history.size)
323
+
324
+ State.pos.yaw = 0
325
+ y.poll
326
+ assert(2, y.history.size)
327
+ end
328
+
329
+ def test_time_delta_event
330
+ plan.discover(t = State.on_delta(:t => 3600))
331
+ assert_kind_of(TimeDeltaEvent, t)
332
+
333
+ t.poll
334
+ assert(!t.happened?)
335
+ sleep(0.5)
336
+ t.poll
337
+ assert(!t.happened?)
338
+
339
+ t.instance_variable_set(:@last_value, Time.now - 3600)
340
+ t.poll
341
+ assert(1, t.history.size)
342
+ end
343
+
344
+ def test_timepoint_event
345
+ plan.discover(ev = State.at(:t => Time.now + 0.5))
346
+ ev.poll
347
+ assert(!ev.happened?)
348
+ sleep(0.5)
349
+ ev.poll
350
+ assert(ev.happened?)
351
+ sleep(0.5)
352
+ ev.poll
353
+ assert_equal(1, ev.history.size)
354
+ end
355
+
356
+ def test_and_state_events
357
+ State.pos = Pos::Euler3D.new
358
+ plan.discover(ev = State.on_delta(:yaw => 2, :d => 10))
359
+ assert_kind_of(AndGenerator, ev)
360
+
361
+ Roby.poll_state_events
362
+ assert_equal(0, ev.history.size)
363
+
364
+ State.pos.yaw = 1
365
+ State.pos.x = 15
366
+ Roby.poll_state_events
367
+ assert_equal(0, ev.history.size)
368
+
369
+ State.pos.yaw = 2
370
+ Roby.poll_state_events
371
+ assert_equal(1, ev.history.size)
372
+
373
+ State.pos.yaw = 3
374
+ State.pos.x = 25
375
+ Roby.poll_state_events
376
+ assert_equal(1, ev.history.size)
377
+
378
+ State.pos.yaw = 4
379
+ Roby.poll_state_events
380
+ assert_equal(2, ev.history.size, ev.waiting.to_a)
381
+ end
382
+
383
+ def test_or_state_events
384
+ State.pos = Pos::Euler3D.new
385
+ plan.discover(y = State.on_delta(:yaw => 2))
386
+
387
+ ev = y.or(:d => 10)
388
+ Roby.poll_state_events
389
+ assert_equal(0, ev.history.size)
390
+
391
+ State.pos.yaw = 1
392
+ State.pos.x = 15
393
+ Roby.poll_state_events
394
+ assert_equal(1, ev.history.size)
395
+
396
+ State.pos.yaw = 2
397
+ Roby.poll_state_events
398
+ assert_equal(1, ev.history.size)
399
+
400
+ State.pos.yaw = 3
401
+ Roby.poll_state_events
402
+ assert_equal(2, ev.history.size)
403
+
404
+ ev = ev.or(:t => 3600)
405
+ Roby.poll_state_events
406
+ assert_equal(0, ev.history.size)
407
+
408
+ time_event = plan.free_events.find { |t| t.kind_of?(TimeDeltaEvent) }
409
+ time_event.instance_variable_set(:@last_value, Time.now - 3600)
410
+ Roby.poll_state_events
411
+ assert_equal(1, ev.history.size)
412
+ end
413
+ end
414
+