toy-robot-simulator 0.0.2 → 0.0.3
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.
- checksums.yaml +4 -4
- data/README.md +10 -9
- data/lib/errors/command.rb +1 -0
- data/lib/errors/robot.rb +1 -0
- data/lib/errors/table.rb +1 -0
- data/lib/helpers/command_helper.rb +10 -1
- data/lib/helpers/command_parser_helper.rb +15 -1
- data/lib/helpers/command_set_loader.rb +23 -13
- data/lib/surface/table.rb +8 -1
- data/lib/surface/table_interface.rb +6 -1
- data/lib/toy_robot/robot.rb +37 -1
- data/lib/toy_robot_controller.rb +27 -13
- data/spec/command_set_loader_spec.rb +7 -7
- data/spec/spec_helper.rb +3 -0
- data/spec/toy_robot_controller_spec.rb +7 -24
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 45d7af2744c4d7fe285025d8a6777f1e55a81d3ec9bfc71c75a4492405642c4a
|
4
|
+
data.tar.gz: 427275d04889e285ed1869bcc97e60957ff0e8b57166b087bda91c720e135b64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 437ddd7ff5990ac97f339c46ec4a5d47b30d7f9b4c4d260d224be29298be147829e5603d607a8a9384c5422b52376eb200665e747638ff192461839212264378
|
7
|
+
data.tar.gz: b1bdd09d3e4b79e0c29a62306acd441fbf74eb4af88849e9b752305d7ab68c931ead274b9f6688802b279645484882971c63bb8c6c20a0be9d3511e2f8392c0a
|
data/README.md
CHANGED
@@ -4,13 +4,13 @@ _version: 0.0.1_
|
|
4
4
|
|
5
5
|
The Ruby gem let the toy robot move a table painlessly, easily, and most importantly, **it does not fall from the table**
|
6
6
|
|
7
|
-
- [Full gem documentation (version 0.0.
|
7
|
+
- [Full gem documentation (version 0.0.3)](https://www.rubydoc.info/gems/toy-robot-simulator/0.0.3/)
|
8
8
|
# Installation
|
9
9
|
```
|
10
10
|
gem install toy-robot-simulator
|
11
11
|
```
|
12
12
|
```ruby
|
13
|
-
gem "toy-robot-simulator", "~> 0.0.
|
13
|
+
gem "toy-robot-simulator", "~> 0.0.3"
|
14
14
|
```
|
15
15
|
```
|
16
16
|
bundle install
|
@@ -33,11 +33,7 @@ examples:
|
|
33
33
|
```ruby
|
34
34
|
ToyRobotController.init(['PLACE 0,0,NORTH', 'MOVE'])
|
35
35
|
```
|
36
|
-
**3.
|
37
|
-
```ruby
|
38
|
-
ToyRobotController.execute_commands
|
39
|
-
```
|
40
|
-
**4. Report**
|
36
|
+
**3. Report**
|
41
37
|
```ruby
|
42
38
|
ToyRobotController.report
|
43
39
|
```
|
@@ -47,7 +43,6 @@ ToyRobotController.report
|
|
47
43
|
|
48
44
|
```ruby
|
49
45
|
require 'helpers/command_set_loader'
|
50
|
-
include CommandSetLoader
|
51
46
|
```
|
52
47
|
```ruby
|
53
48
|
commands = CommandSetLoader.read_commands('./test_data/test1.txt')
|
@@ -57,7 +52,7 @@ commands = CommandSetLoader.read_commands('./test_data/test1.txt')
|
|
57
52
|
ToyRobotController.init(commands)
|
58
53
|
```
|
59
54
|
|
60
|
-
## Things to
|
55
|
+
## Things to consider
|
61
56
|
|
62
57
|
**init** method of ToyRobotController expects array of commands where all the commands should be type of **string**
|
63
58
|
|
@@ -68,6 +63,11 @@ MOVE
|
|
68
63
|
REPORT
|
69
64
|
```
|
70
65
|
|
66
|
+
## Change Log
|
67
|
+
- Updated documentation
|
68
|
+
- Added more readable comments in the code
|
69
|
+
- Updated the CommandSetLoader
|
70
|
+
|
71
71
|
## TODO
|
72
72
|
|
73
73
|
- Add configuration option
|
@@ -77,3 +77,4 @@ REPORT
|
|
77
77
|
- **CommandSetLoader** is reading file locally, would be a good idea to add the option to read the file remotely
|
78
78
|
- Add obstructions on the table
|
79
79
|
- Non square table
|
80
|
+
- Robot reports in multiple formats such as JSON, HTML, XML etc
|
data/lib/errors/command.rb
CHANGED
data/lib/errors/robot.rb
CHANGED
data/lib/errors/table.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative '../constants/application_constants'
|
4
|
-
|
4
|
+
|
5
|
+
# CommandHelper contains all the helper methods to valid integrity and type of a command
|
5
6
|
module CommandHelper
|
7
|
+
# it will validate the provided command against the PLACE_COMMAND_PATTERN set in the application_contants
|
8
|
+
# @retrun [Boolean]
|
6
9
|
def a_valid_place_command?(command)
|
7
10
|
return false if command.match(PLACE_COMMAND_PATTERN).nil?
|
8
11
|
|
@@ -14,16 +17,22 @@ module CommandHelper
|
|
14
17
|
result&.captures
|
15
18
|
end
|
16
19
|
|
20
|
+
# it will return type of command such as PLACE, MOVE, LEFT, RIGHT, REPORT
|
21
|
+
# @return [String]
|
17
22
|
def command_type(command)
|
18
23
|
return if command.nil?
|
19
24
|
return PLACE if command.include? PLACE
|
20
25
|
return command if COMMANDS.include? command
|
21
26
|
end
|
22
27
|
|
28
|
+
# return all directions array [NORTH EAST SOUTH WEST]
|
29
|
+
# @return [Array]
|
23
30
|
def directions
|
24
31
|
DIRECTIONS
|
25
32
|
end
|
26
33
|
|
34
|
+
# return all valid commands array [MOVE LEFT RIGHT REPORT PLACE]
|
35
|
+
# @return [Array]
|
27
36
|
def commands
|
28
37
|
COMMANDS
|
29
38
|
end
|
@@ -2,10 +2,21 @@
|
|
2
2
|
|
3
3
|
require_relative '../constants/application_constants'
|
4
4
|
require_relative 'command_helper'
|
5
|
-
|
5
|
+
|
6
|
+
# CommandParserHelper is just parsing the command and return a command Struct
|
6
7
|
module CommandParserHelper
|
7
8
|
include CommandHelper
|
8
9
|
|
10
|
+
# it the provided command is valid, it will return a Struct with
|
11
|
+
# with type, value, status, error attributes
|
12
|
+
#
|
13
|
+
# type represents the type of command such as PLACE, MOVE, REPORT, LEFT, RIGHT
|
14
|
+
#
|
15
|
+
# value represents the value it holds such value will be X,Y,F for PLACE command
|
16
|
+
#
|
17
|
+
# status and error attributes are set to empty in the start
|
18
|
+
# @param command [String]
|
19
|
+
# @return [Struct]
|
9
20
|
def parse_command(command)
|
10
21
|
type_of_command = command_type(command)
|
11
22
|
return if type_of_command.nil?
|
@@ -16,16 +27,19 @@ module CommandParserHelper
|
|
16
27
|
|
17
28
|
private
|
18
29
|
|
30
|
+
# returns the value of a comamnd
|
19
31
|
def command_value(command)
|
20
32
|
return split_place_command(command) if place_command_and_valid?(command)
|
21
33
|
|
22
34
|
command
|
23
35
|
end
|
24
36
|
|
37
|
+
# return command Struct
|
25
38
|
def command_object(type, value, status = '', error = '')
|
26
39
|
Struct.new(:type, :value, :status, :error).new(type, value, status, error)
|
27
40
|
end
|
28
41
|
|
42
|
+
# check if it is a PLACE command and valid also
|
29
43
|
def place_command_and_valid?(command)
|
30
44
|
command_type(command) == PLACE && a_valid_place_command?(command)
|
31
45
|
end
|
@@ -1,22 +1,32 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative '../errors/command'
|
4
|
-
# CommandSetLoader
|
4
|
+
# CommandSetLoader is there to read commands from file locally for now
|
5
5
|
module CommandSetLoader
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
class << self
|
7
|
+
# @todo Add support to load file remotely and support for different formats such as JSON
|
8
|
+
# @param location [String] location of the file containig commands
|
9
|
+
# @param source [String]
|
10
|
+
# @param format [String]
|
11
|
+
# @raise [Command::FormatNotSupported] if format is not set to text
|
12
|
+
# @raise [Command::SourceNotSupported] if source is not set to file
|
13
|
+
# @raise [Command::EmptyLocationProvided] location is empty
|
14
|
+
def read_commands(location = '', source = 'file', format = 'text')
|
15
|
+
raise Command::FormatNotSupported, 'Only text format is supported' unless format == 'text'
|
16
|
+
raise Command::SourceNotSupported, 'Only file as a source is supported' unless source == 'file'
|
17
|
+
raise Command::EmptyLocationProvided if location.strip == ''
|
10
18
|
|
11
|
-
|
12
|
-
|
13
|
-
|
19
|
+
@location = location
|
20
|
+
read_from_file
|
21
|
+
end
|
14
22
|
|
15
|
-
|
23
|
+
private
|
16
24
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
25
|
+
# reading commands from file and return Array of commands
|
26
|
+
def read_from_file
|
27
|
+
commands = []
|
28
|
+
File.readlines(@location).each { |line| commands << line.strip }
|
29
|
+
commands
|
30
|
+
end
|
21
31
|
end
|
22
32
|
end
|
data/lib/surface/table.rb
CHANGED
@@ -3,17 +3,24 @@
|
|
3
3
|
require_relative 'table_interface'
|
4
4
|
require_relative '../errors/table'
|
5
5
|
module Surface
|
6
|
-
# Table class
|
6
|
+
# Table class represents a square table of 5x5 by default
|
7
|
+
# @todo Add functionality to add Obsturctions on Table
|
7
8
|
class Table
|
8
9
|
include TableInterface
|
9
10
|
attr_accessor :rows, :columns, :grid
|
10
11
|
|
12
|
+
# @param rows [Integer]
|
13
|
+
# @param columns [Integer]
|
11
14
|
def initialize(rows = 5, columns = 5)
|
12
15
|
@grid = Array.new(rows) { Array.new(columns) { 0 } }
|
13
16
|
@rows = rows
|
14
17
|
@columns = columns
|
15
18
|
end
|
16
19
|
|
20
|
+
# validates if the x, y can be placed on to the table
|
21
|
+
# @param x [Integer]
|
22
|
+
# @param y [Integer]
|
23
|
+
# @return [Boolean]
|
17
24
|
def can_be_placed?(x, y)
|
18
25
|
return false unless (0..(rows - 1)).include?(x)
|
19
26
|
return false unless (0..(columns - 1)).include?(y)
|
@@ -1,6 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# module
|
3
|
+
# Surface module is trying to set the rules interfaces type of surfaces such as TableInterface.
|
4
|
+
#
|
5
|
+
# in a nutshell a Table should include the *Surface:TableInterface* and override the can_be_placed? method
|
6
|
+
#
|
7
|
+
# if we want to add any other surface such as Benchtop, it will be a good
|
8
|
+
# practice to create a BenchtopInterface module with the method(s) represents it rules
|
4
9
|
module Surface
|
5
10
|
# TableInterface to valid can_be_placed?(_x, _y) implemented by Table
|
6
11
|
module TableInterface
|
data/lib/toy_robot/robot.rb
CHANGED
@@ -3,10 +3,12 @@
|
|
3
3
|
require_relative '../errors/command'
|
4
4
|
require_relative '../errors/robot'
|
5
5
|
module ToyRobot
|
6
|
-
# Robot class
|
6
|
+
# Robot class represents our ToyRobot which be moving on to the table
|
7
7
|
class Robot
|
8
8
|
attr_accessor :x, :y, :facing, :placed, :table
|
9
9
|
|
10
|
+
# this method will set the instance methods such as table, placed, x, y and facing of robot
|
11
|
+
# @param table [Surface::Table]
|
10
12
|
def initialize(table = nil)
|
11
13
|
@placed = false
|
12
14
|
@table = table
|
@@ -15,6 +17,17 @@ module ToyRobot
|
|
15
17
|
@facing = nil
|
16
18
|
end
|
17
19
|
|
20
|
+
# This method will place the robot on the table as per provided coordinates
|
21
|
+
# and direction it should be facing
|
22
|
+
# @param x [Integer]
|
23
|
+
# @param y [Integer]
|
24
|
+
# @param facing [String]
|
25
|
+
# @raise [Surface::TableIsNotSet] if the table is not set
|
26
|
+
#
|
27
|
+
# @raise [Surface::TableOutOfBound] if x or y will make the robot fall from the table
|
28
|
+
#
|
29
|
+
# @raise [Surface::InvalidFacing] if the facing value is other than [NORTH SOUTH EAST WEST]
|
30
|
+
#
|
18
31
|
def place(x, y, facing)
|
19
32
|
return if @placed
|
20
33
|
raise Surface::TableIsNotSet if @table.nil?
|
@@ -27,16 +40,31 @@ module ToyRobot
|
|
27
40
|
@placed = true
|
28
41
|
end
|
29
42
|
|
43
|
+
# move the robot 90 degress counter clock wise
|
44
|
+
#
|
45
|
+
# example: if the robot was facing NORTH, it will be facing WEST after this method call
|
46
|
+
# @raise [Surface::TableIsNotSet] if the table is not set
|
47
|
+
# @raise [ToyRobot::RobotIsNotPlaced] if the robot is not placed
|
30
48
|
def left
|
31
49
|
check_pre_conditions
|
32
50
|
@facing = next_facing('left')
|
33
51
|
end
|
34
52
|
|
53
|
+
# move the robot 90 degress clock wise
|
54
|
+
#
|
55
|
+
# example: if the robot was facing EAST, it will be facing SOUTH after this method call
|
56
|
+
# @raise [Surface::TableIsNotSet] if the table is not set
|
57
|
+
# @raise [ToyRobot::RobotIsNotPlaced] if the robot is not placed
|
35
58
|
def right
|
36
59
|
check_pre_conditions
|
37
60
|
@facing = next_facing('right')
|
38
61
|
end
|
39
62
|
|
63
|
+
# move the robot in the direct it is facing if possible
|
64
|
+
#
|
65
|
+
# @raise [Surface::TableOutOfBound] if the potential x or y will make the robot fall from the table
|
66
|
+
# @raise [Surface::TableIsNotSet] if the table is not set
|
67
|
+
# @raise [ToyRobot::RobotIsNotPlaced] if the robot is not placed
|
40
68
|
def move
|
41
69
|
check_pre_conditions
|
42
70
|
result = calculate_potential_movement(facing)
|
@@ -50,6 +78,9 @@ module ToyRobot
|
|
50
78
|
@y = y_should_be
|
51
79
|
end
|
52
80
|
|
81
|
+
# @todo Add suppor for other formats such as JSON, XML, HTML etc
|
82
|
+
# @param format [String] default value is console
|
83
|
+
# @raise [ToyRobot::RobotIsNotPlaced] if the robot is not placed on to the table
|
53
84
|
def report(format = 'console')
|
54
85
|
raise ToyRobot::RobotIsNotPlaced unless @placed
|
55
86
|
|
@@ -61,6 +92,9 @@ module ToyRobot
|
|
61
92
|
end
|
62
93
|
end
|
63
94
|
|
95
|
+
# based on provided facing direction, which x or y coordinates should mutate
|
96
|
+
#
|
97
|
+
# *this method does not validate if the robot will fall from the table*
|
64
98
|
def calculate_potential_movement(facing)
|
65
99
|
case facing
|
66
100
|
when 'NORTH'
|
@@ -80,6 +114,8 @@ module ToyRobot
|
|
80
114
|
"#{@x},#{@y},#{@facing}"
|
81
115
|
end
|
82
116
|
|
117
|
+
# based on provided arrow value left/right
|
118
|
+
# it determines the next direction of robot facing
|
83
119
|
def next_facing(arrow)
|
84
120
|
return DIRECTIONS.last if @facing == DIRECTIONS.first && arrow == 'left'
|
85
121
|
return DIRECTIONS.first if @facing == DIRECTIONS.last && arrow == 'right'
|
data/lib/toy_robot_controller.rb
CHANGED
@@ -8,12 +8,21 @@ require_relative 'errors/command'
|
|
8
8
|
# ToyRobotController module which sets up the Robot, Table and execute commands provided
|
9
9
|
module ToyRobotController
|
10
10
|
class << self
|
11
|
-
attr_accessor :robot, :commands
|
12
11
|
include CommandParserHelper
|
13
12
|
|
14
13
|
# This method is expecting [Array<String>] of commands such as ['PLACE 0,0,NORTH', 'MOVE', 'REPORT']
|
15
14
|
# @param commands_stream [Array<String>]
|
16
15
|
# @param table_size [Integer]
|
16
|
+
#
|
17
|
+
# @raise [Command::InvalidCommandStreamType] if the commands_stream is not of type Array
|
18
|
+
#
|
19
|
+
# @raise [Command::InvalidOrEmptyCommands] if the commands_stream array length is 0
|
20
|
+
#
|
21
|
+
# @raise [Command::InvalidCommandType] if the any of commands_stream element is not type String
|
22
|
+
#
|
23
|
+
# @raise [Command::NoValidCommandsFound] if the commands_stream array length is 0 or contains all invalid commands
|
24
|
+
#
|
25
|
+
# @raise [Command::PlaceCommandNotFound] if the commands_stream array does not contain a valid PLACE command
|
17
26
|
def init(commands_stream, table_size = 5)
|
18
27
|
validate_command_stream(commands_stream)
|
19
28
|
|
@@ -22,20 +31,22 @@ module ToyRobotController
|
|
22
31
|
@robot = ToyRobot::Robot.new(@table)
|
23
32
|
@commands = []
|
24
33
|
populate_commands
|
34
|
+
execute_commands
|
25
35
|
end
|
26
36
|
|
27
|
-
#
|
28
|
-
|
29
|
-
|
30
|
-
end
|
37
|
+
# return [ToyRobot::Robot] if present
|
38
|
+
# @return [ToyRobot::Robot]
|
39
|
+
attr_reader :robot
|
31
40
|
|
32
|
-
#
|
33
|
-
#
|
34
|
-
# considerations:
|
41
|
+
# return Array of commands if present
|
35
42
|
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
|
43
|
+
# example: <struct type="PLACE", value=["0", "0", "NORTH"], status="", error="">
|
44
|
+
# @return [Array<Struct>]
|
45
|
+
attr_reader :commands
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# validate the populated commands and send each to the send_command_to_robot method
|
39
50
|
def execute_commands
|
40
51
|
raise Command::NoValidCommandsFound if @commands.size.zero?
|
41
52
|
raise Command::PlaceCommandNotFound if @commands.select { |c| c.type == 'PLACE' }.size.zero?
|
@@ -43,8 +54,9 @@ module ToyRobotController
|
|
43
54
|
@commands.each { |command| send_command_to_robot(command) }
|
44
55
|
end
|
45
56
|
|
46
|
-
|
47
|
-
|
57
|
+
# based on command type, it call the appropriate method of Robot
|
58
|
+
# if the command can not be executed by the Robot, it will update the status and error attributes
|
59
|
+
# of command struct
|
48
60
|
def send_command_to_robot(command)
|
49
61
|
case command.type
|
50
62
|
when 'PLACE'
|
@@ -57,12 +69,14 @@ module ToyRobotController
|
|
57
69
|
command.error = e.to_s
|
58
70
|
end
|
59
71
|
|
72
|
+
# checks the integrity of commands_stream Array
|
60
73
|
def validate_command_stream(commands_stream)
|
61
74
|
raise Command::InvalidCommandStreamType unless commands_stream.is_a?(Array)
|
62
75
|
raise Command::InvalidOrEmptyCommands if commands_stream.size.zero?
|
63
76
|
raise Command::InvalidCommandType unless commands_stream.all? { |i| i.is_a? String }
|
64
77
|
end
|
65
78
|
|
79
|
+
# filling the commands array with all the valid commands by parse_command method
|
66
80
|
def populate_commands
|
67
81
|
@commands_stream.each do |command|
|
68
82
|
current_command = parse_command(command)
|
@@ -1,33 +1,33 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
describe CommandSetLoader do
|
4
|
-
|
4
|
+
let(:loader) { described_class }
|
5
5
|
|
6
|
-
describe '
|
6
|
+
describe '.read_commands' do
|
7
7
|
it 'will load the commands from test1.txt file and return array of commands' do
|
8
|
-
commands = read_commands('./test_data/test1.txt')
|
8
|
+
commands = loader.read_commands('./test_data/test1.txt')
|
9
9
|
expect(commands).to match_array(['PLACE 0,0,NORTH', 'MOVE', 'REPORT'])
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'will load the commands from test2.txt file and return array of commands' do
|
13
|
-
commands = read_commands('./test_data/test2.txt')
|
13
|
+
commands = loader.read_commands('./test_data/test2.txt')
|
14
14
|
expect(commands).to match_array(['PLACE 0,0,NORTH', 'LEFT', 'REPORT'])
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'will load the commands from test3.txt file and return array of commands' do
|
18
|
-
commands = read_commands('./test_data/test3.txt')
|
18
|
+
commands = loader.read_commands('./test_data/test3.txt')
|
19
19
|
expect(commands).to match_array(['PLACE 1,2,EAST', 'MOVE', 'MOVE', 'LEFT', 'MOVE', 'REPORT'])
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'will return SourceNotSupported exception if source is not file' do
|
23
23
|
expect do
|
24
|
-
read_commands('./test_data/test3.txt', 'remote')
|
24
|
+
loader.read_commands('./test_data/test3.txt', 'remote')
|
25
25
|
end.to raise_error(Command::SourceNotSupported)
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'will return FormatNotSupported exception if source is not text' do
|
29
29
|
expect do
|
30
|
-
read_commands('./test_data/test3.txt', 'file', 'json')
|
30
|
+
loader.read_commands('./test_data/test3.txt', 'file', 'json')
|
31
31
|
end.to raise_error(Command::FormatNotSupported)
|
32
32
|
end
|
33
33
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -22,6 +22,9 @@ require_relative '../lib/helpers/command_helper'
|
|
22
22
|
require_relative '../lib/helpers/command_parser_helper'
|
23
23
|
require_relative '../lib/helpers/command_set_loader'
|
24
24
|
require 'byebug'
|
25
|
+
require 'simplecov'
|
26
|
+
SimpleCov.start
|
27
|
+
|
25
28
|
# require 'byebug'
|
26
29
|
RSpec.configure do |config|
|
27
30
|
# rspec-expectations config goes here. You can use an alternate
|
@@ -33,31 +33,24 @@ describe ToyRobotController do
|
|
33
33
|
expect { controller.init(comamnds_stream) }.to raise_error(Command::InvalidCommandType)
|
34
34
|
end
|
35
35
|
end
|
36
|
-
end
|
37
|
-
|
38
|
-
describe '.execute_commands' do
|
39
36
|
context 'when all commands are invalid' do
|
40
37
|
it 'will raise NoValidCommandsFound exception' do
|
41
38
|
comamnds_stream = ['RANDOM Command', 'adfadfadf', 'adfrtrett']
|
42
|
-
controller.init(comamnds_stream)
|
43
|
-
expect { controller.execute_commands }.to raise_error(Command::NoValidCommandsFound)
|
39
|
+
expect { controller.init(comamnds_stream) }.to raise_error(Command::NoValidCommandsFound)
|
44
40
|
end
|
45
41
|
end
|
46
42
|
|
47
43
|
it 'will ignore all commands before PLACE' do
|
48
44
|
controller.init(['MOVE', 'REPORT', 'PLACE 1,1,NORTH', 'MOVE', 'REPORT'])
|
49
|
-
controller.execute_commands
|
50
45
|
expect(controller.commands.select { |c| c.status == 'ignored' }.size).to eq(2)
|
51
46
|
end
|
52
47
|
|
53
48
|
context 'when PLACE command is not provided' do
|
54
49
|
it 'will raise PlaceCommandNotFound exception' do
|
55
|
-
controller.init(%w[MOVE MOVE LEFT MOVE REPORT])
|
56
|
-
expect { controller.execute_commands }.to raise_error(Command::PlaceCommandNotFound)
|
50
|
+
expect { controller.init(%w[MOVE MOVE LEFT MOVE REPORT]) }.to raise_error(Command::PlaceCommandNotFound)
|
57
51
|
end
|
58
52
|
it 'will raise PlaceCommandNotFound exception with a PLACE command without X,Y,Facing' do
|
59
|
-
controller.init(%w[PLACE MOVE MOVE LEFT MOVE REPORT])
|
60
|
-
expect { controller.execute_commands }.to raise_error(Command::PlaceCommandNotFound)
|
53
|
+
expect { controller.init(%w[PLACE MOVE MOVE LEFT MOVE REPORT]) }.to raise_error(Command::PlaceCommandNotFound)
|
61
54
|
end
|
62
55
|
end
|
63
56
|
end
|
@@ -66,37 +59,27 @@ describe ToyRobotController do
|
|
66
59
|
context 'when command sequence is PLACE 0,0,NORTH MOVE REPORT ' do
|
67
60
|
it 'will move the robot to 0,1,NORTH' do
|
68
61
|
controller.init(['PLACE 0,0,NORTH', 'MOVE', 'REPORT'])
|
69
|
-
controller.
|
70
|
-
expect(controller.report).to eq('0,1,NORTH')
|
62
|
+
expect(controller.robot.report).to eq('0,1,NORTH')
|
71
63
|
end
|
72
64
|
end
|
73
65
|
|
74
66
|
context 'when command sequence is PLACE 1,2,EAST MOVE MOVE LEFT MOVE REPORT' do
|
75
67
|
it 'will move the robot to 3,3,NORTH' do
|
76
68
|
controller.init(['PLACE 1,2,EAST', 'MOVE', 'MOVE', 'LEFT', 'MOVE', 'REPORT'])
|
77
|
-
controller.
|
78
|
-
expect(controller.report).to eq('3,3,NORTH')
|
69
|
+
expect(controller.robot.report).to eq('3,3,NORTH')
|
79
70
|
end
|
80
71
|
end
|
81
72
|
context 'when command sequence is PLACE 1,2,WEST MOVE MOVE LEFT MOVE REPORT' do
|
82
73
|
it 'will move the robot to 0,1,SOUTH' do
|
83
74
|
controller.init(['PLACE 1,2,WEST', 'MOVE', 'MOVE', 'LEFT', 'MOVE', 'REPORT'])
|
84
|
-
controller.
|
85
|
-
expect(controller.report).to eq('0,1,SOUTH')
|
75
|
+
expect(controller.robot.report).to eq('0,1,SOUTH')
|
86
76
|
end
|
87
77
|
end
|
88
78
|
|
89
79
|
context 'when command sequence contains only PLACE command' do
|
90
80
|
it 'will report where the robot was PLACED' do
|
91
81
|
controller.init(['PLACE 0,0,SOUTH'])
|
92
|
-
controller.
|
93
|
-
expect(controller.report).to eq('0,0,SOUTH')
|
94
|
-
end
|
95
|
-
end
|
96
|
-
context 'when PLACE command is not provided' do
|
97
|
-
it 'will raise RobotIsNotPlaced exception' do
|
98
|
-
controller.init(%w[MOVE MOVE LEFT MOVE REPORT])
|
99
|
-
expect { controller.report }.to raise_error(ToyRobot::RobotIsNotPlaced)
|
82
|
+
expect(controller.robot.report).to eq('0,0,SOUTH')
|
100
83
|
end
|
101
84
|
end
|
102
85
|
end
|