toy_robot 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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