gisele-vm 0.6.0

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 (185) hide show
  1. data/CHANGELOG.md +5 -0
  2. data/Gemfile +18 -0
  3. data/Gemfile.lock +46 -0
  4. data/LICENCE.md +22 -0
  5. data/Manifest.txt +15 -0
  6. data/README.md +10 -0
  7. data/Rakefile +11 -0
  8. data/bin/gvm +9 -0
  9. data/gisele-vm.gemspec +191 -0
  10. data/gisele-vm.noespec +31 -0
  11. data/lib/gisele-vm.rb +4 -0
  12. data/lib/gisele-vm/loader.rb +5 -0
  13. data/lib/gisele-vm/version.rb +16 -0
  14. data/lib/gisele/compiling.rb +3 -0
  15. data/lib/gisele/compiling/gisele2gts.rb +143 -0
  16. data/lib/gisele/compiling/gts.rb +74 -0
  17. data/lib/gisele/compiling/gts2bytecode.rb +127 -0
  18. data/lib/gisele/vm.rb +87 -0
  19. data/lib/gisele/vm/bytecode.rb +84 -0
  20. data/lib/gisele/vm/bytecode/builder.rb +77 -0
  21. data/lib/gisele/vm/bytecode/grammar.citrus +116 -0
  22. data/lib/gisele/vm/bytecode/grammar.rb +19 -0
  23. data/lib/gisele/vm/bytecode/grammar.sexp.yml +113 -0
  24. data/lib/gisele/vm/bytecode/printer.rb +35 -0
  25. data/lib/gisele/vm/command.rb +140 -0
  26. data/lib/gisele/vm/component.rb +91 -0
  27. data/lib/gisele/vm/console.rb +58 -0
  28. data/lib/gisele/vm/enacter.rb +29 -0
  29. data/lib/gisele/vm/errors.rb +26 -0
  30. data/lib/gisele/vm/event.rb +11 -0
  31. data/lib/gisele/vm/event_manager.rb +65 -0
  32. data/lib/gisele/vm/kernel.rb +58 -0
  33. data/lib/gisele/vm/kernel/macros.gvm +214 -0
  34. data/lib/gisele/vm/kernel/opcodes.rb +212 -0
  35. data/lib/gisele/vm/kernel/runner.rb +63 -0
  36. data/lib/gisele/vm/lifecycle.rb +72 -0
  37. data/lib/gisele/vm/logging.rb +18 -0
  38. data/lib/gisele/vm/null_object.rb +19 -0
  39. data/lib/gisele/vm/prog.rb +63 -0
  40. data/lib/gisele/vm/prog_list.rb +55 -0
  41. data/lib/gisele/vm/prog_list/memory.rb +74 -0
  42. data/lib/gisele/vm/prog_list/sqldb.rb +123 -0
  43. data/lib/gisele/vm/prog_list/storage.rb +31 -0
  44. data/lib/gisele/vm/proxy.rb +14 -0
  45. data/lib/gisele/vm/proxy/client.rb +64 -0
  46. data/lib/gisele/vm/proxy/server.rb +29 -0
  47. data/lib/gisele/vm/registry.rb +57 -0
  48. data/lib/gisele/vm/robustness.rb +31 -0
  49. data/lib/gisele/vm/simulator/resumer.rb +32 -0
  50. data/spec/command/gvm_compile.cmd +1 -0
  51. data/spec/command/gvm_compile.stdout +111 -0
  52. data/spec/command/gvm_gts.cmd +1 -0
  53. data/spec/command/gvm_gts.stdout +101 -0
  54. data/spec/command/gvm_help.cmd +1 -0
  55. data/spec/command/gvm_help.stdout +30 -0
  56. data/spec/command/gvm_version.cmd +1 -0
  57. data/spec/command/gvm_version.stdout +2 -0
  58. data/spec/command/test_command.rb +29 -0
  59. data/spec/fixtures/complete.gis +13 -0
  60. data/spec/fixtures/fake_component.rb +24 -0
  61. data/spec/fixtures/kernel.rb +39 -0
  62. data/spec/fixtures/ts.adl +11 -0
  63. data/spec/fixtures/ts.gts +20 -0
  64. data/spec/fixtures/ts.gvm +19 -0
  65. data/spec/spec_helper.rb +86 -0
  66. data/spec/test_examples.rb +29 -0
  67. data/spec/test_gisele-vm.rb +8 -0
  68. data/spec/unit/bytecode/builder/test_at.rb +56 -0
  69. data/spec/unit/bytecode/builder/test_helpers.rb +36 -0
  70. data/spec/unit/bytecode/builder/test_instruction.rb +35 -0
  71. data/spec/unit/bytecode/builder/test_to_a.rb +53 -0
  72. data/spec/unit/bytecode/bytecode.gvm +1 -0
  73. data/spec/unit/bytecode/grammar/fixtures/comments.gvm +16 -0
  74. data/spec/unit/bytecode/grammar/fixtures/every.gvm +46 -0
  75. data/spec/unit/bytecode/grammar/fixtures/singleblock.gvm +2 -0
  76. data/spec/unit/bytecode/grammar/fixtures/twoblocks.gvm +4 -0
  77. data/spec/unit/bytecode/grammar/fixtures/with_end.gvm +5 -0
  78. data/spec/unit/bytecode/grammar/test_array.rb +24 -0
  79. data/spec/unit/bytecode/grammar/test_block.rb +35 -0
  80. data/spec/unit/bytecode/grammar/test_boolean.rb +20 -0
  81. data/spec/unit/bytecode/grammar/test_constant.rb +20 -0
  82. data/spec/unit/bytecode/grammar/test_eol.rb +20 -0
  83. data/spec/unit/bytecode/grammar/test_eol_comment.rb +36 -0
  84. data/spec/unit/bytecode/grammar/test_file.rb +38 -0
  85. data/spec/unit/bytecode/grammar/test_hash.rb +33 -0
  86. data/spec/unit/bytecode/grammar/test_instruction.rb +32 -0
  87. data/spec/unit/bytecode/grammar/test_int.rb +24 -0
  88. data/spec/unit/bytecode/grammar/test_label.rb +24 -0
  89. data/spec/unit/bytecode/grammar/test_opcode.rb +23 -0
  90. data/spec/unit/bytecode/grammar/test_string.rb +25 -0
  91. data/spec/unit/bytecode/grammar/test_symbol.rb +30 -0
  92. data/spec/unit/bytecode/test_build.rb +36 -0
  93. data/spec/unit/bytecode/test_coerce.rb +41 -0
  94. data/spec/unit/bytecode/test_fetch.rb +20 -0
  95. data/spec/unit/bytecode/test_grammar.rb +30 -0
  96. data/spec/unit/bytecode/test_parse.rb +22 -0
  97. data/spec/unit/bytecode/test_plus.rb +27 -0
  98. data/spec/unit/bytecode/test_to_a.rb +19 -0
  99. data/spec/unit/bytecode/test_to_s.rb +32 -0
  100. data/spec/unit/command/code.gis +3 -0
  101. data/spec/unit/command/test_vm.rb +51 -0
  102. data/spec/unit/compiling/gisele2gts/test_on_par_st.rb +51 -0
  103. data/spec/unit/compiling/gisele2gts/test_on_seq_st.rb +46 -0
  104. data/spec/unit/compiling/gisele2gts/test_on_task_call_st.rb +37 -0
  105. data/spec/unit/compiling/gisele2gts/test_on_task_def.rb +49 -0
  106. data/spec/unit/compiling/gisele2gts/test_on_unit_def.rb +35 -0
  107. data/spec/unit/compiling/gts2bytecode/test_on_end.rb +31 -0
  108. data/spec/unit/compiling/gts2bytecode/test_on_event.rb +37 -0
  109. data/spec/unit/compiling/gts2bytecode/test_on_fork.rb +41 -0
  110. data/spec/unit/compiling/gts2bytecode/test_on_join.rb +42 -0
  111. data/spec/unit/compiling/gts2bytecode/test_on_listen.rb +36 -0
  112. data/spec/unit/compiling/gts2bytecode/test_on_nop.rb +30 -0
  113. data/spec/unit/component/test_component_name.rb +16 -0
  114. data/spec/unit/component/test_logging.rb +36 -0
  115. data/spec/unit/enacter/test_component.rb +11 -0
  116. data/spec/unit/event/test_to_s.rb +12 -0
  117. data/spec/unit/event_manager/test_component.rb +9 -0
  118. data/spec/unit/event_manager/test_subscribe.rb +40 -0
  119. data/spec/unit/event_manager/test_unsubscribe.rb +39 -0
  120. data/spec/unit/kernel/macros/test_fork.rb +37 -0
  121. data/spec/unit/kernel/macros/test_join.rb +43 -0
  122. data/spec/unit/kernel/macros/test_listen.rb +37 -0
  123. data/spec/unit/kernel/macros/test_notify.rb +57 -0
  124. data/spec/unit/kernel/macros/test_react.rb +47 -0
  125. data/spec/unit/kernel/macros/test_schedule_at.rb +30 -0
  126. data/spec/unit/kernel/opcodes/test_op_del.rb +42 -0
  127. data/spec/unit/kernel/opcodes/test_op_event.rb +25 -0
  128. data/spec/unit/kernel/opcodes/test_op_fetch.rb +27 -0
  129. data/spec/unit/kernel/opcodes/test_op_flip.rb +17 -0
  130. data/spec/unit/kernel/opcodes/test_op_fold.rb +29 -0
  131. data/spec/unit/kernel/opcodes/test_op_fork.rb +63 -0
  132. data/spec/unit/kernel/opcodes/test_op_forka.rb +51 -0
  133. data/spec/unit/kernel/opcodes/test_op_get.rb +62 -0
  134. data/spec/unit/kernel/opcodes/test_op_getr.rb +48 -0
  135. data/spec/unit/kernel/opcodes/test_op_ifenil.rb +41 -0
  136. data/spec/unit/kernel/opcodes/test_op_ifezero.rb +32 -0
  137. data/spec/unit/kernel/opcodes/test_op_invoke.rb +34 -0
  138. data/spec/unit/kernel/opcodes/test_op_nop.rb +18 -0
  139. data/spec/unit/kernel/opcodes/test_op_parent.rb +39 -0
  140. data/spec/unit/kernel/opcodes/test_op_pop.rb +22 -0
  141. data/spec/unit/kernel/opcodes/test_op_push.rb +17 -0
  142. data/spec/unit/kernel/opcodes/test_op_save.rb +32 -0
  143. data/spec/unit/kernel/opcodes/test_op_savea.rb +34 -0
  144. data/spec/unit/kernel/opcodes/test_op_self.rb +20 -0
  145. data/spec/unit/kernel/opcodes/test_op_send.rb +20 -0
  146. data/spec/unit/kernel/opcodes/test_op_set.rb +61 -0
  147. data/spec/unit/kernel/opcodes/test_op_then.rb +50 -0
  148. data/spec/unit/kernel/opcodes/test_op_unfold.rb +22 -0
  149. data/spec/unit/kernel/opcodes/test_op_uuid.rb +16 -0
  150. data/spec/unit/kernel/runner/test_pop.rb +26 -0
  151. data/spec/unit/kernel/runner/test_stack.rb +28 -0
  152. data/spec/unit/kernel/test_progress.rb +47 -0
  153. data/spec/unit/kernel/test_resume.rb +53 -0
  154. data/spec/unit/kernel/test_start.rb +36 -0
  155. data/spec/unit/prog/test_to_hash.rb +29 -0
  156. data/spec/unit/prog/test_waitlist_eq.rb +20 -0
  157. data/spec/unit/prog_list/memory/test_component.rb +9 -0
  158. data/spec/unit/prog_list/memory/test_fetch.rb +40 -0
  159. data/spec/unit/prog_list/memory/test_pick.rb +39 -0
  160. data/spec/unit/prog_list/memory/test_save.rb +91 -0
  161. data/spec/unit/prog_list/memory/test_to_relation.rb +17 -0
  162. data/spec/unit/prog_list/sqldb/test_component.rb +11 -0
  163. data/spec/unit/prog_list/sqldb/test_connect.rb +46 -0
  164. data/spec/unit/prog_list/test_memory.rb +9 -0
  165. data/spec/unit/prog_list/test_sqldb.rb +13 -0
  166. data/spec/unit/prog_list/test_storage.rb +51 -0
  167. data/spec/unit/registry/test_component.rb +9 -0
  168. data/spec/unit/registry/test_connect.rb +53 -0
  169. data/spec/unit/registry/test_disconnect.rb +51 -0
  170. data/spec/unit/registry/test_registration.rb +44 -0
  171. data/spec/unit/shared/a_component.rb +49 -0
  172. data/spec/unit/shared/a_storage.rb +114 -0
  173. data/spec/unit/test_logging.rb +46 -0
  174. data/spec/unit/test_prog.rb +57 -0
  175. data/spec/unit/test_prog_list.rb +22 -0
  176. data/spec/unit/vm/test_event_facace.rb +11 -0
  177. data/spec/unit/vm/test_initialize.rb +59 -0
  178. data/spec/unit/vm/test_proglist_facade.rb +21 -0
  179. data/tasks/debug_mail.rake +75 -0
  180. data/tasks/debug_mail.txt +13 -0
  181. data/tasks/gem.rake +73 -0
  182. data/tasks/spec_test.rake +71 -0
  183. data/tasks/unit_test.rake +76 -0
  184. data/tasks/yard.rake +51 -0
  185. metadata +493 -0
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ module Compiling
4
+ describe Gts2Bytecode, "on_event" do
5
+
6
+ let(:gts) do
7
+ Gts.new do
8
+ add_state :kind => :event
9
+ add_state :kind => :nop
10
+ connect(0, 1, :symbol => :hello, :event_args => [ "world" ])
11
+ end
12
+ end
13
+ let(:compiler){ Gts2Bytecode.new }
14
+ let(:bytecode){ compiler.builder.to_a }
15
+
16
+ before do
17
+ subject
18
+ end
19
+
20
+ subject do
21
+ compiler.on_event(gts.ith_state(0))
22
+ end
23
+
24
+ it 'should generate the expected bytecode' do
25
+ bytecode.should eq([:gvm,
26
+ [:block, :s0,
27
+ [:then, :s1],
28
+ [:then, :e0]],
29
+ [:block, :e0,
30
+ [:push, [ "world"] ],
31
+ [:event, :hello] ]
32
+ ])
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ module Compiling
4
+ describe Gts2Bytecode, "on_fork" do
5
+
6
+ let(:gts) do
7
+ Gts.new do
8
+ add_state :kind => :fork
9
+ add_state :kind => :join
10
+ add_state :kind => :event
11
+ add_state :kind => :event
12
+ connect(0, 1, :symbol => :"(wait)")
13
+ connect(0, 2, :symbol => :"(forked#1)")
14
+ connect(0, 3, :symbol => :"(forked#2)")
15
+ connect(2, 1, :symbol => :ping)
16
+ connect(3, 1, :symbol => :pong)
17
+ end
18
+ end
19
+ let(:compiler){ Gts2Bytecode.new }
20
+ let(:bytecode){ compiler.builder.to_a }
21
+
22
+ before do
23
+ subject
24
+ end
25
+
26
+ subject do
27
+ compiler.on_fork(gts.ith_state(0))
28
+ end
29
+
30
+ it 'should generate the expected bytecode' do
31
+ bytecode.should eq([:gvm,
32
+ [:block, :s0,
33
+ [:push, :s1],
34
+ [:push, [:s2, :s3]],
35
+ [:then, :fork]]
36
+ ])
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ module Compiling
4
+ describe Gts2Bytecode, "on_join" do
5
+
6
+ let(:gts) do
7
+ Gts.new do
8
+ add_state :kind => :fork
9
+ add_state :kind => :join
10
+ add_state :kind => :event
11
+ add_state :kind => :event
12
+ add_state :kind => :end
13
+ connect(0, 1, :symbol => :"(wait)")
14
+ connect(0, 2, :symbol => :"(forked#1)")
15
+ connect(0, 3, :symbol => :"(forked#2)")
16
+ connect(2, 1, :symbol => :ping)
17
+ connect(3, 1, :symbol => :pong)
18
+ connect(1, 4, :symbol => nil)
19
+ end
20
+ end
21
+ let(:compiler){ Gts2Bytecode.new }
22
+ let(:bytecode){ compiler.builder.to_a }
23
+
24
+ before do
25
+ subject
26
+ end
27
+
28
+ subject do
29
+ compiler.on_join(gts.ith_state(1))
30
+ end
31
+
32
+ it 'should generate the expected bytecode' do
33
+ bytecode.should eq([:gvm,
34
+ [:block, :s1,
35
+ [:push, {:wake => :s4}],
36
+ [:then, :join]]
37
+ ])
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ module Compiling
4
+ describe Gts2Bytecode, "on_listen" do
5
+
6
+ let(:gts) do
7
+ Gts.new do
8
+ add_state :kind => :listen
9
+ add_state :kind => :nop
10
+ add_state :kind => :nop
11
+ connect(0, 1, :symbol => :ping)
12
+ connect(0, 2, :symbol => :pong)
13
+ end
14
+ end
15
+ let(:compiler){ Gts2Bytecode.new }
16
+ let(:bytecode){ compiler.builder.to_a }
17
+
18
+ before do
19
+ subject
20
+ end
21
+
22
+ subject do
23
+ compiler.on_listen(gts.ith_state(0))
24
+ end
25
+
26
+ it 'should generate the expected bytecode' do
27
+ bytecode.should eq([:gvm,
28
+ [:block, :s0,
29
+ [:push, {:ping=>:s1, :pong=>:s2}],
30
+ [:then, :listen]]
31
+ ])
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ module Compiling
4
+ describe Gts2Bytecode, "on_nop" do
5
+
6
+ let(:gts) do
7
+ Gts.new do
8
+ add_state :kind => :nop
9
+ add_state :kind => :nop
10
+ connect(0, 1, :symbol => nil)
11
+ end
12
+ end
13
+ let(:compiler){ Gts2Bytecode.new }
14
+ let(:bytecode){ compiler.builder.to_a }
15
+
16
+ before do
17
+ subject
18
+ end
19
+
20
+ subject do
21
+ compiler.on_nop(gts.ith_state(0))
22
+ end
23
+
24
+ it 'should generate the expected bytecode' do
25
+ bytecode.should eq([:gvm, [:block, :s0, [:then, :s1]]])
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Component, "component_name" do
5
+
6
+ class FooComponent < VM::Component
7
+ public :component_name
8
+ end
9
+
10
+ it 'uses the class name by default' do
11
+ FooComponent.new.component_name.should eq("FooComponent")
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Component, "logging delegation" do
5
+
6
+ let(:component){ Component.new }
7
+
8
+ context 'without vm' do
9
+
10
+ it 'uses a NullObject to avoid failing' do
11
+ component.vm.should be_a(NullObject)
12
+ end
13
+
14
+ it 'delegates logger methods to it' do
15
+ lambda{
16
+ component.info("message")
17
+ }.should_not raise_error
18
+ end
19
+
20
+ end # without vm
21
+
22
+ context 'with a vm' do
23
+
24
+ before do
25
+ component.registered Struct.new(:info).new("blah")
26
+ end
27
+
28
+ it 'delegates logger methods to it' do
29
+ component.info.should eq("blah")
30
+ end
31
+
32
+ end # with a vm
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Enacter do
5
+ subject{ Enacter.new }
6
+ pending{
7
+ it_should_behave_like "a component"
8
+ }
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module Gisele
2
+ class VM
3
+ describe Event, "to_s" do
4
+
5
+ it 'works as expected' do
6
+ expected = "start[17](Ping, 3)"
7
+ Event.new(Prog.new(:puid => 17), :start, ["Ping", "3"]).to_s.should eq(expected)
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe EventManager do
5
+ subject{ EventManager.new }
6
+ it_should_behave_like "a component"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe EventManager, 'subscribe' do
5
+
6
+ let(:publisher) { EventManager.new }
7
+ let(:subscriber){ lambda{|event| } }
8
+
9
+ after do
10
+ publisher.subscribed?(subscriber).should be_true
11
+ end
12
+
13
+ context 'when not connected' do
14
+ it 'subscribes a block correctly' do
15
+ publisher.subscribe(&subscriber)
16
+ end
17
+ it 'subscribes a Proc correctly' do
18
+ publisher.subscribe(subscriber)
19
+ end
20
+ end
21
+
22
+ context 'when connected' do
23
+ before do
24
+ publisher.registered(vm)
25
+ publisher.connect
26
+ end
27
+ after do
28
+ publisher.send(:name_of, subscriber).should_not be_nil
29
+ end
30
+ it 'subscribes a block to EM' do
31
+ publisher.subscribe(&subscriber)
32
+ end
33
+ it 'subscribes a Proc to EM' do
34
+ publisher.subscribe(subscriber)
35
+ end
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe EventManager, 'unsubscribe' do
5
+
6
+ let(:publisher) { EventManager.new }
7
+ let(:subscriber){ lambda{|event| } }
8
+
9
+ after do
10
+ publisher.subscribed?(subscriber).should be_false
11
+ end
12
+
13
+ context 'when not connected' do
14
+ it 'does nothing when not previously subscribed' do
15
+ publisher.unsubscribe(subscriber).should be_nil
16
+ end
17
+ it 'unsubscribes a block previously subscribed' do
18
+ publisher.subscribe(subscriber)
19
+ publisher.unsubscribe(subscriber)
20
+ end
21
+ end
22
+
23
+ context 'when connected' do
24
+ before do
25
+ publisher.registered(vm)
26
+ publisher.connect
27
+ end
28
+ after do
29
+ publisher.send(:name_of, subscriber).should be_nil
30
+ end
31
+ it 'unsubscribes a Proc to EM' do
32
+ publisher.subscribe(subscriber)
33
+ publisher.unsubscribe(subscriber)
34
+ end
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "fork macro" do
5
+
6
+ let(:runn) { runner(@parent) }
7
+ let(:parent){ list.fetch(@parent) }
8
+
9
+ before do
10
+ @parent = list.save Prog.new(:pc => :fork, :root => 16)
11
+ subject
12
+ end
13
+
14
+ subject do
15
+ runn.run(:fork, [ :joinat, [ :fat1, :fat2 ] ])
16
+ end
17
+
18
+ after do
19
+ runn.stack.should be_empty
20
+ end
21
+
22
+ it 'sets the events as waitlist' do
23
+ parent.waitlist.should eq({@parent+1 => true, @parent+2 => true})
24
+ end
25
+
26
+ it 'fork and schedules self and children correctly' do
27
+ expected = Relation([
28
+ {:puid => @parent, :pc => :joinat, :parent => @parent, :root => 16, :waitfor => :children},
29
+ {:puid => @parent+1, :pc => :fat1, :parent => @parent, :root => 16, :waitfor => :enacter },
30
+ {:puid => @parent+2, :pc => :fat2, :parent => @parent, :root => 16, :waitfor => :enacter }
31
+ ])
32
+ list.to_relation.project([:puid, :pc, :parent, :root, :waitfor]).should eq(expected)
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "join macro" do
5
+
6
+ let(:runn) { runner(@parent) }
7
+ let(:parent){ list.fetch(@parent) }
8
+
9
+ before do
10
+ @parent = list.save Prog.new(:pc => :blah, :waitlist => wlist, :waitfor => :enacter)
11
+ subject
12
+ end
13
+
14
+ subject do
15
+ runn.run(:join, [ {:wake => :wakeat} ])
16
+ end
17
+
18
+ after do
19
+ runn.stack.should be_empty
20
+ end
21
+
22
+ context 'when the waitlist is not empty' do
23
+ let(:wlist){ {12 => true, 13 => true} }
24
+
25
+ it 'keeps the program sleeping' do
26
+ parent.pc.should eq(:blah)
27
+ parent.waitfor.should eq(:children)
28
+ end
29
+ end
30
+
31
+ context 'when the waitlist is empty' do
32
+ let(:wlist){ {} }
33
+
34
+ it 'schedules the program at :wakeat' do
35
+ parent.pc.should eq(:wakeat)
36
+ parent.waitlist.should eq({})
37
+ parent.waitfor.should eq(:enacter)
38
+ end
39
+ end
40
+
41
+ end
42
+ end
43
+ end