another_toy_robot 0.1.8 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ef892b383c68270bf0742d262d9a40ea5047f597
4
- data.tar.gz: b97bbf3224f6acbf2077e42cf6c229f5519f1292
3
+ metadata.gz: 43ea9ed6146a026f2e64bf8fb0c9190950f8ae76
4
+ data.tar.gz: ea3faa443089ea8a429f6f8305b5c3fcb7a99873
5
5
  SHA512:
6
- metadata.gz: f9a12c53ddb64381fff8f995bb2e99373e7ad3a7a7c17349f04a9301e2190019aa64640db423fd662be24b009bab55010920f46505e2b2daa10a7c06e87c5a6e
7
- data.tar.gz: 7d7b71e62de2720cfd32229e6d6110b0a46704be84628f713449ffd07c95bb4b0cd697dc5d91234726bd663440af411a6f13313b38d4dbbe6339ef93205f9b07
6
+ metadata.gz: 556f6c6f940b2079d8be8c87d7ac853541d1ed2aadc097f3a5ef665f2950289e4b64891ffe0f477110571edafa1998dfd4e8dbba53db875766a042566c6e6b1b
7
+ data.tar.gz: f1a887cfa16bdd63a2bd36429f43904db8bb0829e255b11a2296fbb357d231d06c6a9c0f4824b828d0c652670af2ff49334830597088a22a5b881074a3200279
data/Gemfile CHANGED
@@ -1,14 +1,4 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem "pry"
4
- gem "rspec"
5
- gem "rake"
6
- gem "factory_girl", "~> 4.0"
7
-
8
- group :test do
9
- gem "simplecov", require: false
10
- gem "codeclimate-test-reporter", "~> 1.0.0"
11
- end
12
-
13
3
  # Specify your gem's dependencies in toy_robot.gemspec
14
4
  gemspec
data/README.md CHANGED
@@ -4,21 +4,42 @@
4
4
  [![Build Status](https://travis-ci.org/drzel/toy_robot.svg?branch=master)](https://travis-ci.org/drzel/toy_robot)
5
5
 
6
6
  # Another Toy Robot Simulator
7
- The application is a simulation of a toy robot moving on a 5 x 5 unit tabletop. It
8
- is an example of a well tested, object oriented design, employing the command design
9
- pattern.
7
+ The application is a simulation of a toy robot moving on a 5 x 5 unit tabletop. It is an example of a well tested, object oriented design, employing the command design pattern. It is commonly used as an code-test. See specifications below for the full text of the test.
10
8
 
11
- ### Dependencies
12
- Requires Ruby 2.3 or later.
9
+ ### Environment
10
+ This application was developed on Ubuntu 16.10 x86_64. It requires Ruby 2.3 or later.
11
+
12
+ To check your version run:
13
+ ```
14
+ $ ruby -v
15
+ ```
16
+
17
+ Information on installing Ruby can be found at [Installing Ruby](https://www.ruby-lang.org/en/documentation/installation/).
13
18
 
14
19
  ### Installation
20
+ The latest release can be installed via RubyGems:
21
+ ```
22
+ $ gem install another_toy_robot
23
+ ```
24
+
25
+ Alternatively it can be built from source:
26
+ ```
27
+ $ git clone https://github.com/drzel/toy_robot.git
28
+ $ cd toy_robot
29
+ $ bundle install
30
+ ```
31
+
32
+ ### Testing
33
+ The test suite is invoked with:
15
34
  ```
16
- gem install another_toy_robot
35
+ $ bundle exec rspec
17
36
  ```
18
37
 
38
+ Unit tests are written to [Sandi Metz' Unit Testing Minimalist](https://youtu.be/URSWYvyc42M) guidelines.
39
+
19
40
  ### Usage
20
41
  ```
21
- toy_robot
42
+ $ toy_robot
22
43
  ```
23
44
 
24
45
  This will present a prompt:
@@ -29,7 +50,7 @@ Input command:
29
50
  Valid commands are:
30
51
 
31
52
  | Command | Description
32
- | ------------- | ---
53
+ | --- | ---
33
54
  | `place x,y,d` | Places robot at position `x`, `y`, facing cardinal direction `d`. E.g. `place 1,2,north`.
34
55
  | `left` | Rotates robot 90° counter-clockwise.
35
56
  | `right` | Rotates robot 90° clockwise.
@@ -39,16 +60,80 @@ Valid commands are:
39
60
 
40
61
  Commands resulting in the robot moving to an out-of-bounds position (`x` or `y` being less than 0 or greater than 4) will be ignored.
41
62
 
63
+ ### Design
64
+ The app implements:
65
+ - The [command pattern](https://en.wikipedia.org/wiki/Command_pattern)
66
+ - The [null-object pattern](https://en.wikipedia.org/wiki/Null_Object_pattern) (for positions)
67
+ - The [singleton pattern](https://en.wikipedia.org/wiki/Singleton_pattern) (for directions)
68
+
69
+ `toy_robot` is an executable in your load path. It is a Ruby script that calls the main function:
70
+ ```
71
+ #!/usr/bin/env ruby
72
+
73
+ require "toy_robot"
74
+ ToyRobot.main
75
+ ```
76
+
77
+ `ToyRobot#main` instantiates a new `Client`. The `Client` instantiates an `Arena` and `Robot` objects. The new `Robot` is initialised with `NullPosition` in the `Arena`.
78
+
79
+ - The main loop does the following:
80
+ - Requests user input
81
+ - Instantiates a new `Input` object
82
+ - Passes the new `Input` object to the client
83
+
84
+ The `Input` class contains methods to parse the user input and determine the correct `Command` class for the given command. E.g. `"move"` will resolve a the `MoveCommand` while `"derp"` will resolve `InvalidCommand`.
85
+
86
+ The client calls the `Input#new_command` method, passing the `@robot` as the target.
87
+
88
+ The `xCommand` object will parse any arguments provided and call the appropriate action on the `@robot`.
89
+
90
+ When receiving a `place` method the robot will check with its `@arena` to see if the position is `#inbounds` before assigning the new `Position` to itself.
91
+
92
+ When receiving `#left`, `#right` or `#move`, the robot will pass the request to its `@position` which will respond with the new position.
93
+
94
+ The `Robot` will then check with its `@arena` to see if the position is `#inbounds` before assigning the new position to itself.
95
+
96
+ When receiving a `#left`, `#right` or `#move` message the `NullPosition` will return itself.
97
+
98
+ When the `Robot` receives `#report` it prints its `@position` as a string.
99
+
100
+ This process continues until an `"exit"` command is received, breaking the loop.
101
+
102
+ ### Considerations
103
+ Given the requirement for a command line interface to interact with the robot, I settled on the well established and widely used command pattern.
104
+
105
+ The `Input` wrapper allows new commands to be easily added. E.g. Creating a new file `lib/toy_robot/random_command.rb` and requiring it, would be all that is required for the application to accept the `"random"` command, and it would have access to an array of parameters. Validations can also be added by defining a `valid?` method on the command object. See the `lib/toy_robot/place_command.rb` for an example.
106
+
107
+ I'm particularly happy with the `Position` class and the `Direction` modules. Together as a unit they have absolutely no dependencies and could be easily reused with new features, new objects, or with changing specifications. It would be reasonably straight forward to add a second robot, or a third dimension.
108
+
109
+ Currently the `Robot` must be instantiated with an `Arena`. Originally, I had also employed the null object pattern for the `Arena` as well as the position, but as it turned out, with the current specification, there is no situation where a robot is not in an arena, so it was unneeded and removed, reducing overall complexity of the application.
110
+
111
+ As GINnFIN helpfully pointed out in the [Reddit discussion](https://www.reddit.com/r/ruby/comments/5fptz9/i_did_the_toy_robot_challenge_ive_tried_to_be/), the `Position` `#left` and `#right` methods do necessarily need to return a new instance of `Position`, and could instead mutate the current position in place. While this is true, there is a pleasing symmetry in each of the current `Position` methods returning a new instance of position that would would be lost if these were to be changed. I'm not entirely sure which is better, but have decided to keep the current implementation, as different behaviour for the `place` and `move` methods to the `left` and `right` methods may be unnecessarily increasing the conceptual complexity of the app.
112
+
113
+ ### Licence
114
+ [MIT](https://tldrlegal.com/license/mit-license)
115
+
116
+ ### Contributing
117
+ My goal is to continue to develop this application to use as an example for other developers who are learning Ruby and object oriented design and have attempted to ensure it is SOLID, DRY, OO and TDD.
118
+
119
+ If you have something to contribute, whether it be to report an bug, suggest a potential improvement or even ask a question, don't hesitate to log an issue.
120
+
121
+ Pull requests are also warmly welcomed.
122
+
123
+ ### Links
124
+ - [another_toy_robot on RubyGems](https://rubygems.org/gems/another_toy_robot)
125
+ - [Discussion on Reddit](https://www.reddit.com/r/ruby/comments/5fptz9/i_did_the_toy_robot_challenge_ive_tried_to_be/?ref=share&ref_source=link)
126
+
42
127
  ## Specification
43
128
 
44
129
  ### Description
45
130
  - The application is a simulation of a toy robot moving on a square tabletop,
46
- of dimensions 5 units x 5 units.
131
+ of dimensions 5 units x 5 units.
47
132
  - There are no other obstructions on the table surface.
48
133
  - The robot is free to roam around the surface of the table, but must be
49
- prevented from falling to destruction. Any movement that would result in the
50
- robot falling from the table must be prevented, however further valid
51
- movement commands must still be allowed.
134
+ prevented from falling to destruction. Any movement that would result in the
135
+ robot falling from the table must be prevented, however further valid
136
+ movement commands must still be allowed.
52
137
  - Create an application that can read in commands of the following form:
53
138
 
54
139
  ```
@@ -60,20 +145,20 @@ REPORT
60
145
  ```
61
146
 
62
147
  - PLACE will put the toy robot on the table in position X,Y and facing NORTH,
63
- SOUTH, EAST or WEST.
148
+ SOUTH, EAST or WEST.
64
149
  - The origin (0,0) can be considered to be the SOUTH WEST most corner.
65
150
  - The first valid command to the robot is a PLACE command, after that, any
66
- sequence of commands may be issued, in any order, including another PLACE
67
- command. The application should discard all commands in the sequence until a
68
- valid PLACE command has been executed.
151
+ sequence of commands may be issued, in any order, including another PLACE
152
+ command. The application should discard all commands in the sequence until a
153
+ valid PLACE command has been executed.
69
154
  - MOVE will move the toy robot one unit forward in the direction it is currently
70
- facing.
155
+ facing.
71
156
  - LEFT and RIGHT will rotate the robot 90 degrees in the specified direction
72
- without changing the position of the robot.
157
+ without changing the position of the robot.
73
158
  - REPORT will announce the X,Y and F of the robot. This can be in any form, but
74
- standard output is sufficient.
159
+ standard output is sufficient.
75
160
  - A robot that is not on the table can choose the ignore the MOVE, LEFT, RIGHT
76
- and REPORT commands.
161
+ and REPORT commands.
77
162
  - Input can be from a file, or from standard input, as the developer chooses.
78
163
  - Provide test data to exercise the application.
79
164
 
@@ -118,5 +203,6 @@ toy robot.
118
203
 
119
204
  ## Acknowledgements
120
205
  - [RafaelChefe's Toy Robot Simulator](https://github.com/RafaelChefe/toy_robot)
121
- - [Wikipedia Command pattern article](https://en.wikipedia.org/wiki/Command_pattern)
122
- - [Sandi Metz](https://www.sandimetz.com/) :heart:
206
+ - [Sandi Metz' Unit Testing Minimalist](https://youtu.be/URSWYvyc42M)
207
+ - [Daniel Steele](https://uk.linkedin.com/in/developerdansteele) and [Omnidev](https://omnidev.co.uk/)
208
+
data/lib/toy_robot.rb CHANGED
@@ -1,11 +1,5 @@
1
- require "pry"
2
1
  require "toy_robot/client"
3
- require "toy_robot/robot"
4
- require "toy_robot/arena"
5
- require "toy_robot/command"
6
- require "toy_robot/direction"
7
- require "toy_robot/position"
8
- require "toy_robot/null_position"
2
+ require "toy_robot/input"
9
3
 
10
4
  module ToyRobot
11
5
  def self.main
@@ -13,13 +7,9 @@ module ToyRobot
13
7
 
14
8
  loop do
15
9
  print "Input command: "
16
- input = get_input
17
- break if input == "exit"
18
- client.parse input
10
+ input = gets
11
+ break if input =~ /^\s*exit\s+/
12
+ client.command_for Input.new(input)
19
13
  end
20
14
  end
21
-
22
- def self.get_input
23
- gets.downcase.strip
24
- end
25
15
  end
@@ -1,20 +1,10 @@
1
1
  class Arena
2
- def initialize(width:, height:)
3
- @width = width
4
- @height = height
2
+ def initialize(width: 5, height: 5)
3
+ @columns = 0...width
4
+ @rows = 0...height
5
5
  end
6
6
 
7
7
  def inbounds?(x_coord, y_coord)
8
- x_coord&.between?(0, max_x) && y_coord&.between?(0, max_y)
9
- end
10
-
11
- private
12
-
13
- def max_x
14
- @width - 1
15
- end
16
-
17
- def max_y
18
- @height - 1
8
+ @columns.cover?(x_coord) && @rows.cover?(y_coord)
19
9
  end
20
10
  end
@@ -1,24 +1,13 @@
1
+ require "toy_robot/arena"
2
+ require "toy_robot/robot"
3
+
1
4
  class Client
2
5
  def initialize
3
6
  @table = Arena.new width: 5, height: 5
4
7
  @robot = Robot.new arena: @table
5
8
  end
6
9
 
7
- def parse(input)
8
- command = case input
9
- when /place\s+(\d+,\s*){2}([nesw]|(north)|(east)|(south)|(west))$/
10
- PlaceCommand.new robot: @robot, command: input
11
- when "move"
12
- MoveCommand.new robot: @robot
13
- when "left"
14
- LeftCommand.new robot: @robot
15
- when "right"
16
- RightCommand.new robot: @robot
17
- when "report"
18
- ReportCommand.new robot: @robot
19
- else
20
- InvalidCommand.new
21
- end
22
- command.execute
10
+ def command_for(input)
11
+ input.new_command(@robot).execute
23
12
  end
24
13
  end
@@ -1,77 +1,21 @@
1
- class PlaceCommand
2
- def initialize(robot:, command:)
3
- @robot = robot
4
- @params = command[/\s.*/].delete(" ").split(",")
5
- end
6
-
7
- def execute
8
- @robot.place Position.new(x_coord: x_coord,
9
- y_coord: y_coord,
10
- direction: direction)
11
- end
12
-
13
- private
14
-
15
- def x_coord
16
- @params[0].to_i
17
- end
18
-
19
- def y_coord
20
- @params[1].to_i
21
- end
22
-
23
- def direction
24
- case @params[2]
25
- when "n", "north" then North
26
- when "e", "east" then East
27
- when "s", "south" then South
28
- when "w", "west" then West
29
- end
30
- end
31
- end
32
-
33
- class MoveCommand
34
- def initialize(robot:)
35
- @robot = robot
36
- end
37
-
38
- def execute
39
- @robot.move
40
- end
41
- end
1
+ class Command
2
+ attr_accessor :target, :params
42
3
 
43
- class LeftCommand
44
- def initialize(robot:)
45
- @robot = robot
46
- end
4
+ def initialize(target: nil, params: nil)
5
+ @target = target
6
+ @params = params
47
7
 
48
- def execute
49
- @robot.left
8
+ post_initialize
50
9
  end
51
- end
52
10
 
53
- class RightCommand
54
- def initialize(robot:)
55
- @robot = robot
56
- end
11
+ def post_initialize; end
57
12
 
58
13
  def execute
59
- @robot.right
14
+ return InvalidCommand.new.execute unless valid?
15
+ issue_command
60
16
  end
61
- end
62
17
 
63
- class ReportCommand
64
- def initialize(robot:)
65
- @robot = robot
66
- end
67
-
68
- def execute
69
- @robot.report
70
- end
71
- end
72
-
73
- class InvalidCommand
74
- def execute
75
- puts "Invalid command"
18
+ def valid?
19
+ true
76
20
  end
77
21
  end
@@ -0,0 +1,38 @@
1
+ require "toy_robot/move_command"
2
+ require "toy_robot/left_command"
3
+ require "toy_robot/right_command"
4
+ require "toy_robot/place_command"
5
+ require "toy_robot/report_command"
6
+ require "toy_robot/invalid_command"
7
+
8
+ class Input
9
+ def initialize(input)
10
+ @input = input.strip.downcase
11
+ end
12
+
13
+ def new_command(target)
14
+ to_class.new target: target, params: params
15
+ end
16
+
17
+ private
18
+
19
+ def basename
20
+ @basename ||= @input.split(" ").first
21
+ end
22
+
23
+ def params
24
+ @params ||= @input.split(" ").drop 1
25
+ end
26
+
27
+ def classname
28
+ @classname ||= "#{basename.capitalize}Command"
29
+ end
30
+
31
+ def to_class
32
+ if Object.const_defined? classname
33
+ Object.const_get classname
34
+ else
35
+ InvalidCommand
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,7 @@
1
+ require "toy_robot/command"
2
+
3
+ class InvalidCommand < Command
4
+ def execute
5
+ puts "Invalid command"
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require "toy_robot/command"
2
+
3
+ class LeftCommand < Command
4
+ def issue_command
5
+ @target.left
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require "toy_robot/command"
2
+
3
+ class MoveCommand < Command
4
+ def issue_command
5
+ @target.move
6
+ end
7
+ end
@@ -1,11 +1,14 @@
1
1
  class NullPosition
2
- attr_reader :x_coord, :y_coord, :direction, :to_s
2
+ attr_reader :x_coord, :y_coord, :direction
3
3
 
4
4
  def initialize
5
5
  @x_coord = nil
6
6
  @y_coord = nil
7
7
  @direction = nil
8
- @to_s = "No position"
8
+ end
9
+
10
+ def to_s
11
+ "No position"
9
12
  end
10
13
 
11
14
  def advance
@@ -0,0 +1,40 @@
1
+ require "toy_robot/command"
2
+
3
+ class PlaceCommand < Command
4
+ def post_initialize
5
+ @params &&= @params.join.delete(" ").split ","
6
+ end
7
+
8
+ def issue_command
9
+ @target.place Position.new(x_coord: x_coord,
10
+ y_coord: y_coord,
11
+ direction: direction)
12
+ end
13
+
14
+ private
15
+
16
+ def valid?
17
+ @params &&
18
+ @params.length == 3 &&
19
+ @params[0] =~ /^\d+$/ &&
20
+ @params[1] =~ /^\d+$/ &&
21
+ @params[2] =~ /^([nesw]|(north)|(east)|(south)|(west))$/
22
+ end
23
+
24
+ def x_coord
25
+ @params[0].to_i
26
+ end
27
+
28
+ def y_coord
29
+ @params[1].to_i
30
+ end
31
+
32
+ def direction
33
+ case @params[2]
34
+ when "n", "north" then North
35
+ when "e", "east" then East
36
+ when "s", "south" then South
37
+ when "w", "west" then West
38
+ end
39
+ end
40
+ end
@@ -1,3 +1,5 @@
1
+ require "toy_robot/direction"
2
+
1
3
  class Position
2
4
  attr_reader :x_coord, :y_coord, :direction
3
5
 
@@ -8,24 +10,25 @@ class Position
8
10
  end
9
11
 
10
12
  def advance
11
- Position.new(x_coord: @x_coord + @direction::X_DISPLACEMENT,
12
- y_coord: @y_coord + @direction::Y_DISPLACEMENT,
13
- direction: @direction)
13
+ new_position(x_coord: @x_coord + @direction::X_DISPLACEMENT,
14
+ y_coord: @y_coord + @direction::Y_DISPLACEMENT)
14
15
  end
15
16
 
16
17
  def left
17
- Position.new(x_coord: @x_coord,
18
- y_coord: @y_coord,
19
- direction: @direction.left)
18
+ new_position direction: @direction.left
20
19
  end
21
20
 
22
21
  def right
23
- Position.new(x_coord: @x_coord,
24
- y_coord: @y_coord,
25
- direction: @direction.right)
22
+ new_position direction: @direction.right
26
23
  end
27
24
 
28
25
  def to_s
29
26
  "#{@x_coord}, #{@y_coord}, #{@direction}"
30
27
  end
28
+
29
+ private
30
+
31
+ def new_position(x_coord: @x_coord, y_coord: @y_coord, direction: @direction)
32
+ Position.new x_coord: x_coord, y_coord: y_coord, direction: direction
33
+ end
31
34
  end
@@ -0,0 +1,7 @@
1
+ require "toy_robot/command"
2
+
3
+ class ReportCommand < Command
4
+ def issue_command
5
+ @target.report
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require "toy_robot/command"
2
+
3
+ class RightCommand < Command
4
+ def issue_command
5
+ @target.right
6
+ end
7
+ end
@@ -1,25 +1,29 @@
1
+ require "toy_robot/position"
2
+ require "toy_robot/null_position"
3
+ require "toy_robot/arena"
4
+
1
5
  class Robot
2
- attr_accessor :position, :arena
6
+ attr_reader :position, :arena
3
7
 
4
- def initialize(position: NullPosition.new, arena:)
8
+ def initialize(position: NullPosition.new, arena: Arena.new)
5
9
  @position = position
6
10
  @arena = arena
7
11
  end
8
12
 
9
- def place(new_position)
10
- @position = safely_go_to new_position
13
+ def place(position)
14
+ safely_go_to position
11
15
  end
12
16
 
13
17
  def move
14
- @position = safely_go_to @position.advance
18
+ safely_go_to @position.advance
15
19
  end
16
20
 
17
21
  def left
18
- @position = @position.left
22
+ safely_go_to @position.left
19
23
  end
20
24
 
21
25
  def right
22
- @position = @position.right
26
+ safely_go_to @position.right
23
27
  end
24
28
 
25
29
  def report
@@ -28,11 +32,9 @@ class Robot
28
32
 
29
33
  private
30
34
 
31
- def safely_go_to(new_position)
32
- if @arena.inbounds? new_position.x_coord, new_position.y_coord
33
- new_position
34
- else
35
- @position
36
- end
35
+ def safely_go_to(position)
36
+ return unless position.x_coord && position.y_coord
37
+ return unless @arena.inbounds? position.x_coord, position.y_coord
38
+ @position = position
37
39
  end
38
40
  end
@@ -1,3 +1,3 @@
1
1
  module ToyRobot
2
- VERSION = "0.1.8".freeze
2
+ VERSION = "0.1.9".freeze
3
3
  end
data/toy_robot.gemspec CHANGED
@@ -6,7 +6,7 @@ require "toy_robot/version"
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "another_toy_robot"
8
8
  spec.version = ToyRobot::VERSION
9
- spec.date = "2016-12-01"
9
+ spec.date = "2016-12-05"
10
10
  spec.authors = "Sheldon J. Johnson"
11
11
  spec.email = "sheldon.j.johnson@outlook.com"
12
12
  spec.homepage = "https://github.com/drzel/toy_robot"
@@ -24,4 +24,10 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.bindir = "bin"
26
26
  spec.executables << "toy_robot"
27
+
28
+ spec.add_development_dependency "rspec", "~> 3.5"
29
+ spec.add_development_dependency "rake", "~> 11.3"
30
+ spec.add_development_dependency "factory_girl", "~> 4.0"
31
+ spec.add_development_dependency "simplecov", "~> 0.12"
32
+ spec.add_development_dependency "codeclimate-test-reporter", "~> 1.0"
27
33
  end
metadata CHANGED
@@ -1,15 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: another_toy_robot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sheldon J. Johnson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-01 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2016-12-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '11.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '11.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: factory_girl
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '4.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '4.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.12'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.12'
69
+ - !ruby/object:Gem::Dependency
70
+ name: codeclimate-test-reporter
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.0'
13
83
  description: The application is a simulation of a toy robot moving on a square tabletop. It
14
84
  is an example of a well tested, object oriented design, employing the command design
15
85
  pattern.
@@ -35,8 +105,15 @@ files:
35
105
  - lib/toy_robot/client.rb
36
106
  - lib/toy_robot/command.rb
37
107
  - lib/toy_robot/direction.rb
108
+ - lib/toy_robot/input.rb
109
+ - lib/toy_robot/invalid_command.rb
110
+ - lib/toy_robot/left_command.rb
111
+ - lib/toy_robot/move_command.rb
38
112
  - lib/toy_robot/null_position.rb
113
+ - lib/toy_robot/place_command.rb
39
114
  - lib/toy_robot/position.rb
115
+ - lib/toy_robot/report_command.rb
116
+ - lib/toy_robot/right_command.rb
40
117
  - lib/toy_robot/robot.rb
41
118
  - lib/toy_robot/version.rb
42
119
  - toy_robot.gemspec