roby 0.7

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.
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
+