shrewd 0.0.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.
@@ -0,0 +1,50 @@
1
+ # EventSpec
2
+ #
3
+ # Tests for the Shrewd::EventSpec class
4
+
5
+ require 'shrewd/simulation'
6
+ require 'shrewd/entities/event'
7
+ require 'shrewd/entities/process'
8
+
9
+ describe Shrewd::Event do
10
+
11
+ # Shared variables
12
+ let(:name) { 'Initial' }
13
+ let(:description) { 'Description' }
14
+ let(:processes) { [ Shrewd::Process.new('Process1'),
15
+ Shrewd::Process.new('Process2') ] }
16
+
17
+ describe "initialization" do
18
+
19
+ context "with name only" do
20
+ before :each do
21
+ @event = Shrewd::Event.new(name)
22
+ end
23
+
24
+ it "should be valid" do
25
+ expect(@event).to be_an_instance_of Shrewd::Event
26
+ expect(@event.name).to eql name
27
+ expect(@event.description).to be_empty
28
+ expect(@event.processes).to eql Array.new
29
+ expect(@event.action).to be_nil
30
+ end
31
+
32
+ end
33
+
34
+ context "with all parameters" do
35
+ let(:action) { Proc.new { |variables| } }
36
+
37
+ before :each do
38
+ @event = Shrewd::Event.new(name, description, processes, action)
39
+ end
40
+
41
+ it "should be valid" do
42
+ expect(@event).to be_an_instance_of Shrewd::Event
43
+ expect(@event.name).to eql name
44
+ expect(@event.description).to eql description
45
+ expect(@event.processes).to eql processes
46
+ expect(@event.action).to eql action
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,51 @@
1
+ # ProcessSpec
2
+ #
3
+ # Tests for Shrewd::ProcessSpec class
4
+
5
+ module Shrewd
6
+ require 'shrewd/entities/process'
7
+ require 'shrewd/entities/event'
8
+ end
9
+
10
+ describe Shrewd::Process do
11
+
12
+ describe "initialization" do
13
+ let(:name) { 'Service Event' }
14
+ let(:description) { 'Servicing a customer.' }
15
+ let(:event) { Shrewd::Event.new('Event') }
16
+ let(:conditions) { Proc.new { |variables| true } }
17
+ let(:delay) { Proc.new { |variables| 15 } }
18
+
19
+ context "with only name" do
20
+ before :each do
21
+ @process = Shrewd::Process.new(name)
22
+ end
23
+
24
+ it "should be valid" do
25
+ expect(@process).to be_an_instance_of Shrewd::Process
26
+ expect(@process.name).to eql name
27
+ expect(@process.description).to be_empty
28
+ expect(@process.event).to be_nil
29
+ expect(@process.conditions).to be_nil
30
+ expect(@process.delay).to be_nil
31
+ end
32
+ end
33
+
34
+ context "with all parameters" do
35
+ before :each do
36
+ @process = Shrewd::Process.new(name, description,
37
+ event, conditions, delay)
38
+ end
39
+
40
+ it "should be valid" do
41
+ expect(@process).to be_an_instance_of Shrewd::Process
42
+ expect(@process.name).to eql name
43
+ expect(@process.description).to eql description
44
+ expect(@process.event).to eql event
45
+ expect(@process.conditions).to eql conditions
46
+ expect(@process.delay).to eql delay
47
+ end
48
+ end
49
+ end
50
+
51
+ end
@@ -0,0 +1,180 @@
1
+ # SimulationSpec
2
+ #
3
+ # Tests for the Shrewd::Simulation class
4
+
5
+ require 'shrewd/simulation'
6
+
7
+ describe Shrewd::Simulation do
8
+
9
+ # Shared variables
10
+ let(:state_variables) { [ Shrewd::Variable.new('Queue'),
11
+ Shrewd::Variable.new('Employees', '', 5)] }
12
+ let(:process_length) { 20 }
13
+ let(:simulation_length) { 1000 }
14
+ let(:initial_processes) do
15
+ process = Shrewd::Process.new('Process1')
16
+ process.delay = Proc.new { process_length }
17
+
18
+ event = Shrewd::Event.new('Arrival')
19
+ event.processes << process
20
+ process.event = event
21
+
22
+ [ process ]
23
+ end
24
+
25
+ # Create a simulation instance before each test
26
+ before :each do
27
+ @simulation = Shrewd::Simulation.new(state_variables, initial_processes)
28
+ end
29
+
30
+ # Validate new simulation instance
31
+ describe "#new" do
32
+ it "should be a simulation" do
33
+ expect(@simulation).to be_an_instance_of Shrewd::Simulation
34
+ end
35
+
36
+ it "instantiates variables correctly" do
37
+ variables = @simulation.instance_variable_get(:@variables)
38
+ expect(variables).to be_an_instance_of Hash
39
+
40
+ variables.values.each do |variable|
41
+ expect(variable).to be_an_instance_of Shrewd::Variable
42
+ end
43
+
44
+ variables.each do |key, value|
45
+ expect(key).to eql value.name.downcase.gsub(/\s+/,"_").to_sym
46
+ end
47
+
48
+ expect(@simulation.initial_processes).to be_an_instance_of Array
49
+ expect(@simulation.initial_processes).to eql initial_processes
50
+
51
+ @simulation.initial_processes.each do |process|
52
+ expect(process).to be_an_instance_of Shrewd::Process
53
+ end
54
+ end
55
+ end
56
+
57
+ describe "#start" do
58
+ before :each do
59
+ @simulation.start(simulation_length)
60
+ end
61
+
62
+ it "generates a start event" do
63
+ expect(@simulation.print_log.size).to eql (simulation_length/process_length) + 1
64
+ expect(@simulation.print_log.first[:event].name).to eql 'Start'
65
+ end
66
+ end
67
+
68
+ describe "#print_log" do
69
+ it "generates a log" do
70
+ expect(@simulation.print_log).to be_an_instance_of Array
71
+ end
72
+ end
73
+
74
+ describe "#create_initial_event" do
75
+ before :each do
76
+ @simulation.send(:create_initial_event)
77
+ @queue = @simulation.instance_variable_get(:@queue)
78
+ end
79
+
80
+ it "adds initial event to the queue" do
81
+ expect(@queue.size).to eql 1
82
+ end
83
+
84
+ it "creates initial event" do
85
+ initial_event = @queue.first[:event]
86
+ expect(initial_event).to be_an_instance_of Shrewd::Event
87
+ expect(initial_event.name).to eql 'Start'
88
+ end
89
+
90
+ it "adds initial processes to initial event" do
91
+ initial_event = @queue.first[:event]
92
+ expect(initial_event.processes.size).to be > 0
93
+ expect(initial_event.processes).to eql initial_processes
94
+ end
95
+ end
96
+
97
+ describe "#add_to_queue" do
98
+ let(:first_name) { 'First' }
99
+ let(:first_time) { 5 }
100
+ let(:second_name) { 'Second' }
101
+ let(:second_time) { 10 }
102
+ let(:third_name) { 'Third' }
103
+ let(:third_time) { 7 }
104
+ let(:fourth_name) { 'Fourth' }
105
+ let(:fourth_time) { 3 }
106
+
107
+ before :each do
108
+ @initial_event = Shrewd::Event.new(first_name)
109
+ @simulation.send(:add_to_queue, { time: first_time, event: @initial_event })
110
+ @queue = @simulation.instance_variable_get(:@queue)
111
+ end
112
+
113
+ it "adds an event to the queue" do
114
+ expect(@queue).to be_an_instance_of Array
115
+ expect(@queue).to_not be_empty
116
+ expect(@queue.first[:event].name).to eql first_name
117
+ expect(@queue.first[:time]).to eql first_time
118
+ end
119
+
120
+ # Test base binary search
121
+ context "multiples events" do
122
+ before :each do
123
+ @second_event = Shrewd::Event.new(second_name)
124
+ @simulation.send(:add_to_queue, { time: second_time,
125
+ event: @second_event })
126
+ end
127
+
128
+ it "adds second event to the queue" do
129
+ expect(@queue.size).to eql 2
130
+ expect(@queue[1][:event].name).to eql second_name
131
+ expect(@queue[1][:time]).to eql second_time
132
+ end
133
+
134
+ context "with third and fourth event" do
135
+ before :each do
136
+ @third_event = Shrewd::Event.new(third_name)
137
+ @fourth_event = Shrewd::Event.new(fourth_name)
138
+
139
+ @simulation.send(:add_to_queue, { time: third_time,
140
+ event: @third_event })
141
+ @simulation.send(:add_to_queue, { time: fourth_time,
142
+ event: @fourth_event })
143
+ end
144
+
145
+ it "adds third and fourth events to the queue" do
146
+ expect(@queue.size).to eql 4
147
+ end
148
+
149
+ it "places events in order" do
150
+ time = 0
151
+ @queue.each do |item|
152
+ expect(item[:time]).to be > time
153
+ time = item[:time]
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
159
+
160
+ describe "#reset" do
161
+ before :each do
162
+ @simulation.start(1000)
163
+ @simulation.reset
164
+ end
165
+
166
+ it "resets system state" do
167
+ log = @simulation.print_log
168
+ queue = @simulation.instance_variable_get(:@queue)
169
+ clock = @simulation.instance_variable_get(:@clock)
170
+ variables = @simulation.instance_variable_get(:@variables)
171
+ initial = @simulation.instance_variable_get(:@initial_state)
172
+
173
+ expect(log).to be_empty
174
+ expect(queue).to be_empty
175
+ expect(clock).to eql 0
176
+ expect(variables).to eql initial
177
+ end
178
+
179
+ end
180
+ end
@@ -0,0 +1,195 @@
1
+ # VariableSpec
2
+ #
3
+ # Tests for the Shrewd::Variable class
4
+
5
+ require 'shrewd/entities/variable'
6
+
7
+ describe Shrewd::Variable do
8
+
9
+ # Shared variables
10
+ let(:name) { 'Queue' }
11
+ let(:description) { 'Number of people in line.' }
12
+ let(:initial_value) { 5 }
13
+
14
+ describe "initialization" do
15
+
16
+ # Common examples for validating a variable
17
+ shared_examples "valid variable" do
18
+
19
+ it "should be a variable" do
20
+ expect(@variable).to be_an_instance_of Shrewd::Variable
21
+ end
22
+
23
+ it "should have the correct properties" do
24
+ expect(@variable.name).to eql name
25
+ expect(@variable.description).to eql description
26
+ end
27
+
28
+ end
29
+
30
+ context "when default value provided" do
31
+
32
+ before :each do
33
+ @variable = Shrewd::Variable.new(name, description, initial_value)
34
+ end
35
+
36
+ include_examples "valid variable"
37
+
38
+ it "should have the provided default value" do
39
+ expect(@variable.value).to eql initial_value
40
+ end
41
+
42
+ end
43
+
44
+ context "when no default value provided" do
45
+
46
+ before :each do
47
+ @variable = Shrewd::Variable.new(name, description)
48
+ end
49
+
50
+ include_examples "valid variable"
51
+
52
+ it "should have a default of 0" do
53
+ expect(@variable.value).to eql 0
54
+ end
55
+
56
+ end
57
+
58
+ end
59
+
60
+ describe "increment" do
61
+
62
+ let(:positive_amount) { 4 }
63
+ let(:negative_amount) { -2 }
64
+
65
+ before :each do
66
+ @variable = Shrewd::Variable.new(name, description, initial_value)
67
+ end
68
+
69
+ context "by default amount" do
70
+
71
+ before :each do
72
+ @variable.increment
73
+ end
74
+
75
+ it "should add one to initial value" do
76
+ expected_value = initial_value + 1
77
+ expect(@variable.value).to eql expected_value
78
+ end
79
+ end
80
+
81
+ context "by positive amount" do
82
+
83
+ before :each do
84
+ @variable.increment positive_amount
85
+ end
86
+
87
+ it "should add positive amount to initial value" do
88
+ expected_value = initial_value + positive_amount
89
+ expect(@variable.value).to eql expected_value
90
+ end
91
+
92
+ end
93
+
94
+ context "by negative amount" do
95
+
96
+ before :each do
97
+ @variable.increment negative_amount
98
+ end
99
+
100
+ it "should subtract negative amount from initial value" do
101
+ expected_value = initial_value + negative_amount
102
+ expect(@variable.value).to eql expected_value
103
+ end
104
+
105
+ end
106
+ end
107
+
108
+ describe "decrement" do
109
+
110
+ let(:positive_amount) { 2 }
111
+ let(:negative_amount) { -2 }
112
+
113
+ before :each do
114
+ @variable = Shrewd::Variable.new(name, description, initial_value)
115
+ end
116
+
117
+ context "by default amount" do
118
+
119
+ before :each do
120
+ @variable.decrement
121
+ end
122
+
123
+ it "should subtract one from initial value" do
124
+ expected_value = initial_value - 1
125
+ expect(@variable.value).to eql expected_value
126
+ end
127
+ end
128
+
129
+ context "by provided positive amount" do
130
+
131
+ before :each do
132
+ @variable.decrement positive_amount
133
+ end
134
+
135
+ it "should subtract positive amount from initial value" do
136
+ expected_value = initial_value - positive_amount
137
+ expect(@variable.value).to eql expected_value
138
+ end
139
+
140
+ end
141
+
142
+ context "by provided negative amount" do
143
+
144
+ before :each do
145
+ @variable.decrement negative_amount
146
+ end
147
+
148
+ it "should add negative amount to initial value" do
149
+ expected_value = initial_value - negative_amount
150
+ expect(@variable.value).to eql expected_value
151
+ end
152
+
153
+ end
154
+ end
155
+
156
+ describe "compare" do
157
+
158
+ context "with self" do
159
+ before :each do
160
+ @variable1 = Shrewd::Variable.new(name, description, initial_value)
161
+ @variable2 = @variable1
162
+ end
163
+
164
+ it "should be equal" do
165
+ expect(@variable1 == @variable2.value).to be true
166
+ end
167
+ end
168
+
169
+ context "with variable with same value" do
170
+ before :each do
171
+ @variable1 = Shrewd::Variable.new(name, description, initial_value)
172
+ @variable2 = Shrewd::Variable.new(name, description, initial_value)
173
+ end
174
+
175
+ it "should be equal" do
176
+ expect(@variable1 == @variable2.value).to be true
177
+ end
178
+ end
179
+
180
+ context "with a variable with different value" do
181
+ let(:different_value) { initial_value + 3 }
182
+
183
+ before :each do
184
+ @variable1 = Shrewd::Variable.new(name, description, initial_value)
185
+ @variable2 = Shrewd::Variable.new(name, description, different_value)
186
+ end
187
+
188
+ it "should not be equal" do
189
+ expect(@variable1 == @variable2.value).to be false
190
+ end
191
+
192
+ end
193
+
194
+ end
195
+ end