maux_robot 0.1.0 → 0.2.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.
- checksums.yaml +5 -5
- data/README.md +3 -1
- data/bin/maux_robot +1 -0
- data/lib/maux_robot.rb +12 -10
- data/lib/maux_robot/cli.rb +2 -3
- data/lib/maux_robot/formatter.rb +3 -2
- data/lib/maux_robot/formatter/csv.rb +7 -6
- data/lib/maux_robot/formatter/json.rb +12 -7
- data/lib/maux_robot/parser.rb +6 -11
- data/lib/maux_robot/position.rb +14 -13
- data/lib/maux_robot/robot.rb +15 -17
- data/lib/maux_robot/table.rb +1 -2
- data/lib/maux_robot/version.rb +3 -3
- data/spec/maux_robot/cli_spec.rb +12 -10
- data/spec/maux_robot/formatter/csv_spec.rb +6 -4
- data/spec/maux_robot/formatter/json_spec.rb +6 -4
- data/spec/maux_robot/formatter_spec.rb +11 -9
- data/spec/maux_robot/parser_spec.rb +40 -34
- data/spec/maux_robot/position_spec.rb +44 -40
- data/spec/maux_robot/robot_spec.rb +26 -25
- data/spec/maux_robot/table_spec.rb +3 -3
- data/spec/spec_helper.rb +3 -1
- metadata +7 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9c718637133d2a7b8dfb7d42fdcd754ce4eff6ec1fba93f7fe5ddaaa612d1cc1
|
4
|
+
data.tar.gz: 064f6ebc5ceefaa8dc44a2ff1f577178675cf362ffb77c3726c6e2ae6f62f1f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8cd5c5b6adfccdda316a95ac5f88cefbef598239ed2e981c47f10a70b63a0133af84b70b1effafa04dc0643efafa22bb183d8779d43630310e6068a6a854c370
|
7
|
+
data.tar.gz: 51e46cca8fc6e0239ae9c286611fc11e4589959d5338fac2317107fd2703e3112c201ca63e50bdda96aade74e1c2d71a78c02ff7d93f83b40009d9c41c4bed29
|
data/README.md
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
[](https://travis-ci.org/mauriciovieira/maux_robot)
|
2
|
+
[](https://codeclimate.com/github/mauriciovieira/maux_robot/maintainability)
|
3
|
+
[](https://codeclimate.com/github/mauriciovieira/maux_robot/test_coverage)
|
2
4
|
|
3
5
|
# maux_robot
|
4
6
|
|
@@ -105,4 +107,4 @@ The Toy Robot Challenge was originally formulated by [Jon Eaves](https://twitter
|
|
105
107
|
**Mauricio Vieira (mauriciovieira)**
|
106
108
|
+ <http://mauriciovieira.net>
|
107
109
|
+ <https://twitter.com/mauriciovieira>
|
108
|
-
+ <https://github.com/mauriciovieira>
|
110
|
+
+ <https://github.com/mauriciovieira>
|
data/bin/maux_robot
CHANGED
data/lib/maux_robot.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "maux_robot/version"
|
4
|
+
require "maux_robot/cli"
|
5
|
+
require "maux_robot/formatter"
|
6
|
+
require "maux_robot/formatter/csv"
|
7
|
+
require "maux_robot/formatter/json"
|
8
|
+
require "maux_robot/parser"
|
9
|
+
require "maux_robot/position"
|
10
|
+
require "maux_robot/table"
|
11
|
+
require "maux_robot/robot"
|
10
12
|
|
11
13
|
module MauxRobot
|
12
|
-
end
|
14
|
+
end
|
data/lib/maux_robot/cli.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module MauxRobot
|
4
|
-
|
5
4
|
# The CLI is a class responsible of handling command line interface
|
6
5
|
class CLI
|
7
6
|
attr_reader :robot
|
@@ -30,11 +29,11 @@ module MauxRobot
|
|
30
29
|
end
|
31
30
|
|
32
31
|
def execute(command)
|
33
|
-
if command.
|
32
|
+
if command.key?(:arguments)
|
34
33
|
@robot.send(command[:order], command[:arguments])
|
35
34
|
else
|
36
35
|
@robot.send(command[:order])
|
37
36
|
end
|
38
37
|
end
|
39
38
|
end
|
40
|
-
end
|
39
|
+
end
|
data/lib/maux_robot/formatter.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module MauxRobot
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
module MauxRobot
|
4
|
+
module Formatter
|
5
|
+
class Csv
|
6
|
+
def generate(position)
|
7
|
+
"#{position.x},#{position.y},#{position.face.upcase}"
|
8
|
+
end
|
8
9
|
end
|
9
10
|
end
|
10
|
-
end
|
11
|
+
end
|
@@ -1,12 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "json"
|
4
4
|
|
5
|
-
module MauxRobot
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
module MauxRobot
|
6
|
+
module Formatter
|
7
|
+
class Json
|
8
|
+
def generate(position)
|
9
|
+
JSON.generate(
|
10
|
+
x: position.x,
|
11
|
+
y: position.y,
|
12
|
+
face: position.face.upcase.to_s
|
13
|
+
)
|
14
|
+
end
|
10
15
|
end
|
11
16
|
end
|
12
|
-
end
|
17
|
+
end
|
data/lib/maux_robot/parser.rb
CHANGED
@@ -1,26 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module MauxRobot
|
4
|
-
|
5
4
|
class Parser
|
6
5
|
ALLOWED_ORDERS = %i[left right move place report verbose].freeze
|
7
6
|
|
8
7
|
def parse(line_input)
|
9
|
-
clean_input = line_input.strip.squeeze(
|
8
|
+
clean_input = line_input.strip.squeeze(" ").split(" ")
|
10
9
|
order = sanitize_order(clean_input.shift)
|
11
10
|
return unless order
|
12
11
|
|
13
|
-
command = {
|
12
|
+
command = {order: order}
|
14
13
|
|
15
14
|
if clean_input.any?
|
16
|
-
arguments = sanitize_arguments(order, clean_input.join(
|
15
|
+
arguments = sanitize_arguments(order, clean_input.join(""))
|
17
16
|
command[:arguments] = arguments
|
18
17
|
end
|
19
18
|
|
20
19
|
command
|
21
20
|
end
|
22
21
|
|
23
|
-
|
24
22
|
private
|
25
23
|
|
26
24
|
def sanitize_order(input_string)
|
@@ -31,14 +29,11 @@ module MauxRobot
|
|
31
29
|
def sanitize_arguments(order, arguments)
|
32
30
|
case order
|
33
31
|
when :place
|
34
|
-
arguments = arguments.delete(
|
35
|
-
{
|
32
|
+
arguments = arguments.delete(" ").split(",")
|
33
|
+
{x: arguments[0], y: arguments[1], face: arguments[2]}
|
36
34
|
when :report
|
37
|
-
{
|
35
|
+
{format_type: arguments.downcase.to_sym}
|
38
36
|
end
|
39
37
|
end
|
40
38
|
end
|
41
39
|
end
|
42
|
-
|
43
|
-
|
44
|
-
|
data/lib/maux_robot/position.rb
CHANGED
@@ -1,22 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "maux_robot"
|
4
4
|
|
5
5
|
module MauxRobot
|
6
|
-
|
7
6
|
# This class represents the Robot position on the table
|
8
7
|
class Position
|
9
8
|
attr_reader :x, :y, :face
|
10
9
|
|
11
|
-
POSSIBLE_DIRECTIONS = [
|
10
|
+
POSSIBLE_DIRECTIONS = %i[north west south east].freeze
|
12
11
|
POSSIBLE_MOVEMENTS = {
|
13
|
-
north: {
|
14
|
-
west:
|
15
|
-
south: {
|
16
|
-
east:
|
17
|
-
}
|
12
|
+
north: {x: 0, y: 1},
|
13
|
+
west: {x: -1, y: 0},
|
14
|
+
south: {x: 0, y: -1},
|
15
|
+
east: {x: 1, y: 0}
|
16
|
+
}.freeze
|
18
17
|
|
19
|
-
def initialize(x, y, face)
|
18
|
+
def initialize(x, y, face) # rubocop:disable Naming/UncommunicativeMethodParamName
|
20
19
|
@x = x.to_i
|
21
20
|
@y = y.to_i
|
22
21
|
@face = face&.downcase&.to_sym || :invalid
|
@@ -28,13 +27,15 @@ module MauxRobot
|
|
28
27
|
|
29
28
|
def left
|
30
29
|
return self unless valid_direction?
|
31
|
-
|
30
|
+
|
31
|
+
next_direction_index = (POSSIBLE_DIRECTIONS.index(@face) + 1) % 4
|
32
32
|
@face = POSSIBLE_DIRECTIONS[next_direction_index]
|
33
33
|
end
|
34
34
|
|
35
35
|
def right
|
36
36
|
return self unless valid_direction?
|
37
|
-
|
37
|
+
|
38
|
+
next_direction_index = (POSSIBLE_DIRECTIONS.index(@face) - 1)
|
38
39
|
@face = POSSIBLE_DIRECTIONS[next_direction_index]
|
39
40
|
end
|
40
41
|
|
@@ -46,7 +47,7 @@ module MauxRobot
|
|
46
47
|
Position.new(x, y, @face)
|
47
48
|
end
|
48
49
|
|
49
|
-
def report(format_type
|
50
|
+
def report(format_type = :csv)
|
50
51
|
formatter = MauxRobot::Formatter.from(format_type)
|
51
52
|
puts formatter.generate(self)
|
52
53
|
end
|
@@ -61,4 +62,4 @@ module MauxRobot
|
|
61
62
|
super(nil, nil, nil)
|
62
63
|
end
|
63
64
|
end
|
64
|
-
end
|
65
|
+
end
|
data/lib/maux_robot/robot.rb
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "forwardable"
|
4
4
|
|
5
5
|
module MauxRobot
|
6
|
-
|
7
6
|
class RobotError < StandardError; end
|
8
7
|
|
9
8
|
# Error to notify that the robot was not placed yet
|
10
9
|
class RobotNotPlacedYet < RobotError
|
11
10
|
def initialize
|
12
|
-
super(
|
11
|
+
super("The robot was not placed yet!")
|
13
12
|
end
|
14
13
|
end
|
15
14
|
|
@@ -24,18 +23,19 @@ module MauxRobot
|
|
24
23
|
class Robot
|
25
24
|
attr_reader :position, :talkative
|
26
25
|
|
27
|
-
def initialize(table=MauxRobot::Table.new)
|
26
|
+
def initialize(table = MauxRobot::Table.new)
|
28
27
|
@table = table
|
29
28
|
@position = MauxRobot::NullPosition.new
|
30
29
|
@talkative = false
|
31
30
|
end
|
32
31
|
|
33
|
-
def place(x:, y:, face:)
|
32
|
+
def place(x:, y:, face:) # rubocop:disable Naming/UncommunicativeMethodParamName
|
34
33
|
position = MauxRobot::Position.new(x, y, face)
|
35
34
|
|
36
35
|
ok_to_go?(position) do
|
37
36
|
@position = position
|
38
37
|
end
|
38
|
+
@position
|
39
39
|
end
|
40
40
|
|
41
41
|
def move
|
@@ -45,6 +45,8 @@ module MauxRobot
|
|
45
45
|
ok_to_go?(next_position) do
|
46
46
|
@position = next_position
|
47
47
|
end
|
48
|
+
|
49
|
+
@position
|
48
50
|
end
|
49
51
|
end
|
50
52
|
|
@@ -68,26 +70,22 @@ module MauxRobot
|
|
68
70
|
|
69
71
|
def verbose
|
70
72
|
@talkative = !@talkative
|
71
|
-
is_not = @talkative ?
|
73
|
+
is_not = @talkative ? "is" : "is not"
|
72
74
|
puts "Robot #{is_not} talkative now."
|
73
75
|
end
|
74
76
|
|
75
77
|
private
|
76
78
|
|
77
79
|
def ok_to_go?(position)
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
raise NotOkToGo.new(position)
|
82
|
-
end
|
80
|
+
raise NotOkToGo, position unless @table.contains?(position)
|
81
|
+
|
82
|
+
yield
|
83
83
|
end
|
84
84
|
|
85
85
|
def robot_placed?
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
raise RobotNotPlacedYet
|
90
|
-
end
|
86
|
+
raise RobotNotPlacedYet if @position.class == MauxRobot::NullPosition
|
87
|
+
|
88
|
+
yield
|
91
89
|
end
|
92
90
|
end
|
93
|
-
end
|
91
|
+
end
|
data/lib/maux_robot/table.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module MauxRobot
|
4
|
-
|
5
4
|
# This class represents a table according to simulation rules
|
6
5
|
class Table
|
7
|
-
def initialize(x: [0, 4], y: [0, 4])
|
6
|
+
def initialize(x: [0, 4], y: [0, 4]) # rubocop:disable Naming/UncommunicativeMethodParamName
|
8
7
|
@x = x
|
9
8
|
@y = y
|
10
9
|
end
|
data/lib/maux_robot/version.rb
CHANGED
@@ -3,14 +3,14 @@
|
|
3
3
|
module MauxRobot
|
4
4
|
# This module holds the MauxRobot version information.
|
5
5
|
module Version
|
6
|
-
STRING =
|
6
|
+
STRING = "0.2.0"
|
7
7
|
|
8
|
-
MSG =
|
8
|
+
MSG = "%s (using Parser %s, running on %s %s %s)"
|
9
9
|
|
10
10
|
def self.version(debug = false)
|
11
11
|
if debug
|
12
12
|
format(MSG, STRING, Parser::VERSION,
|
13
|
-
|
13
|
+
RUBY_ENGINE, RUBY_VERSION, RUBY_PLATFORM)
|
14
14
|
else
|
15
15
|
STRING
|
16
16
|
end
|
data/spec/maux_robot/cli_spec.rb
CHANGED
@@ -1,21 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "maux_robot"
|
4
4
|
|
5
5
|
describe MauxRobot::CLI do
|
6
|
+
subject(:cli) { described_class.new }
|
6
7
|
|
7
|
-
describe
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
describe "#execute" do
|
9
|
+
let(:position) { MauxRobot::Position.new(0, 2, :east) }
|
10
|
+
|
11
|
+
context "when input is parsed without arguments" do
|
12
|
+
it "sends proper message to robot" do
|
13
|
+
allow(cli.robot).to receive(:move).and_return(position)
|
14
|
+
expect(cli.execute(order: :move)).to eq(position)
|
12
15
|
end
|
13
16
|
end
|
14
17
|
|
15
|
-
context
|
16
|
-
it
|
17
|
-
expect(
|
18
|
-
subject.execute(order: :place, arguments: { x: '0', y: '2', face: 'EAST' })
|
18
|
+
context "when place is parsed command with arguments" do
|
19
|
+
it "sends proper message to robot" do
|
20
|
+
expect(cli.execute(order: :place, arguments: {x: "0", y: "2", face: "EAST"})).to eq(position)
|
19
21
|
end
|
20
22
|
end
|
21
23
|
end
|
@@ -1,11 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
describe MauxRobot::Formatter::Csv do
|
4
|
-
let
|
4
|
+
let(:position) { MauxRobot::Position.new(1, 2, :west) }
|
5
|
+
|
6
|
+
describe "#generate" do
|
7
|
+
subject(:csv_formatter) { described_class.new }
|
5
8
|
|
6
|
-
context '#generate' do
|
7
9
|
it "Formats a position as CSV" do
|
8
|
-
expect(
|
10
|
+
expect(csv_formatter.generate(position)).to eq("1,2,WEST")
|
9
11
|
end
|
10
12
|
end
|
11
|
-
end
|
13
|
+
end
|
@@ -1,11 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
describe MauxRobot::Formatter::Json do
|
4
|
-
let
|
4
|
+
let(:position) { MauxRobot::Position.new(1, 2, :west) }
|
5
|
+
|
6
|
+
describe "#generate" do
|
7
|
+
subject(:json_formatter) { described_class.new }
|
5
8
|
|
6
|
-
context '#generate' do
|
7
9
|
it "Formats a position as JSON" do
|
8
|
-
expect(
|
10
|
+
expect(json_formatter.generate(position)).to eq('{"x":1,"y":2,"face":"WEST"}')
|
9
11
|
end
|
10
12
|
end
|
11
|
-
end
|
13
|
+
end
|
@@ -1,21 +1,23 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
describe MauxRobot::Formatter do
|
4
|
-
|
4
|
+
subject(:formatter) { described_class }
|
5
|
+
|
6
|
+
describe "#from" do
|
5
7
|
describe "valid format_types" do
|
6
8
|
it "returns csv formatter" do
|
7
|
-
expect(
|
9
|
+
expect(formatter.from(:csv).class).to eq(MauxRobot::Formatter::Csv)
|
8
10
|
end
|
9
11
|
|
10
|
-
it
|
11
|
-
expect(
|
12
|
+
it "returns json formatter" do
|
13
|
+
expect(formatter.from(:json).class).to eq(MauxRobot::Formatter::Json)
|
12
14
|
end
|
13
15
|
end
|
14
16
|
|
15
|
-
describe
|
16
|
-
it
|
17
|
-
expect(
|
17
|
+
describe "invalid format_types" do
|
18
|
+
it "defaults to csv formatter" do
|
19
|
+
expect(formatter.from(:anything).class).to eq(MauxRobot::Formatter::Csv)
|
18
20
|
end
|
19
21
|
end
|
20
22
|
end
|
21
|
-
end
|
23
|
+
end
|
@@ -1,67 +1,73 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rubocop:disable Metrics/BlockLength
|
3
4
|
describe MauxRobot::Parser do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
subject(:parser) { described_class.new }
|
6
|
+
|
7
|
+
describe "#parse" do
|
8
|
+
context "with valid orders" do
|
9
|
+
it "#report" do
|
10
|
+
expect(parser.parse("REPORT")).to eq(order: :report)
|
8
11
|
end
|
9
12
|
|
10
|
-
it
|
11
|
-
expect(
|
13
|
+
it "#report csv" do
|
14
|
+
expect(parser.parse("REPORT CSV")).to eq(order: :report, arguments: {format_type: :csv})
|
12
15
|
end
|
13
16
|
|
14
|
-
it
|
15
|
-
expect(
|
17
|
+
it "#report json" do
|
18
|
+
expect(parser.parse("REPORT JSON")).to eq(order: :report, arguments: {format_type: :json})
|
16
19
|
end
|
17
20
|
|
18
|
-
it
|
19
|
-
expect(
|
21
|
+
it "#move" do
|
22
|
+
expect(parser.parse("MOVE")).to eq(order: :move)
|
20
23
|
end
|
21
24
|
|
22
|
-
it
|
23
|
-
expect(
|
25
|
+
it "#left" do
|
26
|
+
expect(parser.parse("LEFT")).to eq(order: :left)
|
24
27
|
end
|
25
28
|
|
26
|
-
it
|
27
|
-
expect(
|
29
|
+
it "#right" do
|
30
|
+
expect(parser.parse("RIGHT")).to eq(order: :right)
|
28
31
|
end
|
29
32
|
|
30
|
-
it
|
31
|
-
expect(
|
33
|
+
it "#verbose" do
|
34
|
+
expect(parser.parse("VERBOSE")).to eq(order: :verbose)
|
32
35
|
end
|
33
36
|
|
34
|
-
it
|
35
|
-
expect(
|
37
|
+
it "#place" do
|
38
|
+
expect(parser.parse("PLACE 0,3,WEST")).to eq(order: :place, arguments: {x: "0", y: "3", face: "WEST"})
|
36
39
|
end
|
37
40
|
end
|
38
41
|
|
39
|
-
context
|
40
|
-
it
|
41
|
-
expect(
|
42
|
+
context "with orders with spaces and downcase" do
|
43
|
+
it "#report" do
|
44
|
+
expect(parser.parse(" repoRT")).to eq(order: :report)
|
42
45
|
end
|
43
46
|
|
44
|
-
it
|
45
|
-
expect(
|
47
|
+
it "#move" do
|
48
|
+
expect(parser.parse("move ")).to eq(order: :move)
|
46
49
|
end
|
47
50
|
|
48
|
-
it
|
49
|
-
expect(
|
51
|
+
it "#left" do
|
52
|
+
expect(parser.parse(" LefT ")).to eq(order: :left)
|
50
53
|
end
|
51
54
|
|
52
|
-
it
|
53
|
-
expect(
|
55
|
+
it "#right" do
|
56
|
+
expect(parser.parse(" rigHt")).to eq(order: :right)
|
54
57
|
end
|
55
58
|
|
56
|
-
it
|
57
|
-
expect(
|
59
|
+
it "#place" do
|
60
|
+
expect(parser.parse("PLACE 2 , 1 , NOrth")).to eq(
|
61
|
+
order: :place, arguments: {x: "2", y: "1", face: "NOrth"}
|
62
|
+
)
|
58
63
|
end
|
59
64
|
end
|
60
65
|
|
61
|
-
context
|
62
|
-
it
|
63
|
-
expect(
|
66
|
+
context "with invalid orders" do
|
67
|
+
it "ignores anything else" do
|
68
|
+
expect(parser.parse("blablabla balbla")).to be_nil
|
64
69
|
end
|
65
70
|
end
|
66
71
|
end
|
67
|
-
end
|
72
|
+
end
|
73
|
+
# rubocop:enable Metrics/BlockLength
|
@@ -1,10 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rubocop:disable Metrics/BlockLength:
|
3
4
|
describe MauxRobot::Position do
|
4
|
-
describe
|
5
|
-
context
|
6
|
-
it
|
7
|
-
position =
|
5
|
+
describe "#initialize" do
|
6
|
+
context "when text input is given" do
|
7
|
+
it "normalizes arguments" do
|
8
|
+
position = described_class.new("0", "1", "SOUTH")
|
8
9
|
|
9
10
|
expect(position.x).to eq(0)
|
10
11
|
expect(position.y).to eq(1)
|
@@ -13,29 +14,29 @@ describe MauxRobot::Position do
|
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
16
|
-
describe
|
17
|
-
context
|
18
|
-
it
|
19
|
-
position =
|
17
|
+
describe "#valid_direction?" do
|
18
|
+
context "when a possible diretion is given" do
|
19
|
+
it "is valid" do
|
20
|
+
position = described_class.new(5, 0, :south)
|
20
21
|
|
21
22
|
expect(position.valid_direction?).to eq(true)
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
25
|
-
context
|
26
|
-
it
|
27
|
-
position =
|
26
|
+
context "when a not possible direction is given" do
|
27
|
+
it "is not valid " do
|
28
|
+
position = described_class.new(1, 1, :south_west)
|
28
29
|
|
29
30
|
expect(position.valid_direction?).to eq(false)
|
30
31
|
end
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
34
|
-
describe
|
35
|
-
let(:position) {
|
35
|
+
describe "rotation" do
|
36
|
+
let(:position) { described_class.new(2, 2, :north) }
|
36
37
|
|
37
|
-
|
38
|
-
it
|
38
|
+
describe "#left" do
|
39
|
+
it "rotates counter-clockwise" do
|
39
40
|
position.left
|
40
41
|
expect(position.face).to eq(:west)
|
41
42
|
|
@@ -50,8 +51,8 @@ describe MauxRobot::Position do
|
|
50
51
|
end
|
51
52
|
end
|
52
53
|
|
53
|
-
|
54
|
-
it
|
54
|
+
describe "#right" do
|
55
|
+
it "rotates clockwise" do
|
55
56
|
position.right
|
56
57
|
expect(position.face).to eq(:east)
|
57
58
|
|
@@ -67,11 +68,11 @@ describe MauxRobot::Position do
|
|
67
68
|
end
|
68
69
|
end
|
69
70
|
|
70
|
-
describe
|
71
|
-
context
|
72
|
-
let(:position) {
|
71
|
+
describe "#forward_position" do # rubocop:disable Metrics/BlockLength
|
72
|
+
context "when facing north" do
|
73
|
+
let(:position) { described_class.new(5, 0, :north) }
|
73
74
|
|
74
|
-
it
|
75
|
+
it "returns a new position 1 step upwards" do
|
75
76
|
new_position = position.forward_position
|
76
77
|
expect(position.x).to eq(5)
|
77
78
|
expect(position.y).to eq(0)
|
@@ -80,10 +81,10 @@ describe MauxRobot::Position do
|
|
80
81
|
end
|
81
82
|
end
|
82
83
|
|
83
|
-
context
|
84
|
-
let(:position) {
|
84
|
+
context "when facing west" do
|
85
|
+
let(:position) { described_class.new(2, 1, :west) }
|
85
86
|
|
86
|
-
it
|
87
|
+
it "returns a new position 1 step leftwards" do
|
87
88
|
new_position = position.forward_position
|
88
89
|
expect(position.x).to eq(2)
|
89
90
|
expect(position.y).to eq(1)
|
@@ -92,10 +93,10 @@ describe MauxRobot::Position do
|
|
92
93
|
end
|
93
94
|
end
|
94
95
|
|
95
|
-
context
|
96
|
-
let(:position) {
|
96
|
+
context "when facing south" do
|
97
|
+
let(:position) { described_class.new(1, 3, :south) }
|
97
98
|
|
98
|
-
it
|
99
|
+
it "returns a new position 1 step downwards" do
|
99
100
|
new_position = position.forward_position
|
100
101
|
expect(position.x).to eq(1)
|
101
102
|
expect(position.y).to eq(3)
|
@@ -104,10 +105,10 @@ describe MauxRobot::Position do
|
|
104
105
|
end
|
105
106
|
end
|
106
107
|
|
107
|
-
context
|
108
|
-
let(:position) {
|
108
|
+
context "when facing east" do
|
109
|
+
let(:position) { described_class.new(2, 0, :east) }
|
109
110
|
|
110
|
-
it
|
111
|
+
it "returns a new position 1 step rightwards" do
|
111
112
|
new_position = position.forward_position
|
112
113
|
expect(position.x).to eq(2)
|
113
114
|
expect(position.y).to eq(0)
|
@@ -117,27 +118,30 @@ describe MauxRobot::Position do
|
|
117
118
|
end
|
118
119
|
end
|
119
120
|
|
120
|
-
describe
|
121
|
-
context
|
122
|
-
let(:position) {
|
121
|
+
describe "#report" do
|
122
|
+
context "when x, y and face are defined" do
|
123
|
+
let(:position) { described_class.new(5, 0, :north) }
|
123
124
|
|
124
|
-
it
|
125
|
+
it "prints X,Y,FACE" do
|
125
126
|
expect { position.report }.to output("5,0,NORTH\n").to_stdout
|
126
127
|
end
|
127
128
|
end
|
128
129
|
|
129
|
-
context
|
130
|
-
let(:position) {
|
131
|
-
|
130
|
+
context "when only face is defined" do
|
131
|
+
let(:position) { described_class.new(nil, nil, "SOUTH") }
|
132
|
+
|
133
|
+
it "prints 0,0,FACE" do
|
132
134
|
expect { position.report }.to output("0,0,SOUTH\n").to_stdout
|
133
135
|
end
|
134
136
|
end
|
135
137
|
|
136
|
-
context
|
137
|
-
let(:position) {
|
138
|
-
|
138
|
+
context "when face is not defined" do
|
139
|
+
let(:position) { described_class.new(5, 0, nil) }
|
140
|
+
|
141
|
+
it "prints X,Y,INVALID" do
|
139
142
|
expect { position.report }.to output("5,0,INVALID\n").to_stdout
|
140
143
|
end
|
141
144
|
end
|
142
145
|
end
|
143
146
|
end
|
147
|
+
# rubocop:enable Metrics/BlockLength:
|
@@ -1,41 +1,42 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe MauxRobot::Robot do
|
3
|
+
describe MauxRobot::Robot do # rubocop:disable Metrics/BlockLength
|
4
4
|
subject(:robot) { described_class.new }
|
5
|
+
|
5
6
|
let(:null_position) { MauxRobot::NullPosition.new }
|
6
7
|
|
7
|
-
describe
|
8
|
-
context
|
9
|
-
it
|
8
|
+
describe "#place" do
|
9
|
+
context "when given a valid place" do
|
10
|
+
it "has a position" do
|
10
11
|
robot.place(x: 0, y: 0, face: :north)
|
11
12
|
|
12
13
|
expect(robot.position).not_to eq null_position
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
16
|
-
context
|
17
|
-
it
|
17
|
+
context "when given an invalid place" do
|
18
|
+
it "raises NotOkToGo error" do
|
18
19
|
expect { robot.place(x: 5, y: 0, face: :south) }.to raise_error MauxRobot::NotOkToGo
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
22
|
-
context
|
23
|
-
it
|
23
|
+
context "when given an invalid direction" do
|
24
|
+
it "raises NotOkToGo error" do
|
24
25
|
expect { robot.place(x: 0, y: 2, face: :south_east) }.to raise_error MauxRobot::NotOkToGo
|
25
26
|
end
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
29
|
-
describe
|
30
|
-
context
|
31
|
-
it
|
30
|
+
describe "#left" do
|
31
|
+
context "when robot is not placed" do
|
32
|
+
it "raises RobotNotPlacedYet error" do
|
32
33
|
expect { robot.left }.to raise_error MauxRobot::RobotNotPlacedYet
|
33
34
|
expect(robot.position).to eq null_position
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
37
|
-
context
|
38
|
-
it
|
38
|
+
context "when robot is placed" do
|
39
|
+
it "rotates accordingly" do
|
39
40
|
robot.place(x: 1, y: 2, face: :south)
|
40
41
|
robot.left
|
41
42
|
|
@@ -44,17 +45,17 @@ describe MauxRobot::Robot do
|
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
47
|
-
describe
|
48
|
-
context
|
49
|
-
it
|
48
|
+
describe "#right" do
|
49
|
+
context "when robot is not placed" do
|
50
|
+
it "raises RobotNotPlacedYet error" do
|
50
51
|
expect { robot.right }.to raise_error MauxRobot::RobotNotPlacedYet
|
51
52
|
|
52
53
|
expect(robot.position).to eq null_position
|
53
54
|
end
|
54
55
|
end
|
55
56
|
|
56
|
-
context
|
57
|
-
it
|
57
|
+
context "with robot placed" do
|
58
|
+
it "rotates accordingly" do
|
58
59
|
robot.place(x: 3, y: 2, face: :north)
|
59
60
|
robot.right
|
60
61
|
|
@@ -63,16 +64,16 @@ describe MauxRobot::Robot do
|
|
63
64
|
end
|
64
65
|
end
|
65
66
|
|
66
|
-
describe
|
67
|
-
context
|
68
|
-
it
|
67
|
+
describe "#move" do
|
68
|
+
context "with robot not placed" do
|
69
|
+
it "raises RobotNotPlacedYet error" do
|
69
70
|
expect { robot.right }.to raise_error MauxRobot::RobotNotPlacedYet
|
70
71
|
expect(robot.position).to eq null_position
|
71
72
|
end
|
72
73
|
end
|
73
74
|
|
74
|
-
context
|
75
|
-
it
|
75
|
+
context "when placing on the table" do
|
76
|
+
it "updates its position" do
|
76
77
|
robot.place(x: 3, y: 2, face: :north)
|
77
78
|
robot.move
|
78
79
|
|
@@ -82,8 +83,8 @@ describe MauxRobot::Robot do
|
|
82
83
|
end
|
83
84
|
end
|
84
85
|
|
85
|
-
context
|
86
|
-
it
|
86
|
+
context "when outside the table" do
|
87
|
+
it "stays where it is" do
|
87
88
|
robot.place(x: 0, y: 0, face: :south)
|
88
89
|
|
89
90
|
expect { robot.move }.to raise_error MauxRobot::NotOkToGo
|
@@ -3,13 +3,13 @@
|
|
3
3
|
describe MauxRobot::Table do
|
4
4
|
subject(:table) { described_class.new(x: [-1, 2], y: [3, 6]) }
|
5
5
|
|
6
|
-
|
7
|
-
it
|
6
|
+
describe "#contains?" do
|
7
|
+
it "contains a position inside boundaries" do
|
8
8
|
position = MauxRobot::Position.new(0, 4, :north)
|
9
9
|
expect(table.contains?(position)).to be true
|
10
10
|
end
|
11
11
|
|
12
|
-
it
|
12
|
+
it "does not contain a position outside boundaries" do
|
13
13
|
position = MauxRobot::Position.new(3, 2, :east)
|
14
14
|
expect(table.contains?(position)).to be false
|
15
15
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,35 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: maux_robot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mauricio Vieira
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: standard
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
20
|
-
- - ">="
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 3.6.0
|
19
|
+
version: 0.4.7
|
23
20
|
type: :development
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
24
|
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
30
|
-
- - ">="
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: 3.6.0
|
26
|
+
version: 0.4.7
|
33
27
|
description: " Maux version of a Toy Robot Simulator.\n"
|
34
28
|
email: maux_robot@mauriciovieira.net
|
35
29
|
executables:
|
@@ -78,15 +72,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
78
72
|
requirements:
|
79
73
|
- - ">="
|
80
74
|
- !ruby/object:Gem::Version
|
81
|
-
version: 2.
|
75
|
+
version: 2.6.0
|
82
76
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
77
|
requirements:
|
84
78
|
- - ">="
|
85
79
|
- !ruby/object:Gem::Version
|
86
80
|
version: '0'
|
87
81
|
requirements: []
|
88
|
-
|
89
|
-
rubygems_version: 2.6.12
|
82
|
+
rubygems_version: 3.0.3
|
90
83
|
signing_key:
|
91
84
|
specification_version: 4
|
92
85
|
summary: Maux version of a Toy Robot Simulator.
|