toy_robot 1.0.4

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,11 @@
1
+ module ToyRobot
2
+ class Roboto
3
+ class Speech
4
+
5
+ def speak(something)
6
+ puts something
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,26 @@
1
+ module ToyRobot
2
+ class Simulator
3
+
4
+ attr_reader :roboto, :table
5
+
6
+ def initialize(table_size: {x: 5, y: 5})
7
+ @roboto = Roboto.new
8
+ @table = Table.new(table_size)
9
+ inform_roboto_about_table
10
+ end
11
+
12
+ def run(orders)
13
+ orders.each do |order|
14
+ understood = @roboto.understand_order(order)
15
+ @roboto.execute_order(understood)
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def inform_roboto_about_table
22
+ @roboto.table_edges = @table.edges
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ module ToyRobot
2
+ class Table
3
+
4
+ attr_reader :roboto, :x, :y
5
+
6
+ def initialize(x:, y:)
7
+ @x = x
8
+ @y = y
9
+ end
10
+
11
+ # Returns a Hash with the limits for X and Y axis
12
+ def edges
13
+ { x: x_limits, y: y_limits }
14
+ end
15
+
16
+ # Returns a hash with min and max values for X based on initial value
17
+ def x_limits
18
+ { min: 0, max: @x-1 }
19
+ end
20
+
21
+ # Returns a hash with min and max values for Y based on initial value
22
+ def y_limits
23
+ { min: 0, max: @y-1 }
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ module ToyRobot
2
+ VERSION = '1.0.4'
3
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ describe ToyRobot::Bin::IOUtils do
4
+
5
+ let(:dummy_class) { Class.new { extend ToyRobot::Bin::IOUtils } }
6
+
7
+ before do
8
+ allow_any_instance_of(Object).to receive(:sleep)
9
+ end
10
+
11
+ describe '#print_with_delay' do
12
+
13
+ it 'prints a message' do
14
+ expect { dummy_class.print_with_delay('a message') }.to match_stdout('a message')
15
+ end
16
+
17
+ it 'has a default delay of 2 seconds' do
18
+ expect(dummy_class).to receive(:delay).with(2)
19
+ dummy_class.print_with_delay('a message')
20
+ end
21
+
22
+ it 'can have custom delay time' do
23
+ expect(dummy_class).to receive(:delay).with(5)
24
+ dummy_class.print_with_delay('a message', 5)
25
+ end
26
+
27
+ end
28
+
29
+ describe '#_print' do
30
+
31
+ it 'prints a message' do
32
+ expect { dummy_class._print('a message') }.to match_stdout('a message')
33
+ end
34
+
35
+ end
36
+
37
+ describe '#delay' do
38
+
39
+ it 'sleeps for desired time' do
40
+ expect(dummy_class).to receive(:sleep).with(3)
41
+ dummy_class.delay 3
42
+ end
43
+
44
+ end
45
+
46
+ describe '#yellow' do
47
+
48
+ it 'returns a yellowish string' do
49
+ expect(dummy_class.yellow('yellowish string')).to eq "\e[33myellowish string\e[0m"
50
+ end
51
+
52
+ end
53
+
54
+ describe '#green' do
55
+
56
+ it 'returns a greenish string' do
57
+ expect(dummy_class.green('greenish string')).to eq "\e[32mgreenish string\e[0m"
58
+ end
59
+
60
+ end
61
+
62
+ describe '#reddish' do
63
+
64
+ it 'returns a reddish string' do
65
+ expect(dummy_class.red('reddish string')).to eq "\e[31mreddish string\e[0m"
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+
3
+ describe ToyRobot::Bin::Runner do
4
+
5
+ before do
6
+ allow_any_instance_of(Object).to receive(:puts)
7
+ allow(subject).to receive(:capture_input) { '1' }
8
+ end
9
+
10
+ it 'has a simulator' do
11
+ expect(subject.simulator).to be_an_instance_of(ToyRobot::Simulator)
12
+ end
13
+
14
+ it 'has a roboto' do
15
+ expect(subject.roboto).to be_an_instance_of(ToyRobot::Roboto)
16
+ end
17
+
18
+ it 'assigns roboto a random name' do
19
+ allow_any_instance_of(ToyRobot::Bin::Runner).to receive(:robots).and_return(['random name'])
20
+ subject = ToyRobot::Bin::Runner.new
21
+ expect(subject.roboto.name).to eq 'random name'
22
+ end
23
+
24
+ describe '#start' do
25
+
26
+ context 'checking prints' do
27
+
28
+ before do
29
+ allow(subject).to receive(:handle_selected_option)
30
+ end
31
+
32
+ it 'shows art' do
33
+ expect(subject).to receive(:show_art)
34
+ subject.start
35
+ end
36
+
37
+ it 'shows help' do
38
+ expect(subject).to receive(:show_help)
39
+ subject.start
40
+ end
41
+
42
+ it 'shows options' do
43
+ expect(subject).to receive(:show_options)
44
+ subject.start
45
+ end
46
+
47
+ end
48
+
49
+ it 'captures user option' do
50
+ allow(subject).to receive(:handle_selected_option)
51
+ subject.start
52
+ expect(subject.selected_option).to eq '1'
53
+ end
54
+
55
+ context 'handling selected option' do
56
+
57
+ context 'when 1' do
58
+
59
+ it 'inputs by hand' do
60
+ expect(subject).to receive(:input_by_hand)
61
+ subject.start
62
+ end
63
+
64
+ end
65
+
66
+ context 'when 2' do
67
+
68
+ before do
69
+ allow(subject).to receive(:capture_input) { '2' }
70
+ end
71
+
72
+ it 'inputs from file' do
73
+ expect(subject).to receive(:input_from_file)
74
+ subject.start
75
+ end
76
+
77
+ end
78
+
79
+ context 'when else' do
80
+
81
+ before do
82
+ allow(subject).to receive(:capture_input) { '3' }
83
+ allow(subject).to receive(:show_art)
84
+ allow(subject).to receive(:show_help)
85
+ allow(subject).to receive(:show_options)
86
+ end
87
+
88
+ it 'prints termination message' do
89
+ expect(subject).to receive(:_print).with('Invalid option, terminating simulator.')
90
+ subject.start
91
+ end
92
+ end
93
+
94
+ end
95
+
96
+ end
97
+
98
+ end
@@ -0,0 +1,5 @@
1
+ MOVE
2
+ PLACE 1,2,NORTH
3
+ LEFT
4
+ RIGHT
5
+ REPORT
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe ToyRobot::ManifestReader do
4
+
5
+ describe '#read' do
6
+
7
+ it 'reads from a default file' do
8
+ subject = ToyRobot::ManifestReader.new
9
+ expect(subject.file).to be_a File
10
+ end
11
+
12
+ it 'reads from custom file' do
13
+ file_path = File.join(File.dirname(__FILE__), 'fixtures', 'manifest_example.txt')
14
+ subject = ToyRobot::ManifestReader.new(file_path: file_path)
15
+ expect(subject.file.path).to eq file_path
16
+ end
17
+
18
+ it 'returns an array with orders' do
19
+ subject = ToyRobot::ManifestReader.new(file_path: File.join(File.dirname(__FILE__), 'fixtures', 'manifest_example.txt'))
20
+ orders_array = [
21
+ 'MOVE',
22
+ 'PLACE 1,2,NORTH',
23
+ 'LEFT',
24
+ 'RIGHT',
25
+ 'REPORT'
26
+ ]
27
+ expect(subject.read).to match_array(orders_array)
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe ToyRobot::Roboto::Brain do
4
+
5
+ it 'has a motor cortex' do
6
+ expect(subject.motor_cortex).to be_an_instance_of(ToyRobot::Roboto::MotorCortex)
7
+ end
8
+
9
+ it 'has speech' do
10
+ expect(subject.speech).to be_an_instance_of(ToyRobot::Roboto::Speech)
11
+ end
12
+
13
+ it 'delegates speak to Speech' do
14
+ expect(subject.speech).to receive(:speak).with('something')
15
+ subject.speak('something')
16
+ end
17
+
18
+ describe '#understand_order' do
19
+
20
+ it 'understand order with bad input' do
21
+ expect(subject.understand_order(' PLACE 1,2,nORTH')).to eq({ command: :place, args: { x: 1, y: 2, f: :north} })
22
+ end
23
+
24
+ context 'when ordering placement' do
25
+
26
+ it 'sanitizes args' do
27
+ expect(subject.understand_order('PLACE 1,2,NORTH')[:args]).to eq({ x: 1, y: 2, f: :north})
28
+ end
29
+
30
+ end
31
+
32
+
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,322 @@
1
+ require 'spec_helper'
2
+
3
+ describe ToyRobot::Roboto::MotorCortex do
4
+
5
+ it 'has a list of cardinal directions' do
6
+ expect(ToyRobot::Roboto::MotorCortex).to have_constant(:CARDINAL_DIRECTIONS)
7
+ end
8
+
9
+ it 'has a list of move directions' do
10
+ expect(ToyRobot::Roboto::MotorCortex).to have_constant(:MOVE)
11
+ end
12
+
13
+ describe '#reset' do
14
+
15
+ subject { ToyRobot::Roboto::MotorCortex.new(x: 2, y: 3, f: :north) }
16
+
17
+ it 'sets X, Y and forwarding direction' do
18
+ subject.reset(x: 1, y: 2, f: :south)
19
+ expect(subject.x).to eq 1
20
+ expect(subject.y).to eq 2
21
+ expect(subject.f).to eq :south
22
+ end
23
+
24
+ it 'raises an exception if cardinal direction is not recognized' do
25
+ expect { subject.reset(x: 1, y: 2, f: :southwest) }.to raise_error('southwest is not a recognized direction')
26
+ end
27
+
28
+ end
29
+
30
+ describe '#rotate_ccw' do
31
+
32
+ context 'when facing north' do
33
+
34
+ subject { ToyRobot::Roboto::MotorCortex.new(f: :north) }
35
+
36
+ it 'rotates to west' do
37
+ subject.rotate_ccw
38
+ expect(subject.f).to eq :west
39
+ end
40
+
41
+ end
42
+
43
+ context 'when facing east' do
44
+
45
+ subject { ToyRobot::Roboto::MotorCortex.new(f: :east) }
46
+
47
+ it 'rotates to north' do
48
+ subject.rotate_ccw
49
+ expect(subject.f).to eq :north
50
+ end
51
+
52
+ end
53
+
54
+ context 'when facing south' do
55
+
56
+ subject { ToyRobot::Roboto::MotorCortex.new(f: :south) }
57
+
58
+ it 'rotates to east' do
59
+ subject.rotate_ccw
60
+ expect(subject.f).to eq :east
61
+ end
62
+
63
+ end
64
+
65
+ context 'when facing west' do
66
+
67
+ subject { ToyRobot::Roboto::MotorCortex.new(f: :west) }
68
+
69
+ it 'rotates to south' do
70
+ subject.rotate_ccw
71
+ expect(subject.f).to eq :south
72
+ end
73
+
74
+ end
75
+
76
+ end
77
+
78
+ describe '#rotate_cw' do
79
+
80
+ context 'when facing north' do
81
+
82
+ subject { ToyRobot::Roboto::MotorCortex.new(f: :north) }
83
+
84
+ it 'rotates to east' do
85
+ subject.rotate_cw
86
+ expect(subject.f).to eq :east
87
+ end
88
+
89
+ end
90
+
91
+ context 'when facing east' do
92
+
93
+ subject { ToyRobot::Roboto::MotorCortex.new(f: :east) }
94
+
95
+ it 'rotates to south' do
96
+ subject.rotate_cw
97
+ expect(subject.f).to eq :south
98
+ end
99
+
100
+ end
101
+
102
+ context 'when facing south' do
103
+
104
+ subject { ToyRobot::Roboto::MotorCortex.new(f: :south) }
105
+
106
+ it 'rotates to west' do
107
+ subject.rotate_cw
108
+ expect(subject.f).to eq :west
109
+ end
110
+
111
+ end
112
+
113
+ context 'when facing west' do
114
+
115
+ subject { ToyRobot::Roboto::MotorCortex.new(f: :west) }
116
+
117
+ it 'rotates to north' do
118
+ subject.rotate_cw
119
+ expect(subject.f).to eq :north
120
+ end
121
+
122
+ end
123
+
124
+ end
125
+
126
+ describe '#forward' do
127
+
128
+ context 'when facing north' do
129
+
130
+ subject { ToyRobot::Roboto::MotorCortex.new(x: 1, y: 1, f: :north) }
131
+
132
+ it 'increases Y axis by one' do
133
+ subject.forward
134
+ expect(subject.y).to eq 2
135
+ end
136
+
137
+ it 'keeps X axis the same' do
138
+ subject.forward
139
+ expect(subject.x).to eq 1
140
+ end
141
+
142
+ it 'keeps forwarding direction the same' do
143
+ subject.forward
144
+ expect(subject.f).to eq :north
145
+ end
146
+
147
+ end
148
+
149
+ context 'when facing east' do
150
+
151
+ subject { ToyRobot::Roboto::MotorCortex.new(x: 1, y: 1, f: :east) }
152
+
153
+ it 'increases X axis by one' do
154
+ subject.forward
155
+ expect(subject.x).to eq 2
156
+ end
157
+
158
+ it 'keeps Y axis the same' do
159
+ subject.forward
160
+ expect(subject.y).to eq 1
161
+ end
162
+
163
+ it 'keeps forwarding direction the same' do
164
+ subject.forward
165
+ expect(subject.f).to eq :east
166
+ end
167
+
168
+ end
169
+
170
+ context 'when facing south' do
171
+
172
+ subject { ToyRobot::Roboto::MotorCortex.new(x: 1, y: 1, f: :south) }
173
+
174
+ it 'decreases Y axis by one' do
175
+ subject.forward
176
+ expect(subject.y).to eq 0
177
+ end
178
+
179
+ it 'keeps X axis the same' do
180
+ subject.forward
181
+ expect(subject.x).to eq 1
182
+ end
183
+
184
+ it 'keeps forwarding direction the same' do
185
+ subject.forward
186
+ expect(subject.f).to eq :south
187
+ end
188
+
189
+ end
190
+
191
+ context 'when facing west' do
192
+
193
+ subject { ToyRobot::Roboto::MotorCortex.new(x: 1, y: 1, f: :west) }
194
+
195
+ it 'decreases X axis by one' do
196
+ subject.forward
197
+ expect(subject.x).to eq 0
198
+ end
199
+
200
+ it 'keeps Y axis the same' do
201
+ subject.forward
202
+ expect(subject.y).to eq 1
203
+ end
204
+
205
+ it 'keeps forwarding direction the same' do
206
+ subject.forward
207
+ expect(subject.f).to eq :west
208
+ end
209
+
210
+ end
211
+
212
+ end
213
+
214
+ describe '#forward_prediction' do
215
+
216
+ context 'when facing north' do
217
+
218
+ subject { ToyRobot::Roboto::MotorCortex.new(x: 1, y: 1, f: :north) }
219
+
220
+ it 'increases Y axis by one' do
221
+ expect(subject.forward_prediction).to eq [1, 2]
222
+ end
223
+
224
+ end
225
+
226
+ context 'when facing east' do
227
+
228
+ subject { ToyRobot::Roboto::MotorCortex.new(x: 1, y: 1, f: :east) }
229
+
230
+ it 'increases X axis by one' do
231
+ expect(subject.forward_prediction).to eq [2, 1]
232
+ end
233
+
234
+ end
235
+
236
+ context 'when facing south' do
237
+
238
+ subject { ToyRobot::Roboto::MotorCortex.new(x: 1, y: 1, f: :south) }
239
+
240
+ it 'decreases Y axis by one' do
241
+ expect(subject.forward_prediction).to eq [1, 0]
242
+ end
243
+
244
+ end
245
+
246
+ context 'when facing west' do
247
+
248
+ subject { ToyRobot::Roboto::MotorCortex.new(x: 1, y: 1, f: :west) }
249
+
250
+ it 'decreases X axis by one' do
251
+ expect(subject.forward_prediction).to eq [0, 1]
252
+ end
253
+
254
+ end
255
+
256
+ end
257
+
258
+ describe '#to_s' do
259
+
260
+ subject { ToyRobot::Roboto::MotorCortex.new(x: 3, y: 6, f: :north) }
261
+
262
+ it 'returns a formated string with axis and forwarding direction' do
263
+ expect(subject.to_s).to eq 'X: 3, Y: 6, F: north'
264
+ end
265
+
266
+ context 'when X is nil' do
267
+
268
+ subject { ToyRobot::Roboto::MotorCortex.new(x: nil, y: 6, f: :north) }
269
+
270
+ it 'says N/A' do
271
+ expect(subject.to_s).to eq 'X: N/A, Y: 6, F: north'
272
+ end
273
+
274
+ end
275
+
276
+ context 'when Y is nil' do
277
+
278
+ subject { ToyRobot::Roboto::MotorCortex.new(x: 2, y: nil, f: :north) }
279
+
280
+ it 'says N/A' do
281
+ expect(subject.to_s).to eq 'X: 2, Y: N/A, F: north'
282
+ end
283
+
284
+ end
285
+
286
+ context 'when F is nil' do
287
+
288
+ subject { ToyRobot::Roboto::MotorCortex.new(x: 2, y: 3, f: nil) }
289
+
290
+ it 'says N/A' do
291
+ expect(subject.to_s).to eq 'X: 2, Y: 3, F: N/A'
292
+ end
293
+
294
+ end
295
+
296
+ end
297
+
298
+ describe '#nil?' do
299
+
300
+ context 'when X, Y and F are present' do
301
+
302
+ subject { ToyRobot::Roboto::MotorCortex.new(x: 3, y: 6, f: :north) }
303
+
304
+ it 'returns false' do
305
+ expect(subject.nil?).to be_falsy
306
+ end
307
+
308
+ end
309
+
310
+ context 'when X or Y or F are nil' do
311
+
312
+ subject { ToyRobot::Roboto::MotorCortex.new(x: 3, y: nil, f: :north) }
313
+
314
+ it 'returns true' do
315
+ expect(subject.nil?).to be_truthy
316
+ end
317
+
318
+ end
319
+
320
+ end
321
+
322
+ end