iotas 0.0.2
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 +5 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +28 -0
- data/LICENSE +661 -0
- data/README.md +18 -0
- data/Rakefile +6 -0
- data/iotas.gemspec +28 -0
- data/lib/iotas/board.rb +69 -0
- data/lib/iotas/door.rb +91 -0
- data/lib/iotas/iota.rb +64 -0
- data/lib/iotas/link.rb +70 -0
- data/lib/iotas/particle.rb +213 -0
- data/lib/iotas/room.rb +192 -0
- data/lib/iotas/spin.rb +150 -0
- data/lib/iotas.rb +51 -0
- data/lib/version.rb +28 -0
- data/spec/board_spec.rb +95 -0
- data/spec/door_spec.rb +94 -0
- data/spec/link_spec.rb +38 -0
- data/spec/particle_spec.rb +240 -0
- data/spec/room_spec.rb +304 -0
- data/spec/spec_helper.rb +38 -0
- data/spec/spin_spec.rb +129 -0
- data/spec/spot_spec.rb +26 -0
- data/test/test_evendoors.rb +168 -0
- metadata +132 -0
data/lib/iotas/room.rb
ADDED
@@ -0,0 +1,192 @@
|
|
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 iotas.
|
7
|
+
#
|
8
|
+
# iotas 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
|
+
# iotas 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 iotas. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
|
21
|
+
#
|
22
|
+
module Iotas
|
23
|
+
#
|
24
|
+
ERROR_ROUTE_NS = 'routing error: no source'.freeze
|
25
|
+
ERROR_ROUTE_RRWD = 'routing error: right room, wrong door'.freeze
|
26
|
+
ERROR_ROUTE_DDWR = 'routing error: drill down, wrong room'.freeze
|
27
|
+
ERROR_ROUTE_TRWR = 'routing error: top room, wrong room'.freeze
|
28
|
+
ERROR_ROUTE_NDNL = 'routing error: no destination, no link'.freeze
|
29
|
+
ERROR_ROUTE_SND = 'routing error: system no destination'.freeze
|
30
|
+
#
|
31
|
+
class Room < Iota
|
32
|
+
#
|
33
|
+
def initialize n, p
|
34
|
+
super n, p
|
35
|
+
@iotas = {}
|
36
|
+
@links = {}
|
37
|
+
end
|
38
|
+
#
|
39
|
+
def to_json *a
|
40
|
+
{
|
41
|
+
'kls' => self.class.name,
|
42
|
+
'name' => @name,
|
43
|
+
'iotas' => @iotas,
|
44
|
+
'links' => @links
|
45
|
+
}.to_json *a
|
46
|
+
end
|
47
|
+
#
|
48
|
+
def self.json_create o
|
49
|
+
raise Iotas::Exception.new "JSON #{o['kls']} != #{self.name}" if o['kls'] != self.name
|
50
|
+
room = self.new o['name'], o['parent']
|
51
|
+
o['iotas'].each do |name,iota|
|
52
|
+
eval( iota['kls'] ).json_create(iota.merge!('parent'=>room))
|
53
|
+
end
|
54
|
+
o['links'].each do |src,links|
|
55
|
+
links.each do |link|
|
56
|
+
room.add_link Iotas::Link.json_create(link)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
room
|
60
|
+
end
|
61
|
+
#
|
62
|
+
def add_iota s
|
63
|
+
raise Iotas::Exception.new "Iota #{s.name} already has #{s.parent.name} as parent" if not s.parent.nil? and s.parent!=self
|
64
|
+
raise Iotas::Exception.new "Iota #{s.name} already exists in #{path}" if @iotas.has_key? s.name
|
65
|
+
s.parent = self if s.parent.nil?
|
66
|
+
@iotas[s.name]=s
|
67
|
+
end
|
68
|
+
#
|
69
|
+
def add_link l
|
70
|
+
l.door = @iotas[l.src]
|
71
|
+
raise Iotas::Exception.new "Link source #{l.src} does not exist in #{path}" if l.door.nil?
|
72
|
+
(@links[l.src] ||= [])<< l
|
73
|
+
end
|
74
|
+
#
|
75
|
+
def start!
|
76
|
+
puts " * start #{path}" if @spin.debug_routing
|
77
|
+
@iotas.values.each do |iota| iota.start! end
|
78
|
+
end
|
79
|
+
#
|
80
|
+
def stop!
|
81
|
+
puts " * stop #{path}" if @spin.debug_routing
|
82
|
+
@iotas.values.each do |iota| iota.stop! end
|
83
|
+
end
|
84
|
+
#
|
85
|
+
def search_down spath
|
86
|
+
return self if spath==path
|
87
|
+
return nil if (spath=~/^#{path}\/(\w+)\/?/)!=0
|
88
|
+
if iota = @iotas[$1]
|
89
|
+
return iota if iota.path==spath # needed as Door doesn't implement #search_down
|
90
|
+
return iota.search_down spath
|
91
|
+
end
|
92
|
+
nil
|
93
|
+
end
|
94
|
+
#
|
95
|
+
def try_links p
|
96
|
+
puts " -> try_links ..." if @spin.debug_routing
|
97
|
+
links = @links[p.src.name]
|
98
|
+
return false if links.nil?
|
99
|
+
pending_link = nil
|
100
|
+
apply_link = false
|
101
|
+
links.each do |link|
|
102
|
+
apply_link = link.cond_fields.nil? # unconditional link
|
103
|
+
p.set_link_fields link.cond_fields if not apply_link
|
104
|
+
if apply_link or (p.link_value==link.cond_value)
|
105
|
+
# link matches !
|
106
|
+
if pending_link
|
107
|
+
p2 = @spin.require_p p.class
|
108
|
+
p2.clone_data p
|
109
|
+
p2.apply_link! link
|
110
|
+
send_p p2
|
111
|
+
end
|
112
|
+
pending_link = link
|
113
|
+
end
|
114
|
+
end
|
115
|
+
if pending_link
|
116
|
+
p.apply_link! pending_link
|
117
|
+
send_p p
|
118
|
+
end
|
119
|
+
(not pending_link.nil?)
|
120
|
+
end
|
121
|
+
#
|
122
|
+
def route_p p
|
123
|
+
if p.room.nil? or p.room==path
|
124
|
+
if door = @iotas[p.door]
|
125
|
+
p.dst_routed! door
|
126
|
+
else
|
127
|
+
p.error! Iotas::ERROR_ROUTE_RRWD
|
128
|
+
end
|
129
|
+
elsif (p.room=~/^#{path}\/(.*)/)==0
|
130
|
+
room, *more = $1.split Iotas::PATH_SEP
|
131
|
+
if child=@iotas[room]
|
132
|
+
child.route_p p
|
133
|
+
else
|
134
|
+
p.error! Iotas::ERROR_ROUTE_DDWR
|
135
|
+
end
|
136
|
+
elsif @parent
|
137
|
+
@parent.route_p p
|
138
|
+
else
|
139
|
+
p.error! Iotas::ERROR_ROUTE_TRWR
|
140
|
+
end
|
141
|
+
end
|
142
|
+
#
|
143
|
+
def send_p p
|
144
|
+
puts " * send_p #{(p.next_dst.nil? ? 'no dst' : p.next_dst)} ..." if @spin.debug_routing
|
145
|
+
if p.src.nil?
|
146
|
+
# do not route orphan particles !!
|
147
|
+
p.error! Iotas::ERROR_ROUTE_NS, @spin
|
148
|
+
elsif p.next_dst
|
149
|
+
p.split_dst!
|
150
|
+
if p.door
|
151
|
+
route_p p
|
152
|
+
else
|
153
|
+
# boomerang
|
154
|
+
p.dst_routed! p.src
|
155
|
+
end
|
156
|
+
elsif try_links p
|
157
|
+
return
|
158
|
+
else
|
159
|
+
p.error! Iotas::ERROR_ROUTE_NDNL
|
160
|
+
end
|
161
|
+
puts " -> #{p.dst.path}#{Iotas::ACT_SEP}#{p.action}" if @spin.debug_routing
|
162
|
+
@spin.post_p p
|
163
|
+
end
|
164
|
+
#
|
165
|
+
def send_sys_p p
|
166
|
+
puts " * send_sys_p #{(p.next_dst.nil? ? 'no dst' : p.next_dst)} ..." if @spin.debug_routing
|
167
|
+
if p.next_dst
|
168
|
+
p.split_dst!
|
169
|
+
if p.door
|
170
|
+
route_p p
|
171
|
+
elsif p.action
|
172
|
+
p.dst_routed! @spin
|
173
|
+
end
|
174
|
+
else
|
175
|
+
p.error! Iotas::ERROR_ROUTE_SND
|
176
|
+
end
|
177
|
+
puts " -> #{p.dst.path}#{Iotas::ACT_SEP}#{p.action}" if @spin.debug_routing
|
178
|
+
@spin.post_sys_p p
|
179
|
+
end
|
180
|
+
#
|
181
|
+
def process_sys_p p
|
182
|
+
if p.action==Iotas::SYS_ACT_ADD_LINK
|
183
|
+
add_link Iotas::Link.from_particle_data p
|
184
|
+
end
|
185
|
+
@spin.release_p p
|
186
|
+
end
|
187
|
+
#
|
188
|
+
end
|
189
|
+
#
|
190
|
+
end
|
191
|
+
#
|
192
|
+
# EOF
|
data/lib/iotas/spin.rb
ADDED
@@ -0,0 +1,150 @@
|
|
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 iotas.
|
7
|
+
#
|
8
|
+
# iotas 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
|
+
# iotas 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 iotas. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
|
21
|
+
#
|
22
|
+
module Iotas
|
23
|
+
#
|
24
|
+
class Spin < Room
|
25
|
+
#
|
26
|
+
def initialize n, o={}
|
27
|
+
super n, nil
|
28
|
+
#
|
29
|
+
@pool = {} # per particle class free list
|
30
|
+
@sys_fifo = [] # system particles fifo list
|
31
|
+
@app_fifo = [] # application particles fifo list
|
32
|
+
#
|
33
|
+
@run = false
|
34
|
+
@hibernation = o['hibernation']||false
|
35
|
+
@hibernate_path = 'iotas-hibernate-'+n+'.json'
|
36
|
+
@debug_errors = o[:debug_errors]||o['debug_errors']||false
|
37
|
+
@debug_routing = o[:debug_routing]||o['debug_routing']||false
|
38
|
+
#
|
39
|
+
if not o.empty?
|
40
|
+
o['iotas'].each do |name,iota|
|
41
|
+
Iotas::Room.json_create(iota.merge!('parent'=>self))
|
42
|
+
end if o['iotas']
|
43
|
+
o['app_fifo'].each do |particle|
|
44
|
+
@app_fifo << Iotas::Particle.json_create(particle.merge!('spin'=>self))
|
45
|
+
end if o['app_fifo']
|
46
|
+
o['sys_fifo'].each do |particle|
|
47
|
+
@sys_fifo << Iotas::Particle.json_create(particle.merge!('spin'=>self))
|
48
|
+
end if o['sys_fifo']
|
49
|
+
end
|
50
|
+
end
|
51
|
+
#
|
52
|
+
attr_accessor :run, :hibernate_path, :debug_errors, :debug_routing
|
53
|
+
#
|
54
|
+
def to_json *a
|
55
|
+
{
|
56
|
+
'kls' => self.class.name,
|
57
|
+
'timestamp' => Time.now,
|
58
|
+
'name' => @name,
|
59
|
+
'hibernation' => @hibernation,
|
60
|
+
'iotas' => @iotas,
|
61
|
+
'sys_fifo' => @sys_fifo,
|
62
|
+
'app_fifo' => @app_fifo,
|
63
|
+
'debug_errors' => @debug_errors,
|
64
|
+
'debug_routing' => @debug_routing
|
65
|
+
}.to_json(*a)
|
66
|
+
end
|
67
|
+
#
|
68
|
+
def self.json_create o
|
69
|
+
raise Iotas::Exception.new "JSON #{o['kls']} != #{self.name}" if o['kls'] != self.name
|
70
|
+
self.new o['name'], o
|
71
|
+
end
|
72
|
+
#
|
73
|
+
def clear!
|
74
|
+
@iotas.clear
|
75
|
+
@pool.clear
|
76
|
+
@sys_fifo.clear
|
77
|
+
@app_fifo.clear
|
78
|
+
end
|
79
|
+
#
|
80
|
+
#
|
81
|
+
def release_p p
|
82
|
+
# hope there is no circular loop
|
83
|
+
while p2=p.merged_shift
|
84
|
+
release_p p2
|
85
|
+
end
|
86
|
+
( @pool[p.class] ||= [] ) << p
|
87
|
+
end
|
88
|
+
#
|
89
|
+
def require_p p_kls
|
90
|
+
l = @pool[p_kls]
|
91
|
+
return p_kls.new if l.nil?
|
92
|
+
p = l.pop
|
93
|
+
return p_kls.new if p.nil?
|
94
|
+
p.reset!
|
95
|
+
p
|
96
|
+
end
|
97
|
+
#
|
98
|
+
def post_p p
|
99
|
+
@app_fifo << p
|
100
|
+
end
|
101
|
+
#
|
102
|
+
def post_sys_p p
|
103
|
+
@sys_fifo << p
|
104
|
+
end
|
105
|
+
#
|
106
|
+
def process_sys_p p
|
107
|
+
if p.action==Iotas::SYS_ACT_HIBERNATE
|
108
|
+
stop!
|
109
|
+
hibernate! p[FIELD_HIBERNATE_PATH]
|
110
|
+
else
|
111
|
+
super p
|
112
|
+
end
|
113
|
+
end
|
114
|
+
#
|
115
|
+
def spin!
|
116
|
+
@iotas.values.each do |iota| iota.start! end unless @hibernation
|
117
|
+
@run = true
|
118
|
+
@hibernation = false
|
119
|
+
while @run and (@sys_fifo.length>0 or @app_fifo.length>0)
|
120
|
+
while @run and @sys_fifo.length>0
|
121
|
+
p = @sys_fifo.shift
|
122
|
+
p.dst.process_sys_p p
|
123
|
+
end
|
124
|
+
while @run and @app_fifo.length>0
|
125
|
+
p = @app_fifo.shift
|
126
|
+
p.dst.process_p p
|
127
|
+
break
|
128
|
+
end
|
129
|
+
end
|
130
|
+
@iotas.values.each do |iota| iota.stop! end unless @hibernation
|
131
|
+
end
|
132
|
+
#
|
133
|
+
def stop!
|
134
|
+
@run=false
|
135
|
+
end
|
136
|
+
#
|
137
|
+
def hibernate! path=nil
|
138
|
+
@hibernation = true
|
139
|
+
File.open(path||@hibernate_path,'w') do |f| f << JSON.pretty_generate(self) end
|
140
|
+
end
|
141
|
+
#
|
142
|
+
def self.resume! path
|
143
|
+
self.json_create JSON.load File.open(path,'r') { |f| f.read }
|
144
|
+
end
|
145
|
+
#
|
146
|
+
end
|
147
|
+
#
|
148
|
+
end
|
149
|
+
#
|
150
|
+
# EOF
|
data/lib/iotas.rb
ADDED
@@ -0,0 +1,51 @@
|
|
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 iotas.
|
7
|
+
#
|
8
|
+
# iotas 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
|
+
# iotas 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 iotas. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
|
21
|
+
require 'version'
|
22
|
+
#
|
23
|
+
module Iotas
|
24
|
+
#
|
25
|
+
PATH_SEP = '/'.freeze
|
26
|
+
LINK_SEP = ','.freeze
|
27
|
+
ACT_SEP = '?'.freeze
|
28
|
+
#
|
29
|
+
ACT_GET = 'get'.freeze
|
30
|
+
ACT_ERROR = 'error'.freeze
|
31
|
+
#
|
32
|
+
SYS_ACT_HIBERNATE = 'hibernate'.freeze
|
33
|
+
SYS_ACT_ADD_LINK = 'sys_add_link'.freeze
|
34
|
+
#
|
35
|
+
FIELD_ERROR_MSG = 'edoors_error'.freeze
|
36
|
+
FIELD_HIBERNATE_PATH= 'hibernate_path'.freeze
|
37
|
+
#
|
38
|
+
class Exception < ::Exception; end
|
39
|
+
#
|
40
|
+
end
|
41
|
+
#
|
42
|
+
require 'json'
|
43
|
+
require 'iotas/particle'
|
44
|
+
require 'iotas/iota'
|
45
|
+
require 'iotas/room'
|
46
|
+
require 'iotas/spin'
|
47
|
+
require 'iotas/door'
|
48
|
+
require 'iotas/board'
|
49
|
+
require 'iotas/link'
|
50
|
+
#
|
51
|
+
# 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 iotas.
|
7
|
+
#
|
8
|
+
# iotas 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
|
+
# iotas 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 iotas. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
|
21
|
+
#
|
22
|
+
module Iotas
|
23
|
+
#
|
24
|
+
VERSION = "0.0.2"
|
25
|
+
#
|
26
|
+
end
|
27
|
+
#
|
28
|
+
# EOF
|
data/spec/board_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 Iotas::Board do
|
8
|
+
#
|
9
|
+
before (:all) do
|
10
|
+
@spin = Iotas::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 = Iotas::Board.new 'hell', @spin
|
19
|
+
p0 = board.require_p Iotas::Particle
|
20
|
+
p0.src.should be board
|
21
|
+
p1 = board.require_p Iotas::Particle
|
22
|
+
p1.src.should be board
|
23
|
+
(p0===p1).should be_false
|
24
|
+
board.release_p p0
|
25
|
+
p2 = board.require_p Iotas::Particle
|
26
|
+
p2.src.should be board
|
27
|
+
(p0===p2).should be_true
|
28
|
+
end
|
29
|
+
#
|
30
|
+
it "particle wait and merge" do
|
31
|
+
p0 = Iotas::Particle.new
|
32
|
+
p0['k0'] = 'v0'
|
33
|
+
p0['k1'] = 'neither'
|
34
|
+
p0['k2'] = 'v2'
|
35
|
+
p0.set_link_fields 'k0,k2'
|
36
|
+
p0.link_value.should eql 'v0v2'
|
37
|
+
p1 = Iotas::Particle.new
|
38
|
+
p1['k0'] = 'v0'
|
39
|
+
p1['k1'] = 'nore'
|
40
|
+
p1['k2'] = 'v2'
|
41
|
+
p1.set_link_fields 'k0,k2'
|
42
|
+
p1.link_value.should eql 'v0v2'
|
43
|
+
P0 = p0
|
44
|
+
P1 = p1
|
45
|
+
class Board0 < Iotas::Board
|
46
|
+
attr_reader :ok, :follow
|
47
|
+
def receive_p p
|
48
|
+
@ok = false
|
49
|
+
case p.action
|
50
|
+
when Iotas::ACT_FOLLOW
|
51
|
+
@follow = true
|
52
|
+
@ok = (p===P0 and p.merged(0)===P1)
|
53
|
+
else
|
54
|
+
@follow = false
|
55
|
+
@ok = (p===P1 and p.merged(0)===P0)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
b0 = Board0.new 'door0', @spin
|
60
|
+
b0.process_p p0
|
61
|
+
p0.merged(0).should be_nil
|
62
|
+
b0.process_p p1
|
63
|
+
b0.ok.should be_true
|
64
|
+
b0.follow.should be_false
|
65
|
+
#
|
66
|
+
p1.merged_shift
|
67
|
+
#
|
68
|
+
b0.process_p p0
|
69
|
+
p0.merged(0).should be_nil
|
70
|
+
# need to set it to p0 too, so case in Board0 is ok
|
71
|
+
p0.set_dst! Iotas::ACT_FOLLOW
|
72
|
+
p0.split_dst!
|
73
|
+
p1.set_dst! Iotas::ACT_FOLLOW
|
74
|
+
p1.split_dst!
|
75
|
+
b0.process_p p1
|
76
|
+
b0.ok.should be_true
|
77
|
+
b0.follow.should be_true
|
78
|
+
end
|
79
|
+
#
|
80
|
+
it "board->json->board" do
|
81
|
+
board = Iotas::Board.new 'hell', @spin
|
82
|
+
p0 = Iotas::Particle.new
|
83
|
+
p1 = Iotas::Particle.new
|
84
|
+
p1['v0']=0
|
85
|
+
p1.set_link_fields 'v0'
|
86
|
+
board.process_p p0
|
87
|
+
board.process_p p1
|
88
|
+
hell = Iotas::Board.json_create( JSON.load( JSON.generate(board) ) )
|
89
|
+
board.name.should eql hell.name
|
90
|
+
JSON.generate(board).should eql JSON.generate(hell)
|
91
|
+
end
|
92
|
+
#
|
93
|
+
end
|
94
|
+
#
|
95
|
+
# EOF
|
data/spec/door_spec.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# -*- coding: UTF-8 -*-
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'spec_helper'
|
6
|
+
#
|
7
|
+
describe Iotas::Door do
|
8
|
+
#
|
9
|
+
before (:all) do
|
10
|
+
@spin = Iotas::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 = Iotas::Door.new 'hell', @spin
|
19
|
+
p0 = door.require_p Iotas::Particle
|
20
|
+
p0.src.should be door
|
21
|
+
p1 = door.require_p Iotas::Particle
|
22
|
+
p1.src.should be door
|
23
|
+
(p0===p1).should be_false
|
24
|
+
door.release_p p0
|
25
|
+
p2 = door.require_p Iotas::Particle
|
26
|
+
p2.src.should be door
|
27
|
+
(p0===p2).should be_true
|
28
|
+
end
|
29
|
+
#
|
30
|
+
it "NoMethodError when receive_p not overridden" do
|
31
|
+
class Door0 < Iotas::Door
|
32
|
+
end
|
33
|
+
f = Fake.new 'fake', @spin
|
34
|
+
d0 = Door0.new 'door0', f
|
35
|
+
p0 = d0.require_p Iotas::Particle
|
36
|
+
lambda { d0.process_p p0 }.should raise_error(NoMethodError)
|
37
|
+
end
|
38
|
+
#
|
39
|
+
it "send_p, send_sys_p, release_p and release of lost particles" do
|
40
|
+
class Door0 < Iotas::Door
|
41
|
+
def receive_p p
|
42
|
+
case p.action
|
43
|
+
when 'RELEASE'
|
44
|
+
release_p p
|
45
|
+
when 'SEND'
|
46
|
+
send_p p
|
47
|
+
when 'SEND_SYS'
|
48
|
+
send_sys_p p
|
49
|
+
else
|
50
|
+
# lost!!
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
f = Fake.new 'fake', @spin
|
55
|
+
d0 = Door0.new 'door0', f
|
56
|
+
p0 = d0.require_p Iotas::Particle
|
57
|
+
#
|
58
|
+
p0.set_dst! 'SEND'
|
59
|
+
p0.split_dst!
|
60
|
+
d0.process_p p0
|
61
|
+
f.p.should eql p0
|
62
|
+
#
|
63
|
+
p0.set_dst! 'SEND_SYS'
|
64
|
+
p0.split_dst!
|
65
|
+
d0.process_p p0
|
66
|
+
f.sp.should eql p0
|
67
|
+
#
|
68
|
+
p0.set_dst! 'RELEASE'
|
69
|
+
p0.split_dst!
|
70
|
+
d0.process_p p0
|
71
|
+
p1 = d0.require_p Iotas::Particle
|
72
|
+
p1.should be p0
|
73
|
+
#
|
74
|
+
p0.set_dst! 'LOST'
|
75
|
+
p0.split_dst!
|
76
|
+
d0.process_p p0
|
77
|
+
p1 = d0.require_p Iotas::Particle
|
78
|
+
p1.should be p0
|
79
|
+
#
|
80
|
+
d0.process_sys_p p0
|
81
|
+
p1 = @spin.require_p Iotas::Particle
|
82
|
+
p1.should be p0
|
83
|
+
end
|
84
|
+
#
|
85
|
+
it "door->json->door" do
|
86
|
+
door = Iotas::Door.new 'hell', @spin
|
87
|
+
hell = Iotas::Door.json_create( JSON.load( JSON.generate(door) ) )
|
88
|
+
door.name.should eql hell.name
|
89
|
+
JSON.generate(door).should eql JSON.generate(hell)
|
90
|
+
end
|
91
|
+
#
|
92
|
+
end
|
93
|
+
#
|
94
|
+
# 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 Iotas::Link do
|
8
|
+
#
|
9
|
+
it "from particle data" do
|
10
|
+
@spin = Iotas::Spin.new 'dom0'
|
11
|
+
p = @spin.require_p Iotas::Particle
|
12
|
+
p.set_data Iotas::LNK_SRC, 'input1'
|
13
|
+
p.set_data Iotas::LNK_DSTS, 'concat1?follow,output1'
|
14
|
+
p.set_data Iotas::LNK_FIELDS, 'f0,f2'
|
15
|
+
p.set_data Iotas::LNK_CONDF, 'f0,f1,f2'
|
16
|
+
p.set_data Iotas::LNK_CONDV, 'v0v1v2'
|
17
|
+
lnk = Iotas::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 = Iotas::Link.new 'input1', 'concat1?follow,output1', 'f0,f2', 'f0,f1,f2', 'v0v1v2'
|
27
|
+
lnk = Iotas::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
|