rachinations 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +6 -0
- data/.travis.yml +8 -0
- data/.yardopts +1 -0
- data/Gemfile +19 -0
- data/Gemfile.lock +93 -0
- data/LICENSE.txt +21 -0
- data/README.md +18 -0
- data/Rakefile +16 -0
- data/lib/rachinations.rb +49 -0
- data/lib/rachinations/domain/diagrams/diagram.rb +167 -0
- data/lib/rachinations/domain/diagrams/non_deterministic_diagram.rb +16 -0
- data/lib/rachinations/domain/diagrams/verbose_diagram.rb +9 -0
- data/lib/rachinations/domain/edge_collection.rb +12 -0
- data/lib/rachinations/domain/edges/edge.rb +159 -0
- data/lib/rachinations/domain/edges/random_edge.rb +4 -0
- data/lib/rachinations/domain/exceptions/bad_options.rb +3 -0
- data/lib/rachinations/domain/exceptions/no_elements_found.rb +2 -0
- data/lib/rachinations/domain/exceptions/no_elements_matching_condition_error.rb +2 -0
- data/lib/rachinations/domain/exceptions/no_elements_of_given_type.rb +3 -0
- data/lib/rachinations/domain/exceptions/unsupported_type_error.rb +2 -0
- data/lib/rachinations/domain/modules/common/hash_init.rb +88 -0
- data/lib/rachinations/domain/modules/common/invariant.rb +17 -0
- data/lib/rachinations/domain/modules/diagrams/verbose.rb +30 -0
- data/lib/rachinations/domain/node_collection.rb +30 -0
- data/lib/rachinations/domain/nodes/converter.rb +276 -0
- data/lib/rachinations/domain/nodes/gate.rb +6 -0
- data/lib/rachinations/domain/nodes/node.rb +166 -0
- data/lib/rachinations/domain/nodes/pool.rb +267 -0
- data/lib/rachinations/domain/nodes/resourceful_node.rb +96 -0
- data/lib/rachinations/domain/nodes/resourceless_node.rb +11 -0
- data/lib/rachinations/domain/nodes/sink.rb +17 -0
- data/lib/rachinations/domain/nodes/source.rb +161 -0
- data/lib/rachinations/domain/nodes/trader.rb +6 -0
- data/lib/rachinations/domain/resource_bag.rb +131 -0
- data/lib/rachinations/domain/resources/token.rb +51 -0
- data/lib/rachinations/domain/strategies/strategy.rb +5 -0
- data/lib/rachinations/domain/strategies/valid_types.rb +69 -0
- data/lib/rachinations/dsl/dsl.rb +63 -0
- data/lib/rachinations/extras/fifo.rb +27 -0
- data/lib/rachinations/version.rb +3 -0
- data/machinations_diagrams/apenas_bonito.xml +22 -0
- data/machinations_diagrams/behavior_converter.xml +53 -0
- data/machinations_diagrams/behavior_converter_fim.xml +10 -0
- data/machinations_diagrams/canon/README.md +8 -0
- data/machinations_diagrams/canon/converters_differences.xml +27 -0
- data/machinations_diagrams/canon/converters_differences2.xml +34 -0
- data/machinations_diagrams/canon/converters_similarities.xml +63 -0
- data/machinations_diagrams/canon/converters_similarities2.xml +21 -0
- data/machinations_diagrams/canon/nodes_and_edges_differences.xml +15 -0
- data/machinations_diagrams/canon/nodes_and_edges_similarities.xml +20 -0
- data/machinations_diagrams/deterministic_example.xml +46 -0
- data/machinations_diagrams/economies_of_scale.xml +32 -0
- data/machinations_diagrams/feature_ou_bug.xml +5 -0
- data/machinations_diagrams/loop_in_trigger.xml +21 -0
- data/machinations_diagrams/naficadevendo.xml +12 -0
- data/machinations_diagrams/noreporting_equivalent.xml +22 -0
- data/machinations_diagrams/pull_all_example.xml +7 -0
- data/machinations_diagrams/sketch_of_memory.xml +41 -0
- data/machinations_diagrams/software_engineering_process 2.xml +130 -0
- data/machinations_diagrams/software_engineering_process v3.xml +168 -0
- data/machinations_diagrams/software_engineering_process v4.xml +192 -0
- data/machinations_diagrams/software_engineering_process.xml +65 -0
- data/machinations_diagrams/software_engineering_process_with_rework_after_test.xml +195 -0
- data/machinations_diagrams/startup_marketing.xml +35 -0
- data/machinations_diagrams/triggers_allow_multiple_stages_at_same_round.xml +19 -0
- data/machinations_diagrams/um_de_cada_vez_vs_todos_de_uma_vez.xml +20 -0
- data/rachinations.gemspec +35 -0
- data/testing/features/step_definitions/step_definitions.rb +11 -0
- data/testing/simulations/modelo1.rb +20 -0
- data/testing/simulations/modelo2.rb +49 -0
- data/testing/simulations/noreporting.rb +51 -0
- data/testing/simulations/sequencial.rb +19 -0
- data/testing/simulations/sobonito.rb +28 -0
- data/testing/simulations/sobonitowhile.rb +28 -0
- data/testing/simulations/whatIwish1.rb +20 -0
- data/testing/spec/canon/converter_spec.rb +33 -0
- data/testing/spec/canon/pool_spec.rb +68 -0
- data/testing/spec/conditions_spec.rb +10 -0
- data/testing/spec/converter_spec.rb +223 -0
- data/testing/spec/diagram_spec.rb +671 -0
- data/testing/spec/edge_spec.rb +256 -0
- data/testing/spec/hash_init_spec.rb +59 -0
- data/testing/spec/node_spec.rb +31 -0
- data/testing/spec/non_deterministic_diagram_spec.rb +112 -0
- data/testing/spec/pool_spec.rb +233 -0
- data/testing/spec/source_spec.rb +132 -0
- data/testing/spec/spec_helper.rb +34 -0
- data/testing/spec/xexeo_spec.rb +193 -0
- metadata +283 -0
@@ -0,0 +1,256 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe Edge do
|
4
|
+
|
5
|
+
describe '#initialize' do
|
6
|
+
|
7
|
+
it 'can be created' do
|
8
|
+
|
9
|
+
# i only want to test edge methods so I'll use a mock object and stub the method I need
|
10
|
+
# to call, namely :name.
|
11
|
+
|
12
|
+
from = double(:name => 'node1')
|
13
|
+
|
14
|
+
to = double(:name => 'node2')
|
15
|
+
|
16
|
+
edge = Edge.new name: 'edge1', from: from, to: to
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
it "is created with the expected defaults in case attributes aren't provided" do
|
21
|
+
edge = Edge.new name: 'edge', from: Object.new, to: Object.new
|
22
|
+
|
23
|
+
expect(edge.label).to eq 1
|
24
|
+
expect(edge.types).to eq []
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'can be created with types' do
|
29
|
+
|
30
|
+
from = double(:name => 'node1')
|
31
|
+
to = double(:name => 'node2')
|
32
|
+
|
33
|
+
edge = Edge.new name: 'edge1', from: from, to: to, types: [Blue, Black]
|
34
|
+
|
35
|
+
expect(edge.name).to eq('edge1')
|
36
|
+
expect(edge.from).to eq(from)
|
37
|
+
expect(edge.to).to eq(to)
|
38
|
+
expect(edge.support?(Blue)).to be true
|
39
|
+
expect(edge.support?(Black)).to be true
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'can be assigned an integer label' do
|
44
|
+
|
45
|
+
from = double(:name => 'node1')
|
46
|
+
to = double(:name => 'node2')
|
47
|
+
|
48
|
+
edge = Edge.new name: 'edge1', from: from, to: to, types: [Blue, Red], label: 5
|
49
|
+
|
50
|
+
expect(edge.name).to eq 'edge1'
|
51
|
+
|
52
|
+
expect(edge.from).to eq from
|
53
|
+
expect(edge.to).to eq to
|
54
|
+
|
55
|
+
expect(edge.support?(Blue)).to be true
|
56
|
+
expect(edge.support?(Black)).not_to be true
|
57
|
+
expect(edge.support?(Red)).to be true
|
58
|
+
|
59
|
+
expect(edge.label).to be 5
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#test_ping?' do
|
66
|
+
before(:each) do
|
67
|
+
@strategy=double(:condition => proc {})
|
68
|
+
@to = instance_double(ResourcefulNode, :disabled? => false, :types => double())
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when require_all' do
|
72
|
+
|
73
|
+
it 'is false when no resources can pass' do
|
74
|
+
from = instance_double(ResourcefulNode, :resource_count => 0, :disabled? => false)
|
75
|
+
|
76
|
+
edge = Edge.new :name => 'e', :from => from, :to => @to
|
77
|
+
expect(edge).to receive(:strategy).and_return(@strategy)
|
78
|
+
expect(edge.test_ping?(true)).to eq false
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'is false when some but not all required resources can pass' do
|
83
|
+
from = instance_double(ResourcefulNode, :resource_count => 5, :disabled? => false)
|
84
|
+
|
85
|
+
edge = Edge.new :name => 'e', :from => from, :to => @to, :label => 8
|
86
|
+
expect(edge).to receive(:strategy).and_return(@strategy)
|
87
|
+
expect(edge.test_ping?(true)).to eq false
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'is true when the exact number of required resources are available to be moved' do
|
91
|
+
from = instance_double(ResourcefulNode, :resource_count => 8, :disabled? => false)
|
92
|
+
|
93
|
+
edge = Edge.new :name => 'e', :from => from, :to => @to, :label => 8
|
94
|
+
expect(edge).to receive(:strategy).and_return(@strategy)
|
95
|
+
expect(edge.test_ping?(true)).to eq true
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'is true when the more resources than required are available to be moved' do
|
99
|
+
from = instance_double(ResourcefulNode, :resource_count => 3, :disabled? => false)
|
100
|
+
|
101
|
+
edge = Edge.new :name => 'e', :from => from, :to => @to, :label => 2
|
102
|
+
expect(edge).to receive(:strategy).and_return(@strategy)
|
103
|
+
expect(edge.test_ping?(true)).to eq true
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'when not require_all' do
|
109
|
+
|
110
|
+
it 'is false when no resources are available at all' do
|
111
|
+
from = instance_double(ResourcefulNode, :resource_count => 0, :disabled? => false)
|
112
|
+
|
113
|
+
edge = Edge.new :name => 'e', :from => from, :to => @to
|
114
|
+
expect(edge).to receive(:strategy).and_return(@strategy)
|
115
|
+
expect(edge.test_ping?(false)).to eq false
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'is true if at least one resource is available' do
|
119
|
+
from = instance_double(ResourcefulNode, :resource_count => 1, :disabled? => false)
|
120
|
+
|
121
|
+
edge = Edge.new :name => 'e', :from => from, :to => @to, :label => 8
|
122
|
+
expect(edge).to receive(:strategy).and_return(@strategy)
|
123
|
+
expect(edge.test_ping?(false)).to eq true
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
describe '#pull_expression' do
|
131
|
+
|
132
|
+
before(:each) do
|
133
|
+
@e = Edge.new name: 'e', from: double(), to: double()
|
134
|
+
|
135
|
+
@strat = instance_double(ValidTypes)
|
136
|
+
allow(@e).to receive(:strategy).and_return(@strat)
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'forwards the call to a strategy' do
|
140
|
+
blk=proc { |r| true }
|
141
|
+
expect(@strat).to receive(:pull_condition).and_return(blk)
|
142
|
+
@e.pull_expression
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
describe '#push_expression' do
|
148
|
+
before(:each) do
|
149
|
+
@e = Edge.new name: 'e', from: double(), to: double()
|
150
|
+
|
151
|
+
@strat = instance_double(ValidTypes)
|
152
|
+
allow(@e).to receive(:strategy).and_return(@strat)
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'forwards the call to a strategy' do
|
156
|
+
blk=proc { |r| true }
|
157
|
+
expect(@strat).to receive(:push_condition).and_return(blk)
|
158
|
+
received_blk = @e.push_expression
|
159
|
+
expect(received_blk).to be blk
|
160
|
+
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe '#pull!' do
|
165
|
+
|
166
|
+
context 'when edge has label 1' do
|
167
|
+
|
168
|
+
before(:each) do
|
169
|
+
@p1 = instance_double(Node, types: [], enabled?: true)
|
170
|
+
@p2 = instance_double(Node, types: [], enabled?: true)
|
171
|
+
@e = Edge.new name: 'e', from: @p1, to: @p2
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'sends take_resource! with a block to to_node' do
|
175
|
+
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'returns a resource in case it succeeded' do
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'raises an exception if it cannot pull the one resource' do
|
184
|
+
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
context 'when edge has label greater than 1' do
|
190
|
+
|
191
|
+
it 'sends #get_block to self before pulling anything each time' do
|
192
|
+
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'sends #take_resource! with a block from node as many times as it has' do
|
196
|
+
# as many times as the label tells it to
|
197
|
+
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'raises no exception if at least one resource (but not all) got pulled' do
|
201
|
+
# because the semantics of a label is 'at most' that many resources
|
202
|
+
# if not all could be pulled, it's not an error.
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'raises exception if no resources could be pulled' do
|
206
|
+
|
207
|
+
end
|
208
|
+
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'does not send put_resource! to the caller' do
|
212
|
+
# it merely returns the resource
|
213
|
+
|
214
|
+
end
|
215
|
+
|
216
|
+
|
217
|
+
end
|
218
|
+
|
219
|
+
describe '#push!' do
|
220
|
+
|
221
|
+
|
222
|
+
context 'when edge has label 1' do
|
223
|
+
|
224
|
+
before(:each) do
|
225
|
+
@p1 = instance_double(Node,name:'n', types: [], enabled?: true)
|
226
|
+
@p2 = instance_double(Node,name:'n2', types: [], enabled?: true)
|
227
|
+
@e = Edge.new name: 'e', from: @p1, to: @p2
|
228
|
+
end
|
229
|
+
it 'sends put_resource! to to_node' do
|
230
|
+
# passing the same parameter it was given by the caller
|
231
|
+
res = instance_double(Token,type:Token)
|
232
|
+
expect(@p2).to receive(:put_resource!)
|
233
|
+
@e.push!(res)
|
234
|
+
|
235
|
+
end
|
236
|
+
|
237
|
+
it 'raises an exception if the push was unsuccessful' do
|
238
|
+
# wrap the exception raised by to node or let it bubble up?
|
239
|
+
end
|
240
|
+
|
241
|
+
|
242
|
+
end
|
243
|
+
|
244
|
+
context 'when edge has label greater than 1' do
|
245
|
+
|
246
|
+
it 'raises error if no resources could be sent' do
|
247
|
+
|
248
|
+
end
|
249
|
+
|
250
|
+
end
|
251
|
+
|
252
|
+
|
253
|
+
end
|
254
|
+
|
255
|
+
|
256
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
# a class double so as not to bring in extra stuff we don't want to test
|
4
|
+
#http://martinfowler.com/articles/mocksArentStubs.html
|
5
|
+
class Double
|
6
|
+
include HashInit
|
7
|
+
|
8
|
+
def options
|
9
|
+
#isto é um array com 2 symbols e uma hash
|
10
|
+
[:foo, :registro, bar: :required]
|
11
|
+
end
|
12
|
+
|
13
|
+
def defaults
|
14
|
+
{
|
15
|
+
foo: 'foo',
|
16
|
+
registro: 'foobar'
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def aliases
|
21
|
+
{ resistro: :registro, boo: :bar }
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
describe 'Passing of options to Nodes' do
|
28
|
+
|
29
|
+
it 'notifies the user when no parameters were given' do
|
30
|
+
expect{Double.new}.to raise_error BadOptions
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'notifies the user when given parameter was not a hash' do
|
34
|
+
expect{Double.new Array.new}.to raise_error BadOptions
|
35
|
+
expect{Double.new Object.new}.to raise_error BadOptions
|
36
|
+
expect{Double.new String.new}.to raise_error BadOptions
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'runs ok on simple case' do
|
40
|
+
expect{Double.new bar: 'someval'}.not_to raise_error
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'raises errors if required options are not given' do
|
44
|
+
expect{Double.new foo: 'foo'}.to raise_error BadOptions
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'raises errors on invalid options' do
|
48
|
+
expect{Double.new bar: 'name', ajsdasdsad: :alkjdasdsad}.to raise_error BadOptions
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'correctly infers aliases for non-required options' do
|
52
|
+
expect{Double.new bar: 'bar', resistro: 'foo bar'}.not_to raise_error
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'correctly infers aliases for required options' do
|
56
|
+
expect{Double.new boo: 'bar'}.not_to raise_error
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe Node do
|
4
|
+
|
5
|
+
it 'knows which edges are incoming' do
|
6
|
+
|
7
|
+
n = Node.new
|
8
|
+
|
9
|
+
e = double(:to => n)
|
10
|
+
|
11
|
+
n.attach_edge(e)
|
12
|
+
|
13
|
+
expect(n.edges).to include e
|
14
|
+
expect(n.incoming_edges).to include e
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'knows which edges are outgoing' do
|
19
|
+
|
20
|
+
n = Node.new
|
21
|
+
|
22
|
+
e = double(:from => n)
|
23
|
+
|
24
|
+
n.attach_edge(e)
|
25
|
+
|
26
|
+
expect(n.edges).to include e
|
27
|
+
expect(n.outgoing_edges).to include e
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe NonDeterministicDiagram do
|
5
|
+
|
6
|
+
it "runs noreporting" do
|
7
|
+
generator = NonDeterministicDiagram.new('1to2')
|
8
|
+
#generator.extend(Verbose)
|
9
|
+
|
10
|
+
generator.add_node! Pool, {
|
11
|
+
name: 'g1',
|
12
|
+
activation: :automatic,
|
13
|
+
initial_value: 5,
|
14
|
+
mode: :push
|
15
|
+
}
|
16
|
+
|
17
|
+
generator.add_node! Pool, {
|
18
|
+
name: 'g2',
|
19
|
+
activation: :automatic,
|
20
|
+
mode: :push
|
21
|
+
}
|
22
|
+
|
23
|
+
generator.add_node! Pool, {
|
24
|
+
name: 'g3'
|
25
|
+
}
|
26
|
+
|
27
|
+
generator.add_edge! Edge, {
|
28
|
+
name: 'c1',
|
29
|
+
from: 'g1',
|
30
|
+
to: 'g2'
|
31
|
+
}
|
32
|
+
|
33
|
+
generator.add_edge! Edge, {
|
34
|
+
name: 'c2',
|
35
|
+
from: 'g1',
|
36
|
+
to: 'g3',
|
37
|
+
}
|
38
|
+
|
39
|
+
|
40
|
+
generator.add_edge! Edge, {
|
41
|
+
name: 'c3',
|
42
|
+
from: 'g2',
|
43
|
+
to: 'g1',
|
44
|
+
}
|
45
|
+
|
46
|
+
generator.run!(100) #should be enough
|
47
|
+
|
48
|
+
# don´t know what to test...
|
49
|
+
expect(generator.get_node('g3').resource_count).to eq 5
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
include DSL
|
54
|
+
|
55
|
+
it ' makes a train run' do
|
56
|
+
|
57
|
+
|
58
|
+
d = NonDeterministicDiagram.new 'dia'
|
59
|
+
|
60
|
+
d.add_node! Pool, {
|
61
|
+
name: 'p1',
|
62
|
+
mode: :push_any,
|
63
|
+
activation: :automatic,
|
64
|
+
initial_value: 8
|
65
|
+
}
|
66
|
+
|
67
|
+
d.add_node! Pool, {
|
68
|
+
name: 'p2',
|
69
|
+
mode: :push_any,
|
70
|
+
activation: :automatic
|
71
|
+
}
|
72
|
+
|
73
|
+
d.add_node! Pool, {
|
74
|
+
name: 'p3',
|
75
|
+
mode: :push_any,
|
76
|
+
activation: :automatic
|
77
|
+
}
|
78
|
+
|
79
|
+
d.add_node! Pool, {
|
80
|
+
name: 'p4',
|
81
|
+
mode: :push_any,
|
82
|
+
activation: :automatic
|
83
|
+
}
|
84
|
+
|
85
|
+
d.add_edge! Edge, {
|
86
|
+
name: 'e1',
|
87
|
+
from: 'p1',
|
88
|
+
to: 'p2'
|
89
|
+
}
|
90
|
+
d.add_edge! Edge, {
|
91
|
+
name: 'e2',
|
92
|
+
from: 'p2',
|
93
|
+
to: 'p3'
|
94
|
+
}
|
95
|
+
d.add_edge! Edge, {
|
96
|
+
name: 'e3',
|
97
|
+
from: 'p3',
|
98
|
+
to: 'p4'
|
99
|
+
}
|
100
|
+
|
101
|
+
|
102
|
+
d.run!(200)
|
103
|
+
|
104
|
+
expect(d.get_node('p1').resource_count).to eq 0
|
105
|
+
expect(d.get_node('p2').resource_count).to eq 0
|
106
|
+
expect(d.get_node('p3').resource_count).to eq 0
|
107
|
+
expect(d.get_node('p4').resource_count).to eq 8
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
end
|