edoors-ruby 0.0.6
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 +2 -0
- data/.travis.yml +7 -0
- data/Changelog +23 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +28 -0
- data/LICENSE +661 -0
- data/README.md +18 -0
- data/Rakefile +6 -0
- data/bin/edoors.rb +71 -0
- data/edoors-ruby.gemspec +28 -0
- data/examples/hello_world.json +38 -0
- data/examples/hello_world.rb +76 -0
- data/lib/edoors.rb +51 -0
- data/lib/edoors/board.rb +69 -0
- data/lib/edoors/door.rb +95 -0
- data/lib/edoors/iota.rb +67 -0
- data/lib/edoors/link.rb +70 -0
- data/lib/edoors/particle.rb +235 -0
- data/lib/edoors/room.rb +190 -0
- data/lib/edoors/spin.rb +168 -0
- data/lib/version.rb +28 -0
- data/spec/board_spec.rb +92 -0
- data/spec/door_spec.rb +95 -0
- data/spec/link_spec.rb +38 -0
- data/spec/particle_spec.rb +266 -0
- data/spec/room_spec.rb +315 -0
- data/spec/spec_helper.rb +38 -0
- data/spec/spin_spec.rb +132 -0
- data/spec/spot_spec.rb +26 -0
- data/test/test_iotas.rb +168 -0
- metadata +136 -0
data/lib/edoors/spin.rb
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
#
|
4
|
+
# Copyright 2012 Jérémy Zurcher <jeremy@asynk.ch>
|
5
|
+
#
|
6
|
+
# This file is part of edoors-ruby.
|
7
|
+
#
|
8
|
+
# edoors-ruby is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU Affero General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# edoors-ruby is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU Affero General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU Affero General Public License
|
19
|
+
# along with edoors-ruby. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
|
21
|
+
#
|
22
|
+
module Edoors
|
23
|
+
#
|
24
|
+
class Spin < Room
|
25
|
+
#
|
26
|
+
def initialize n, o={}
|
27
|
+
super n, nil
|
28
|
+
#
|
29
|
+
@pool = {} # per particle class free list
|
30
|
+
@world = {} # global iotas index
|
31
|
+
@sys_fifo = [] # system particles fifo list
|
32
|
+
@app_fifo = [] # application particles fifo list
|
33
|
+
#
|
34
|
+
@run = false
|
35
|
+
@hibernation = o['hibernation']||false
|
36
|
+
@hibernate_path = 'edoors-hibernate-'+n+'.json'
|
37
|
+
@debug_errors = o[:debug_errors]||o['debug_errors']||false
|
38
|
+
@debug_routing = o[:debug_routing]||o['debug_routing']||false
|
39
|
+
#
|
40
|
+
if not o.empty?
|
41
|
+
room = o['inner_room']
|
42
|
+
if room
|
43
|
+
room['iotas'].each do |name,iota|
|
44
|
+
eval( iota['kls'] ).json_create(iota.merge!('parent'=>self))
|
45
|
+
end
|
46
|
+
room['links'].each do |src,links|
|
47
|
+
links.each do |link|
|
48
|
+
add_link Edoors::Link.json_create(link)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
o['app_fifo'].each do |particle|
|
53
|
+
@app_fifo << Edoors::Particle.json_create(particle.merge!('spin'=>self))
|
54
|
+
end if o['app_fifo']
|
55
|
+
o['sys_fifo'].each do |particle|
|
56
|
+
@sys_fifo << Edoors::Particle.json_create(particle.merge!('spin'=>self))
|
57
|
+
end if o['sys_fifo']
|
58
|
+
end
|
59
|
+
end
|
60
|
+
#
|
61
|
+
attr_accessor :run, :hibernate_path, :debug_errors, :debug_routing
|
62
|
+
#
|
63
|
+
def to_json *a
|
64
|
+
{
|
65
|
+
'kls' => self.class.name,
|
66
|
+
'timestamp' => Time.now,
|
67
|
+
'name' => @name,
|
68
|
+
'hibernation' => @hibernation,
|
69
|
+
'inner_room' => { :iotas=>@iotas, :links=>@links },
|
70
|
+
'sys_fifo' => @sys_fifo,
|
71
|
+
'app_fifo' => @app_fifo,
|
72
|
+
'debug_errors' => @debug_errors,
|
73
|
+
'debug_routing' => @debug_routing
|
74
|
+
}.to_json(*a)
|
75
|
+
end
|
76
|
+
#
|
77
|
+
def self.json_create o
|
78
|
+
raise Edoors::Exception.new "JSON #{o['kls']} != #{self.name}" if o['kls'] != self.name
|
79
|
+
self.new o['name'], o
|
80
|
+
end
|
81
|
+
#
|
82
|
+
def add_to_world iota
|
83
|
+
@world[iota.path] = iota
|
84
|
+
end
|
85
|
+
#
|
86
|
+
def search_world path
|
87
|
+
@world[path]
|
88
|
+
end
|
89
|
+
#
|
90
|
+
def clear!
|
91
|
+
@iotas.clear
|
92
|
+
@world.clear
|
93
|
+
@pool.clear
|
94
|
+
@sys_fifo.clear
|
95
|
+
@app_fifo.clear
|
96
|
+
end
|
97
|
+
#
|
98
|
+
#
|
99
|
+
def release_p p
|
100
|
+
# hope there is no circular loop
|
101
|
+
while p2=p.merged_shift
|
102
|
+
release_p p2
|
103
|
+
end
|
104
|
+
p.reset!
|
105
|
+
( @pool[p.class] ||= [] ) << p
|
106
|
+
end
|
107
|
+
#
|
108
|
+
def require_p p_kls
|
109
|
+
l = @pool[p_kls]
|
110
|
+
return p_kls.new if l.nil?
|
111
|
+
p = l.pop
|
112
|
+
return p_kls.new if p.nil?
|
113
|
+
p
|
114
|
+
end
|
115
|
+
#
|
116
|
+
def post_p p
|
117
|
+
@app_fifo << p
|
118
|
+
end
|
119
|
+
#
|
120
|
+
def post_sys_p p
|
121
|
+
@sys_fifo << p
|
122
|
+
end
|
123
|
+
#
|
124
|
+
def process_sys_p p
|
125
|
+
if p.action==Edoors::SYS_ACT_HIBERNATE
|
126
|
+
stop!
|
127
|
+
hibernate! p[FIELD_HIBERNATE_PATH]
|
128
|
+
else
|
129
|
+
super p
|
130
|
+
end
|
131
|
+
end
|
132
|
+
#
|
133
|
+
def spin!
|
134
|
+
@iotas.values.each do |iota| iota.start! end unless @hibernation
|
135
|
+
@run = true
|
136
|
+
@hibernation = false
|
137
|
+
while @run and (@sys_fifo.length>0 or @app_fifo.length>0)
|
138
|
+
while @run and @sys_fifo.length>0
|
139
|
+
p = @sys_fifo.shift
|
140
|
+
p.dst.process_sys_p p
|
141
|
+
end
|
142
|
+
while @run and @app_fifo.length>0
|
143
|
+
p = @app_fifo.shift
|
144
|
+
p.dst.process_p p
|
145
|
+
break
|
146
|
+
end
|
147
|
+
end
|
148
|
+
@iotas.values.each do |iota| iota.stop! end unless @hibernation
|
149
|
+
end
|
150
|
+
#
|
151
|
+
def stop!
|
152
|
+
@run=false
|
153
|
+
end
|
154
|
+
#
|
155
|
+
def hibernate! path=nil
|
156
|
+
@hibernation = true
|
157
|
+
File.open(path||@hibernate_path,'w') do |f| f << JSON.pretty_generate(self) end
|
158
|
+
end
|
159
|
+
#
|
160
|
+
def self.resume! path
|
161
|
+
self.json_create JSON.load File.open(path,'r') { |f| f.read }
|
162
|
+
end
|
163
|
+
#
|
164
|
+
end
|
165
|
+
#
|
166
|
+
end
|
167
|
+
#
|
168
|
+
# EOF
|
data/lib/version.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
#
|
4
|
+
# Copyright 2012 Jérémy Zurcher <jeremy@asynk.ch>
|
5
|
+
#
|
6
|
+
# This file is part of edoors-ruby.
|
7
|
+
#
|
8
|
+
# edoors-ruby is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU Affero General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# edoors-ruby is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU Affero General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU Affero General Public License
|
19
|
+
# along with edoors-ruby. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
|
21
|
+
#
|
22
|
+
module Edoors
|
23
|
+
#
|
24
|
+
VERSION = "0.0.6"
|
25
|
+
#
|
26
|
+
end
|
27
|
+
#
|
28
|
+
# EOF
|
data/spec/board_spec.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'spec_helper'
|
6
|
+
#
|
7
|
+
describe Edoors::Board do
|
8
|
+
#
|
9
|
+
before (:all) do
|
10
|
+
@spin = Edoors::Spin.new 'dom0'
|
11
|
+
end
|
12
|
+
#
|
13
|
+
before(:each) do
|
14
|
+
@spin.clear!
|
15
|
+
end
|
16
|
+
#
|
17
|
+
it "require_p release_p" do
|
18
|
+
board = Edoors::Board.new 'hell', @spin
|
19
|
+
p0 = board.require_p Edoors::Particle
|
20
|
+
p1 = board.require_p Edoors::Particle
|
21
|
+
(p0===p1).should be_false
|
22
|
+
board.release_p p0
|
23
|
+
p2 = board.require_p Edoors::Particle
|
24
|
+
(p0===p2).should be_true
|
25
|
+
end
|
26
|
+
#
|
27
|
+
it "particle wait and merge" do
|
28
|
+
p0 = Edoors::Particle.new
|
29
|
+
p0['k0'] = 'v0'
|
30
|
+
p0['k1'] = 'neither'
|
31
|
+
p0['k2'] = 'v2'
|
32
|
+
p0.set_link_fields 'k0,k2'
|
33
|
+
p0.link_value.should eql 'v0v2'
|
34
|
+
p1 = Edoors::Particle.new
|
35
|
+
p1['k0'] = 'v0'
|
36
|
+
p1['k1'] = 'nore'
|
37
|
+
p1['k2'] = 'v2'
|
38
|
+
p1.set_link_fields 'k0,k2'
|
39
|
+
p1.link_value.should eql 'v0v2'
|
40
|
+
P0 = p0
|
41
|
+
P1 = p1
|
42
|
+
class Board0 < Edoors::Board
|
43
|
+
attr_reader :ok, :follow
|
44
|
+
def receive_p p
|
45
|
+
@ok = false
|
46
|
+
case p.action
|
47
|
+
when Edoors::ACT_FOLLOW
|
48
|
+
@follow = true
|
49
|
+
@ok = (p===P0 and p.merged(0)===P1)
|
50
|
+
else
|
51
|
+
@follow = false
|
52
|
+
@ok = (p===P1 and p.merged(0)===P0)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
b0 = Board0.new 'door0', @spin
|
57
|
+
b0.process_p p0
|
58
|
+
p0.merged(0).should be_nil
|
59
|
+
b0.process_p p1
|
60
|
+
b0.ok.should be_true
|
61
|
+
b0.follow.should be_false
|
62
|
+
#
|
63
|
+
p1.merged_shift
|
64
|
+
#
|
65
|
+
b0.process_p p0
|
66
|
+
p0.merged(0).should be_nil
|
67
|
+
# need to set it to p0 too, so case in Board0 is ok
|
68
|
+
p0.add_dst Edoors::ACT_FOLLOW
|
69
|
+
p0.split_dst!
|
70
|
+
p1.add_dst Edoors::ACT_FOLLOW
|
71
|
+
p1.split_dst!
|
72
|
+
b0.process_p p1
|
73
|
+
b0.ok.should be_true
|
74
|
+
b0.follow.should be_true
|
75
|
+
end
|
76
|
+
#
|
77
|
+
it "board->json->board" do
|
78
|
+
board = Edoors::Board.new 'hell', @spin
|
79
|
+
p0 = Edoors::Particle.new
|
80
|
+
p1 = Edoors::Particle.new
|
81
|
+
p1['v0']=0
|
82
|
+
p1.set_link_fields 'v0'
|
83
|
+
board.process_p p0
|
84
|
+
board.process_p p1
|
85
|
+
hell = Edoors::Board.json_create( JSON.load( JSON.generate(board) ) )
|
86
|
+
board.name.should eql hell.name
|
87
|
+
JSON.generate(board).should eql JSON.generate(hell)
|
88
|
+
end
|
89
|
+
#
|
90
|
+
end
|
91
|
+
#
|
92
|
+
# EOF
|
data/spec/door_spec.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'spec_helper'
|
6
|
+
#
|
7
|
+
describe Edoors::Door do
|
8
|
+
#
|
9
|
+
before (:all) do
|
10
|
+
@spin = Edoors::Spin.new 'dom0'
|
11
|
+
end
|
12
|
+
#
|
13
|
+
before(:each) do
|
14
|
+
@spin.clear!
|
15
|
+
end
|
16
|
+
#
|
17
|
+
it "require_p release_p" do
|
18
|
+
door = Edoors::Door.new 'hell', @spin
|
19
|
+
p0 = door.require_p Edoors::Particle
|
20
|
+
p1 = door.require_p Edoors::Particle
|
21
|
+
(p0===p1).should be_false
|
22
|
+
door.release_p p0
|
23
|
+
p2 = door.require_p Edoors::Particle
|
24
|
+
(p0===p2).should be_true
|
25
|
+
end
|
26
|
+
#
|
27
|
+
it "NoMethodError when receive_p not overridden" do
|
28
|
+
class Door0 < Edoors::Door
|
29
|
+
end
|
30
|
+
f = Fake.new 'fake', @spin
|
31
|
+
d0 = Door0.new 'door0', f
|
32
|
+
p0 = d0.require_p Edoors::Particle
|
33
|
+
lambda { d0.process_p p0 }.should raise_error(NoMethodError)
|
34
|
+
end
|
35
|
+
#
|
36
|
+
it "send_p, send_sys_p, release_p and release of lost particles" do
|
37
|
+
class Door0 < Edoors::Door
|
38
|
+
def receive_p p
|
39
|
+
case p.action
|
40
|
+
when 'RELEASE'
|
41
|
+
release_p p
|
42
|
+
when 'SEND'
|
43
|
+
send_p p
|
44
|
+
when 'SEND_SYS'
|
45
|
+
send_sys_p p
|
46
|
+
else
|
47
|
+
# lost!!
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
f = Fake.new 'fake', @spin
|
52
|
+
d0 = Door0.new 'door0', f
|
53
|
+
p0 = d0.require_p Edoors::Particle
|
54
|
+
#
|
55
|
+
p0.add_dst 'SEND'
|
56
|
+
p0.split_dst!
|
57
|
+
d0.process_p p0
|
58
|
+
f.p.should eql p0
|
59
|
+
p0.clear_dsts!
|
60
|
+
#
|
61
|
+
p0.add_dst 'SEND_SYS'
|
62
|
+
p0.split_dst!
|
63
|
+
d0.process_p p0
|
64
|
+
f.sp.should eql p0
|
65
|
+
p0.clear_dsts!
|
66
|
+
#
|
67
|
+
p0.add_dst 'RELEASE'
|
68
|
+
p0.split_dst!
|
69
|
+
d0.process_p p0
|
70
|
+
p1 = d0.require_p Edoors::Particle
|
71
|
+
p1.should be p0
|
72
|
+
p0.clear_dsts!
|
73
|
+
#
|
74
|
+
p0.add_dst 'LOST'
|
75
|
+
p0.split_dst!
|
76
|
+
d0.process_p p0
|
77
|
+
p1 = d0.require_p Edoors::Particle
|
78
|
+
p1.should be p0
|
79
|
+
p0.clear_dsts!
|
80
|
+
#
|
81
|
+
d0.process_sys_p p0
|
82
|
+
p1 = @spin.require_p Edoors::Particle
|
83
|
+
p1.should be p0
|
84
|
+
end
|
85
|
+
#
|
86
|
+
it "door->json->door" do
|
87
|
+
door = Edoors::Door.new 'hell', @spin
|
88
|
+
hell = Edoors::Door.json_create( JSON.load( JSON.generate(door) ) )
|
89
|
+
door.name.should eql hell.name
|
90
|
+
JSON.generate(door).should eql JSON.generate(hell)
|
91
|
+
end
|
92
|
+
#
|
93
|
+
end
|
94
|
+
#
|
95
|
+
# EOF
|
data/spec/link_spec.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'spec_helper'
|
6
|
+
#
|
7
|
+
describe Edoors::Link do
|
8
|
+
#
|
9
|
+
it "from particle data" do
|
10
|
+
@spin = Edoors::Spin.new 'dom0'
|
11
|
+
p = @spin.require_p Edoors::Particle
|
12
|
+
p.set_data Edoors::LNK_SRC, 'input1'
|
13
|
+
p.set_data Edoors::LNK_DSTS, 'concat1?follow,output1'
|
14
|
+
p.set_data Edoors::LNK_FIELDS, 'f0,f2'
|
15
|
+
p.set_data Edoors::LNK_CONDF, 'f0,f1,f2'
|
16
|
+
p.set_data Edoors::LNK_CONDV, 'v0v1v2'
|
17
|
+
lnk = Edoors::Link.from_particle_data p
|
18
|
+
lnk.src.should eql 'input1'
|
19
|
+
lnk.dsts.should eql 'concat1?follow,output1'
|
20
|
+
lnk.fields.should eql 'f0,f2'
|
21
|
+
lnk.cond_fields.should eql 'f0,f1,f2'
|
22
|
+
lnk.cond_value.should eql 'v0v1v2'
|
23
|
+
end
|
24
|
+
#
|
25
|
+
it "link->json->link" do
|
26
|
+
link = Edoors::Link.new 'input1', 'concat1?follow,output1', 'f0,f2', 'f0,f1,f2', 'v0v1v2'
|
27
|
+
lnk = Edoors::Link.json_create( JSON.load( JSON.generate(link) ) )
|
28
|
+
link.src.should eql lnk.src
|
29
|
+
link.dsts.should eql lnk.dsts
|
30
|
+
link.fields.should eql lnk.fields
|
31
|
+
link.cond_fields.should eql lnk.cond_fields
|
32
|
+
link.cond_value.should eql lnk.cond_value
|
33
|
+
JSON.generate(link).should eql JSON.generate(lnk)
|
34
|
+
end
|
35
|
+
#
|
36
|
+
end
|
37
|
+
#
|
38
|
+
# EOF
|
@@ -0,0 +1,266 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'spec_helper'
|
6
|
+
#
|
7
|
+
describe Edoors::Particle do
|
8
|
+
#
|
9
|
+
it "payload manipulation" do
|
10
|
+
p = Edoors::Particle.new
|
11
|
+
#
|
12
|
+
p['key']=666
|
13
|
+
p['key'].should eql 666
|
14
|
+
p.data('key').should eql 666
|
15
|
+
p.get_data('key').should eql 666
|
16
|
+
#
|
17
|
+
p.set_data 'key', 69
|
18
|
+
p['key'].should eql 69
|
19
|
+
p.data('key').should eql 69
|
20
|
+
p.get_data('key').should eql 69
|
21
|
+
end
|
22
|
+
#
|
23
|
+
it "payload clone" do
|
24
|
+
p = Edoors::Particle.new
|
25
|
+
p['k00'] = { 'k0'=>0,'k1'=>1}
|
26
|
+
p['k11'] = [1,2,3]
|
27
|
+
o = Edoors::Particle.new
|
28
|
+
o.clone_data p
|
29
|
+
p['k00']=nil
|
30
|
+
p['k00'].should be_nil
|
31
|
+
o['k00']['k0'].should eql 0
|
32
|
+
o['k00']['k1'].should eql 1
|
33
|
+
p['k11']=nil
|
34
|
+
p['k11'].should be_nil
|
35
|
+
o['k11'][0].should eql 1
|
36
|
+
o['k11'][1].should eql 2
|
37
|
+
o['k11'][2].should eql 3
|
38
|
+
end
|
39
|
+
#
|
40
|
+
it "particle merge" do
|
41
|
+
spin = Edoors::Spin.new 'dom0'
|
42
|
+
p = Edoors::Particle.new
|
43
|
+
q = Edoors::Particle.new
|
44
|
+
o = Edoors::Particle.new
|
45
|
+
p.merge! q
|
46
|
+
p.merge! o
|
47
|
+
p.merged(0).should be q
|
48
|
+
p.merged(1).should be o
|
49
|
+
p.merged(2).should be_nil
|
50
|
+
p.merged_shift.should be q
|
51
|
+
p.merged(0).should be o
|
52
|
+
p.merged(1).should be_nil
|
53
|
+
p.merged_shift.should be o
|
54
|
+
p.merged(0).should be_nil
|
55
|
+
p.merge! q
|
56
|
+
p.merge! o
|
57
|
+
p.merged(0).should be q
|
58
|
+
p.merged(1).should be o
|
59
|
+
p.clear_merged!
|
60
|
+
p.merged(0).should be_nil
|
61
|
+
p.merge! q
|
62
|
+
p.merge! o
|
63
|
+
p.merged(0).should be q
|
64
|
+
p.merged(1).should be o
|
65
|
+
p.clear_merged! spin
|
66
|
+
p.merged(0).should be_nil
|
67
|
+
spin.require_p(Edoors::Particle).should be o
|
68
|
+
spin.require_p(Edoors::Particle).should be q
|
69
|
+
end
|
70
|
+
#
|
71
|
+
it "routing: add_dsts, next_dst and dst_routed!" do
|
72
|
+
p = Edoors::Particle.new
|
73
|
+
d0 = Edoors::Door.new 'door0', nil
|
74
|
+
d1 = Edoors::Door.new 'door1', nil
|
75
|
+
p.dst.should be_nil
|
76
|
+
p.next_dst.should be_nil
|
77
|
+
p.add_dsts 'some?where,room0/room1/door?action,room/door,door'
|
78
|
+
p.next_dst.should eql 'some?where'
|
79
|
+
p.dst_routed! d0
|
80
|
+
p.dst.should be d0
|
81
|
+
p.next_dst.should eql 'room0/room1/door?action'
|
82
|
+
p.dst_routed! d1
|
83
|
+
p.dst.should be d1
|
84
|
+
p.next_dst.should eql 'room/door'
|
85
|
+
p.dst_routed! nil
|
86
|
+
p.dst.should be_nil
|
87
|
+
p.next_dst.should eql 'door'
|
88
|
+
end
|
89
|
+
#
|
90
|
+
it "wrong path should raise exeption" do
|
91
|
+
p = Edoors::Particle.new
|
92
|
+
lambda { p.add_dst 'action', '/room' }.should raise_error(Edoors::Exception)
|
93
|
+
lambda { p.add_dst 'action', 'room/' }.should raise_error(Edoors::Exception)
|
94
|
+
lambda { p.add_dst '', 'room/' }.should raise_error(Edoors::Exception)
|
95
|
+
lambda { p.add_dst 'action', 'room//door' }.should raise_error(Edoors::Exception)
|
96
|
+
lambda { p.add_dst ' ' }.should raise_error(Edoors::Exception)
|
97
|
+
lambda { p.add_dst ' ', '' }.should raise_error(Edoors::Exception)
|
98
|
+
lambda { p.add_dst 'f f' }.should raise_error(Edoors::Exception)
|
99
|
+
lambda { p.add_dst '', ' d' }.should raise_error(Edoors::Exception)
|
100
|
+
lambda { p.add_dst '' }.should raise_error(Edoors::Exception)
|
101
|
+
lambda { p.add_dst '', '' }.should raise_error(Edoors::Exception)
|
102
|
+
lambda { p.add_dst nil }.should raise_error(TypeError)
|
103
|
+
lambda { p.add_dst 'action', nil }.should raise_error(NoMethodError)
|
104
|
+
end
|
105
|
+
#
|
106
|
+
it "routing: set_dst!" do
|
107
|
+
p = Edoors::Particle.new
|
108
|
+
d0 = Edoors::Door.new 'door0', nil
|
109
|
+
#
|
110
|
+
p.set_dst! 'action', d0
|
111
|
+
p.action.should eql 'action'
|
112
|
+
p.dst.should be d0
|
113
|
+
end
|
114
|
+
#
|
115
|
+
it "routing: add_dst and split_dst!" do
|
116
|
+
p = Edoors::Particle.new
|
117
|
+
d0 = Edoors::Door.new 'door0', nil
|
118
|
+
#
|
119
|
+
p.split_dst!
|
120
|
+
p.room.should be_nil
|
121
|
+
p.door.should be_nil
|
122
|
+
p.action.should be_nil
|
123
|
+
#
|
124
|
+
p.add_dst 'action', 'room0/room1/door'
|
125
|
+
p.split_dst!
|
126
|
+
p.room.should eql 'room0/room1'
|
127
|
+
p.door.should eql 'door'
|
128
|
+
p.action.should eql 'action'
|
129
|
+
p.clear_dsts!
|
130
|
+
#
|
131
|
+
p.add_dst 'action', 'room/door'
|
132
|
+
p.split_dst!
|
133
|
+
p.room.should eql 'room'
|
134
|
+
p.door.should eql 'door'
|
135
|
+
p.action.should eql 'action'
|
136
|
+
p.clear_dsts!
|
137
|
+
#
|
138
|
+
p.add_dst 'action', ''
|
139
|
+
p.split_dst!
|
140
|
+
p.room.should be_nil
|
141
|
+
p.door.should be_nil
|
142
|
+
p.action.should eql 'action'
|
143
|
+
p.clear_dsts!
|
144
|
+
#
|
145
|
+
p.add_dst 'action'
|
146
|
+
p.split_dst!
|
147
|
+
p.room.should be_nil
|
148
|
+
p.door.should be_nil
|
149
|
+
p.action.should eql 'action'
|
150
|
+
p.clear_dsts!
|
151
|
+
#
|
152
|
+
p.add_dsts 'door?action,?action'
|
153
|
+
p.split_dst!
|
154
|
+
p.room.should be_nil
|
155
|
+
p.door.should eql 'door'
|
156
|
+
p.action.should eql 'action'
|
157
|
+
#
|
158
|
+
p.dst_routed! d0
|
159
|
+
#
|
160
|
+
p.dst.should be d0
|
161
|
+
p.split_dst!
|
162
|
+
p.room.should be_nil
|
163
|
+
p.door.should be_nil
|
164
|
+
p.action.should eql 'action'
|
165
|
+
#
|
166
|
+
end
|
167
|
+
#
|
168
|
+
it "routing: error!" do
|
169
|
+
p = Edoors::Particle.new
|
170
|
+
d = Edoors::Door.new 'door', nil
|
171
|
+
p.init! d
|
172
|
+
p.add_dsts 'door?action,?action'
|
173
|
+
p.next_dst.should eql 'door?action'
|
174
|
+
p.error! 'err_msg'
|
175
|
+
p[Edoors::FIELD_ERROR_MSG].should eql 'err_msg'
|
176
|
+
p.action.should eq Edoors::ACT_ERROR
|
177
|
+
p.dst.should be d
|
178
|
+
end
|
179
|
+
#
|
180
|
+
it "link fields and link value" do
|
181
|
+
p = Edoors::Particle.new
|
182
|
+
p['k0'] = 'v0'
|
183
|
+
p['k1'] = 'v1'
|
184
|
+
p['k2'] = 'v2'
|
185
|
+
p.set_link_fields 'k0,k2'
|
186
|
+
p.link_value.should eql 'v0v2'
|
187
|
+
p.set_link_fields 'k1,k0'
|
188
|
+
p.link_value.should eql 'v1v0'
|
189
|
+
p['k0']='vx'
|
190
|
+
p.link_value.should eql 'v1vx'
|
191
|
+
end
|
192
|
+
#
|
193
|
+
it "apply_link!" do
|
194
|
+
p = Edoors::Particle.new
|
195
|
+
p['k0'] = 'v0'
|
196
|
+
p['k1'] = 'v1'
|
197
|
+
p['k2'] = 'v2'
|
198
|
+
p.set_link_fields 'k0,k2'
|
199
|
+
p.add_dsts 'door?action,?action'
|
200
|
+
p.src.should be_nil
|
201
|
+
p.link_value.should eql 'v0v2'
|
202
|
+
p.next_dst.should eql 'door?action'
|
203
|
+
lnk = Edoors::Link.new('door0', 'door1?get,door2', 'k1', 'f0,f1', 'v0v1')
|
204
|
+
f = Fake.new 'fake', nil
|
205
|
+
lnk.door = f
|
206
|
+
p.apply_link! lnk
|
207
|
+
p.src.should be f
|
208
|
+
p.next_dst.should eql 'door1?get'
|
209
|
+
p.link_value.should eql 'v1'
|
210
|
+
end
|
211
|
+
#
|
212
|
+
it "particle->json->particle" do
|
213
|
+
s0 = Edoors::Spin.new 'top'
|
214
|
+
s1 = Edoors::Room.new 'room0', s0
|
215
|
+
s2 = Edoors::Room.new 'room1', s1
|
216
|
+
s3 = Edoors::Door.new 'doora', s2
|
217
|
+
s4 = Edoors::Door.new 'doorb', s1
|
218
|
+
p0 = Edoors::Particle.new
|
219
|
+
p0['k0'] = 'v0'
|
220
|
+
p0['k1'] = 'v1'
|
221
|
+
p0['k2'] = 'v2'
|
222
|
+
p0.init! s3
|
223
|
+
p0.set_link_fields 'k0,k2'
|
224
|
+
p0.add_dsts 'room0/room1/room2/doorX?myaction,door?action,?action'
|
225
|
+
p0.split_dst!
|
226
|
+
p1 = Edoors::Particle.new
|
227
|
+
p1['k3'] = 'v6'
|
228
|
+
p1['k4'] = 'v7'
|
229
|
+
p1['k5'] = 'v8'
|
230
|
+
p1.init! s3
|
231
|
+
p1.dst_routed! s4
|
232
|
+
p1.set_link_fields 'k5,k4,k3'
|
233
|
+
p1.add_dsts 'room0/room1/door?action,output?action'
|
234
|
+
p0.merge! p1
|
235
|
+
o = JSON.load( JSON.generate(p0) )
|
236
|
+
o['spin'] = s0
|
237
|
+
px = Edoors::Particle.json_create( o )
|
238
|
+
((px.ts-p0.ts)<0.5).should be_true
|
239
|
+
px.src.should be s3
|
240
|
+
px.dst.should be_nil
|
241
|
+
px.room.should eql 'room0/room1/room2'
|
242
|
+
px.door.should eql 'doorX'
|
243
|
+
px.action.should eql 'myaction'
|
244
|
+
px.next_dst.should eql 'room0/room1/room2/doorX?myaction'
|
245
|
+
px.link_value.should eql 'v0v2'
|
246
|
+
px['k0'].should eql 'v0'
|
247
|
+
px['k1'].should eql 'v1'
|
248
|
+
px['k2'].should eql 'v2'
|
249
|
+
py = px.merged(0)
|
250
|
+
((py.ts-p1.ts)<0.5).should be_true
|
251
|
+
py.src.should be s3
|
252
|
+
py.dst.should be s4
|
253
|
+
py.room.should be_nil
|
254
|
+
py.door.should be_nil
|
255
|
+
py.action.should be_nil
|
256
|
+
py.next_dst.should eql 'room0/room1/door?action'
|
257
|
+
py.link_value.should eql 'v8v7v6'
|
258
|
+
py['k3'].should eql 'v6'
|
259
|
+
py['k4'].should eql 'v7'
|
260
|
+
py['k5'].should eql 'v8'
|
261
|
+
JSON.generate(p0).should eql JSON.generate(px)
|
262
|
+
end
|
263
|
+
#
|
264
|
+
end
|
265
|
+
#
|
266
|
+
# EOF
|