maux_robot 0.0.3 → 0.2.1

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
- SHA1:
3
- metadata.gz: 776efb576b9d292a6d18f2ab3428c45b223399a3
4
- data.tar.gz: 8f65894e13ff0bb52a95a61b0654d58200a53cb8
2
+ SHA256:
3
+ metadata.gz: bb0f6fcc5ae3274a9d93db090e6a853d97c11f98a140fb2a79831a1c02a9ff98
4
+ data.tar.gz: ba213d2c6232452a777474ddf4c7b2c9fc164fab3b4e26b93bea068819d28fde
5
5
  SHA512:
6
- metadata.gz: 20aef8da93c3cb1f28378607a95020a8201fef566adc14522432d3a1ab0723b7c597dab066bc57c2359a51d83ea9785cd1bb28602d32b95418b5b16b122bd130
7
- data.tar.gz: d09ae6bb62e2bdbc5d9b2f5f110ae78d0ebc0d86b66c8371d42984dea9823e138cc0eff556cd0b94fd04cb6f030e9079fbd0d3a3afded3ca5b6d5e8ad70582c7
6
+ metadata.gz: 2aec0265aacd2e5b3bb2c46cee40ee9126a2e1ae4e6c20ff7a87e274d881704dabd04aac8c631e2f7b6ea736b521068ca2982a1bb5472cc1ecd3046c4f2d7ace
7
+ data.tar.gz: f92e4cf8c646c32150c7ace2c1492d4753476ca23b9d35f01cbfdf6d47f288da31f0683a9942c841fadcc8428e208c8690f7abc6de25248ff353687538f66bd2
data/README.md CHANGED
@@ -1,3 +1,7 @@
1
+ [![Build Status](https://travis-ci.org/mauriciovieira/maux_robot.svg?branch=master)](https://travis-ci.org/mauriciovieira/maux_robot)
2
+ [![Maintainability](https://api.codeclimate.com/v1/badges/b45a7baf1130fb9aa8f6/maintainability)](https://codeclimate.com/github/mauriciovieira/maux_robot/maintainability)
3
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/b45a7baf1130fb9aa8f6/test_coverage)](https://codeclimate.com/github/mauriciovieira/maux_robot/test_coverage)
4
+
1
5
  # maux_robot
2
6
 
3
7
  Maux version of a Toy Robot Simulator in Ruby
@@ -22,7 +26,8 @@ PLACE X,Y,F
22
26
  MOVE
23
27
  LEFT
24
28
  RIGHT
25
- REPORT
29
+ REPORT [csv|json]
30
+ VERBOSE
26
31
  ```
27
32
 
28
33
  * `PLACE` will put the toy robot on the table in position X,Y
@@ -38,7 +43,8 @@ in the direction it is currently facing.
38
43
  * `LEFT` and `RIGHT` will rotate the robot 90 degrees
39
44
  in the specified direction
40
45
  without changing the position of the robot.
41
- * `REPORT` will announce the X,Y and F of the robot.
46
+ * `REPORT` will announce the X,Y and F of the robot. If `csv` or `json` is passed, it formats the whereabouts accordingly. The default format is `csv`.
47
+ * `VERBOSE` will turn the error messages (talkative mode) on or off. The robot starts with talkative mode set to off.
42
48
 
43
49
  * A robot that is not on the table ignores the `MOVE`, `LEFT`, `RIGHT` and `REPORT` commands.
44
50
 
@@ -101,4 +107,4 @@ The Toy Robot Challenge was originally formulated by [Jon Eaves](https://twitter
101
107
  **Mauricio Vieira (mauriciovieira)**
102
108
  + <http://mauriciovieira.net>
103
109
  + <https://twitter.com/mauriciovieira>
104
- + <https://github.com/mauriciovieira>
110
+ + <https://github.com/mauriciovieira>
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  $LOAD_PATH.unshift("#{__dir__}/../lib")
4
5
 
@@ -1,5 +1,14 @@
1
- require 'maux_robot/version'
2
- require 'maux_robot/cli'
3
- require 'maux_robot/position'
4
- require 'maux_robot/table'
5
- require 'maux_robot/robot'
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"
12
+
13
+ module MauxRobot
14
+ end
@@ -1,11 +1,8 @@
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
- ALLOWED_ORDERS = %i[left right move place report].freeze
8
-
9
6
  attr_reader :robot
10
7
  def initialize
11
8
  @robot = Robot.new
@@ -19,43 +16,24 @@ module MauxRobot
19
16
  def run_script(all_input)
20
17
  all_input.split("\n").each do |line_input|
21
18
  command = parse(line_input)
22
- execute(command) if command
19
+ begin
20
+ execute(command) if command
21
+ rescue MauxRobot::RobotError => e
22
+ puts e if @robot.talkative
23
+ end
23
24
  end
24
25
  end
25
26
 
26
27
  def parse(line_input)
27
- clean_input = line_input.strip.squeeze(' ').split(' ')
28
- order = sanitize_order(clean_input.shift)
29
- return unless order
30
-
31
- command = { order: order }
32
-
33
- if clean_input.any?
34
- arguments = sanitize_arguments(clean_input.join(''))
35
- command[:arguments] = arguments
36
- end
37
-
38
- command
28
+ Parser.new.parse(line_input)
39
29
  end
40
30
 
41
31
  def execute(command)
42
- if command[:arguments].nil?
43
- @robot.send(command[:order])
44
- else
32
+ if command.key?(:arguments)
45
33
  @robot.send(command[:order], command[:arguments])
34
+ else
35
+ @robot.send(command[:order])
46
36
  end
47
37
  end
48
-
49
- private
50
-
51
- def sanitize_order(input_string)
52
- order = input_string.downcase.to_sym
53
- order if ALLOWED_ORDERS.include?(order)
54
- end
55
-
56
- def sanitize_arguments(arguments)
57
- arguments = arguments.delete(' ').split(',')
58
- { x: arguments[0], y: arguments[1], face: arguments[2] }
59
- end
60
38
  end
61
- end
39
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MauxRobot
4
+ module Formatter
5
+ def self.from(format_type)
6
+ case format_type
7
+ when :json
8
+ Formatter::Json.new
9
+ else
10
+ Formatter::Csv.new
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MauxRobot
4
+ module Formatter
5
+ class Csv
6
+ def generate(position)
7
+ "#{position.x},#{position.y},#{position.face.upcase}"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
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
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MauxRobot
4
+ class Parser
5
+ ALLOWED_ORDERS = %i[left right move place report verbose].freeze
6
+
7
+ def parse(line_input)
8
+ clean_input = line_input.strip.squeeze(" ").split(" ")
9
+ order = sanitize_order(clean_input.shift)
10
+ return unless order
11
+
12
+ command = {order: order}
13
+
14
+ if clean_input.any?
15
+ arguments = sanitize_arguments(order, clean_input.join(""))
16
+ command[:arguments] = arguments
17
+ end
18
+
19
+ command
20
+ end
21
+
22
+ private
23
+
24
+ def sanitize_order(input_string)
25
+ order = input_string.downcase.to_sym
26
+ order if ALLOWED_ORDERS.include?(order)
27
+ end
28
+
29
+ def sanitize_arguments(order, arguments)
30
+ case order
31
+ when :place
32
+ arguments = arguments.delete(" ").split(",")
33
+ {x: arguments[0], y: arguments[1], face: arguments[2]}
34
+ when :report
35
+ {format_type: arguments.downcase.to_sym}
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,22 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'maux_robot'
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 = [:north, :west, :south, :east]
10
+ POSSIBLE_DIRECTIONS = %i[north west south east].freeze
12
11
  POSSIBLE_MOVEMENTS = {
13
- north: { x: 0, y: 1 },
14
- west: { x: -1, y: 0 },
15
- south: { x: 0, y: -1 },
16
- east: { x: 1, y: 0 },
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
@@ -26,24 +25,41 @@ module MauxRobot
26
25
  POSSIBLE_DIRECTIONS.include?(@face)
27
26
  end
28
27
 
29
- def turn_left
30
- next_direction_index = ( POSSIBLE_DIRECTIONS.index(@face) + 1 ) % 4
28
+ def left
29
+ return self unless valid_direction?
30
+
31
+ next_direction_index = (POSSIBLE_DIRECTIONS.index(@face) + 1) % 4
31
32
  @face = POSSIBLE_DIRECTIONS[next_direction_index]
32
33
  end
33
34
 
34
- def turn_right
35
- next_direction_index = ( POSSIBLE_DIRECTIONS.index(@face) - 1 )
35
+ def right
36
+ return self unless valid_direction?
37
+
38
+ next_direction_index = (POSSIBLE_DIRECTIONS.index(@face) - 1)
36
39
  @face = POSSIBLE_DIRECTIONS[next_direction_index]
37
40
  end
38
41
 
39
42
  def forward_position
43
+ return self unless valid_direction?
44
+
40
45
  x = @x + POSSIBLE_MOVEMENTS[@face][:x]
41
46
  y = @y + POSSIBLE_MOVEMENTS[@face][:y]
42
47
  Position.new(x, y, @face)
43
48
  end
44
49
 
45
- def to_s
46
- "#{@x},#{@y},#{@face.upcase.to_s}"
50
+ def report(format_type = :csv)
51
+ formatter = MauxRobot::Formatter.from(format_type)
52
+ puts formatter.generate(self)
53
+ end
54
+
55
+ def ==(other)
56
+ other.x == x && other.y == y && other.face == face
57
+ end
58
+ end
59
+
60
+ class NullPosition < Position
61
+ def initialize
62
+ super(nil, nil, nil)
47
63
  end
48
64
  end
49
- end
65
+ end
@@ -1,41 +1,91 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "forwardable"
4
+
3
5
  module MauxRobot
6
+ class RobotError < StandardError; end
7
+
8
+ # Error to notify that the robot was not placed yet
9
+ class RobotNotPlacedYet < RobotError
10
+ def initialize
11
+ super("The robot was not placed yet!")
12
+ end
13
+ end
14
+
15
+ # Error to notify that the position is/would be outside the table
16
+ class NotOkToGo < RobotError
17
+ def initialize(position)
18
+ super("It's not ok to go to #{position.x},#{position.y}")
19
+ end
20
+ end
4
21
 
5
22
  # The main class. It executes the actions using its table and position
6
23
  class Robot
7
- attr_reader :position
24
+ attr_reader :position, :talkative
8
25
 
9
- def initialize(table=MauxRobot::Table.new)
26
+ def initialize(table = MauxRobot::Table.new)
10
27
  @table = table
28
+ @position = MauxRobot::NullPosition.new
29
+ @talkative = false
11
30
  end
12
31
 
13
- def place(x:, y:, face:)
32
+ def place(x:, y:, face:) # rubocop:disable Naming/UncommunicativeMethodParamName
14
33
  position = MauxRobot::Position.new(x, y, face)
15
34
 
16
- if position.valid_direction? and @table.contains?(position)
35
+ ok_to_go?(position) do
17
36
  @position = position
18
37
  end
38
+ @position
39
+ end
40
+
41
+ def move
42
+ robot_placed? do
43
+ next_position = @position.forward_position
44
+
45
+ ok_to_go?(next_position) do
46
+ @position = next_position
47
+ end
48
+
49
+ @position
50
+ end
19
51
  end
20
52
 
21
53
  def left
22
- @position&.turn_left
54
+ robot_placed? do
55
+ @position.left
56
+ end
23
57
  end
24
58
 
25
59
  def right
26
- @position&.turn_right
60
+ robot_placed? do
61
+ @position.right
62
+ end
27
63
  end
28
64
 
29
- def move
30
- next_position = @position.forward_position
31
-
32
- if @table.contains?(next_position)
33
- @position = next_position
65
+ def report(format_type: :csv)
66
+ robot_placed? do
67
+ @position.report(format_type)
34
68
  end
35
69
  end
36
70
 
37
- def report
38
- puts @position if @position
71
+ def verbose
72
+ @talkative = !@talkative
73
+ is_not = @talkative ? "is" : "is not"
74
+ puts "Robot #{is_not} talkative now."
75
+ end
76
+
77
+ private
78
+
79
+ def ok_to_go?(position)
80
+ raise NotOkToGo, position unless @table.contains?(position)
81
+
82
+ yield
83
+ end
84
+
85
+ def robot_placed?
86
+ raise RobotNotPlacedYet if @position.class == MauxRobot::NullPosition
87
+
88
+ yield
39
89
  end
40
90
  end
41
- end
91
+ end
@@ -1,16 +1,16 @@
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
11
10
 
12
11
  def contains?(position)
13
- position.x.between?(@x[0], @x[1]) &&
12
+ position.valid_direction? &&
13
+ position.x.between?(@x[0], @x[1]) &&
14
14
  position.y.between?(@y[0], @y[1])
15
15
  end
16
16
  end
@@ -3,14 +3,14 @@
3
3
  module MauxRobot
4
4
  # This module holds the MauxRobot version information.
5
5
  module Version
6
- STRING = '0.0.3'.freeze
6
+ STRING = "0.2.1"
7
7
 
8
- MSG = '%s (using Parser %s, running on %s %s %s)'.freeze
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
- RUBY_ENGINE, RUBY_VERSION, RUBY_PLATFORM)
13
+ RUBY_ENGINE, RUBY_VERSION, RUBY_PLATFORM)
14
14
  else
15
15
  STRING
16
16
  end
@@ -0,0 +1,10 @@
1
+ namespace :maux_robot do
2
+ desc "Run linter and tests for CI"
3
+ task :ci do
4
+ puts "Running ruby standard code style linter"
5
+ Rake::Task["standard"].invoke
6
+
7
+ puts "Running rspec"
8
+ Rake::Task["spec"].invoke
9
+ end
10
+ end
@@ -1,70 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'maux_robot'
3
+ require "maux_robot"
4
4
 
5
5
  describe MauxRobot::CLI do
6
- describe '#parse' do
7
- context 'valid orders' do
8
- it '#report' do
9
- expect(subject.parse('REPORT')).to eq(order: :report)
10
- end
11
-
12
- it '#move' do
13
- expect(subject.parse('MOVE')).to eq(order: :move)
14
- end
15
-
16
- it '#left' do
17
- expect(subject.parse('LEFT')).to eq(order: :left)
18
- end
19
-
20
- it '#right' do
21
- expect(subject.parse('RIGHT')).to eq(order: :right)
22
- end
23
-
24
- it '#place' do
25
- expect(subject.parse('PLACE 0,3,WEST')).to eq(order: :place, arguments: { x: '0', y: '3', face: 'WEST' })
26
- end
27
- end
28
-
29
- context 'orders with spaces and downcase' do
30
- it '#report' do
31
- expect(subject.parse(' repoRT')).to eq(order: :report)
32
- end
6
+ subject(:cli) { described_class.new }
33
7
 
34
- it '#move' do
35
- expect(subject.parse('move ')).to eq(order: :move)
36
- end
37
-
38
- it '#left' do
39
- expect(subject.parse(' LefT ')).to eq(order: :left)
40
- end
41
-
42
- it '#right' do
43
- expect(subject.parse(' rigHt')).to eq(order: :right)
44
- end
45
-
46
- it '#place' do
47
- expect(subject.parse('PLACE 2 , 1 , NOrth')).to eq(order: :place, arguments: { x: '2', y: '1', face: 'NOrth' })
48
- end
49
- end
50
-
51
- it 'ignores anything else' do
52
- expect(subject.parse('blablabla balbla')).to be_nil
53
- end
54
- end
8
+ describe "#execute" do
9
+ let(:position) { MauxRobot::Position.new(0, 2, :east) }
55
10
 
56
- describe '#execute' do
57
- context 'commands without arguments' do
58
- it 'sends proper message to robot' do
59
- expect(subject.robot).to receive(:move)
60
- subject.execute(order: :move)
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)
61
15
  end
62
16
  end
63
17
 
64
- context 'place' do
65
- it 'send place command along with arguments' do
66
- expect(subject.robot).to receive(:place).with(x: '0', y: '2', face: 'EAST')
67
- 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)
68
21
  end
69
22
  end
70
23
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe MauxRobot::Formatter::Csv do
4
+ let(:position) { MauxRobot::Position.new(1, 2, :west) }
5
+
6
+ describe "#generate" do
7
+ subject(:csv_formatter) { described_class.new }
8
+
9
+ it "Formats a position as CSV" do
10
+ expect(csv_formatter.generate(position)).to eq("1,2,WEST")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe MauxRobot::Formatter::Json do
4
+ let(:position) { MauxRobot::Position.new(1, 2, :west) }
5
+
6
+ describe "#generate" do
7
+ subject(:json_formatter) { described_class.new }
8
+
9
+ it "Formats a position as JSON" do
10
+ expect(json_formatter.generate(position)).to eq('{"x":1,"y":2,"face":"WEST"}')
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe MauxRobot::Formatter do
4
+ subject(:formatter) { described_class }
5
+
6
+ describe "#from" do
7
+ describe "valid format_types" do
8
+ it "returns csv formatter" do
9
+ expect(formatter.from(:csv).class).to eq(MauxRobot::Formatter::Csv)
10
+ end
11
+
12
+ it "returns json formatter" do
13
+ expect(formatter.from(:json).class).to eq(MauxRobot::Formatter::Json)
14
+ end
15
+ end
16
+
17
+ describe "invalid format_types" do
18
+ it "defaults to csv formatter" do
19
+ expect(formatter.from(:anything).class).to eq(MauxRobot::Formatter::Csv)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Metrics/BlockLength
4
+ describe MauxRobot::Parser do
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)
11
+ end
12
+
13
+ it "#report csv" do
14
+ expect(parser.parse("REPORT CSV")).to eq(order: :report, arguments: {format_type: :csv})
15
+ end
16
+
17
+ it "#report json" do
18
+ expect(parser.parse("REPORT JSON")).to eq(order: :report, arguments: {format_type: :json})
19
+ end
20
+
21
+ it "#move" do
22
+ expect(parser.parse("MOVE")).to eq(order: :move)
23
+ end
24
+
25
+ it "#left" do
26
+ expect(parser.parse("LEFT")).to eq(order: :left)
27
+ end
28
+
29
+ it "#right" do
30
+ expect(parser.parse("RIGHT")).to eq(order: :right)
31
+ end
32
+
33
+ it "#verbose" do
34
+ expect(parser.parse("VERBOSE")).to eq(order: :verbose)
35
+ end
36
+
37
+ it "#place" do
38
+ expect(parser.parse("PLACE 0,3,WEST")).to eq(order: :place, arguments: {x: "0", y: "3", face: "WEST"})
39
+ end
40
+ end
41
+
42
+ context "with orders with spaces and downcase" do
43
+ it "#report" do
44
+ expect(parser.parse(" repoRT")).to eq(order: :report)
45
+ end
46
+
47
+ it "#move" do
48
+ expect(parser.parse("move ")).to eq(order: :move)
49
+ end
50
+
51
+ it "#left" do
52
+ expect(parser.parse(" LefT ")).to eq(order: :left)
53
+ end
54
+
55
+ it "#right" do
56
+ expect(parser.parse(" rigHt")).to eq(order: :right)
57
+ end
58
+
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
+ )
63
+ end
64
+ end
65
+
66
+ context "with invalid orders" do
67
+ it "ignores anything else" do
68
+ expect(parser.parse("blablabla balbla")).to be_nil
69
+ end
70
+ end
71
+ end
72
+ end
73
+ # rubocop:enable Metrics/BlockLength
@@ -1,12 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'maux_robot'
4
-
3
+ # rubocop:disable Metrics/BlockLength:
5
4
  describe MauxRobot::Position do
6
- describe '#initialize' do
7
- context 'given text input' do
8
- it 'should normalize arguments' do
9
- position = MauxRobot::Position.new('0', '1', 'SOUTH')
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")
10
9
 
11
10
  expect(position.x).to eq(0)
12
11
  expect(position.y).to eq(1)
@@ -15,65 +14,65 @@ describe MauxRobot::Position do
15
14
  end
16
15
  end
17
16
 
18
- describe '#valid_direction?' do
19
- context 'given a possible diretion' do
20
- it 'should be valid' do
21
- position = MauxRobot::Position.new(5, 0, :south)
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)
22
21
 
23
22
  expect(position.valid_direction?).to eq(true)
24
23
  end
25
24
  end
26
25
 
27
- context 'given a not possible direction' do
28
- it 'should not be valid ' do
29
- position = MauxRobot::Position.new(1, 1, :south_west)
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)
30
29
 
31
30
  expect(position.valid_direction?).to eq(false)
32
31
  end
33
32
  end
34
33
  end
35
34
 
36
- describe 'rotation' do
37
- let(:position) { MauxRobot::Position.new(2, 2, :north) }
35
+ describe "rotation" do
36
+ let(:position) { described_class.new(2, 2, :north) }
38
37
 
39
- context '#turn_left' do
40
- it 'should rotate counter-clockwise' do
41
- position.turn_left
38
+ describe "#left" do
39
+ it "rotates counter-clockwise" do
40
+ position.left
42
41
  expect(position.face).to eq(:west)
43
42
 
44
- position.turn_left
43
+ position.left
45
44
  expect(position.face).to eq(:south)
46
45
 
47
- position.turn_left
46
+ position.left
48
47
  expect(position.face).to eq(:east)
49
48
 
50
- position.turn_left
49
+ position.left
51
50
  expect(position.face).to eq(:north)
52
51
  end
53
52
  end
54
53
 
55
- context '#turn_right' do
56
- it 'should rotate clockwise' do
57
- position.turn_right
54
+ describe "#right" do
55
+ it "rotates clockwise" do
56
+ position.right
58
57
  expect(position.face).to eq(:east)
59
58
 
60
- position.turn_right
59
+ position.right
61
60
  expect(position.face).to eq(:south)
62
61
 
63
- position.turn_right
62
+ position.right
64
63
  expect(position.face).to eq(:west)
65
64
 
66
- position.turn_right
65
+ position.right
67
66
  expect(position.face).to eq(:north)
68
67
  end
69
68
  end
70
69
  end
71
70
 
72
- describe '#forward_position' do
73
- context 'facing north' do
74
- let(:position) { MauxRobot::Position.new(5, 0, :north) }
71
+ describe "#forward_position" do # rubocop:disable Metrics/BlockLength
72
+ context "when facing north" do
73
+ let(:position) { described_class.new(5, 0, :north) }
75
74
 
76
- it 'should return a new position 1 step upwards' do
75
+ it "returns a new position 1 step upwards" do
77
76
  new_position = position.forward_position
78
77
  expect(position.x).to eq(5)
79
78
  expect(position.y).to eq(0)
@@ -82,10 +81,10 @@ describe MauxRobot::Position do
82
81
  end
83
82
  end
84
83
 
85
- context 'facing west' do
86
- let(:position) { MauxRobot::Position.new(2, 1, :west) }
84
+ context "when facing west" do
85
+ let(:position) { described_class.new(2, 1, :west) }
87
86
 
88
- it 'should return a new position 1 step leftwards' do
87
+ it "returns a new position 1 step leftwards" do
89
88
  new_position = position.forward_position
90
89
  expect(position.x).to eq(2)
91
90
  expect(position.y).to eq(1)
@@ -94,10 +93,10 @@ describe MauxRobot::Position do
94
93
  end
95
94
  end
96
95
 
97
- context 'facing south' do
98
- let(:position) { MauxRobot::Position.new(1, 3, :south) }
96
+ context "when facing south" do
97
+ let(:position) { described_class.new(1, 3, :south) }
99
98
 
100
- it 'should return a new position 1 step downwards' do
99
+ it "returns a new position 1 step downwards" do
101
100
  new_position = position.forward_position
102
101
  expect(position.x).to eq(1)
103
102
  expect(position.y).to eq(3)
@@ -106,10 +105,10 @@ describe MauxRobot::Position do
106
105
  end
107
106
  end
108
107
 
109
- context 'facing east' do
110
- let(:position) { MauxRobot::Position.new(2, 0, :east) }
108
+ context "when facing east" do
109
+ let(:position) { described_class.new(2, 0, :east) }
111
110
 
112
- it 'should return a new position 1 step rightwards' do
111
+ it "returns a new position 1 step rightwards" do
113
112
  new_position = position.forward_position
114
113
  expect(position.x).to eq(2)
115
114
  expect(position.y).to eq(0)
@@ -119,26 +118,30 @@ describe MauxRobot::Position do
119
118
  end
120
119
  end
121
120
 
122
- describe '#to_s' do
123
- context 'if x, y and face are defined' do
124
- let(:position) { MauxRobot::Position.new(5, 0, :north) }
125
- it 'returns X,Y,FACE' do
126
- expect(position.to_s).to eq('5,0,NORTH')
121
+ describe "#report" do
122
+ context "when x, y and face are defined" do
123
+ let(:position) { described_class.new(5, 0, :north) }
124
+
125
+ it "prints X,Y,FACE" do
126
+ expect { position.report }.to output("5,0,NORTH\n").to_stdout
127
127
  end
128
128
  end
129
129
 
130
- context 'if only face is defined' do
131
- let(:position) { MauxRobot::Position.new(nil, nil, 'SOUTH') }
132
- it 'returns 0,0,FACE' do
133
- expect(position.to_s).to eq('0,0,SOUTH')
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
134
+ expect { position.report }.to output("0,0,SOUTH\n").to_stdout
134
135
  end
135
136
  end
136
137
 
137
- context 'if face is not defined' do
138
- let(:position) { MauxRobot::Position.new(5, 0, nil) }
139
- it 'returns X,Y,INVALID' do
140
- expect(position.to_s).to eq('5,0,INVALID')
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
142
+ expect { position.report }.to output("5,0,INVALID\n").to_stdout
141
143
  end
142
144
  end
143
145
  end
144
146
  end
147
+ # rubocop:enable Metrics/BlockLength:
@@ -1,48 +1,42 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'maux_robot'
4
-
5
- describe MauxRobot::Robot do
3
+ describe MauxRobot::Robot do # rubocop:disable Metrics/BlockLength
6
4
  subject(:robot) { described_class.new }
7
5
 
8
- describe '#place' do
9
- context 'given a valid place' do
10
- it 'should have a position' do
6
+ let(:null_position) { MauxRobot::NullPosition.new }
7
+
8
+ describe "#place" do
9
+ context "when given a valid place" do
10
+ it "has a position" do
11
11
  robot.place(x: 0, y: 0, face: :north)
12
12
 
13
- expect(robot.position).not_to be_nil
13
+ expect(robot.position).not_to eq null_position
14
14
  end
15
15
  end
16
16
 
17
- context 'given an invalid place' do
18
- it 'should not have a position' do
19
- robot.place(x: 5, y: 0, face: :south)
20
-
21
- expect(robot.position).to be_nil
17
+ context "when given an invalid place" do
18
+ it "raises NotOkToGo error" do
19
+ expect { robot.place(x: 5, y: 0, face: :south) }.to raise_error MauxRobot::NotOkToGo
22
20
  end
23
21
  end
24
22
 
25
- context 'given an invalid direction' do
26
- it 'should not have a position' do
27
- robot.place(x: 0, y: 2, face: :south_east)
28
-
29
- expect(robot.position).to be_nil
23
+ context "when given an invalid direction" do
24
+ it "raises NotOkToGo error" do
25
+ expect { robot.place(x: 0, y: 2, face: :south_east) }.to raise_error MauxRobot::NotOkToGo
30
26
  end
31
27
  end
32
28
  end
33
29
 
34
- describe '#left' do
35
- context 'robot not placed' do
36
- it 'should silently ignore' do
37
- robot.place(x: 0, y: 2, face: :south_east)
38
- robot.left
39
-
40
- expect(robot.position).to be_nil
30
+ describe "#left" do
31
+ context "when robot is not placed" do
32
+ it "raises RobotNotPlacedYet error" do
33
+ expect { robot.left }.to raise_error MauxRobot::RobotNotPlacedYet
34
+ expect(robot.position).to eq null_position
41
35
  end
42
36
  end
43
37
 
44
- context 'robot placed' do
45
- it 'should rotate accordingly' do
38
+ context "when robot is placed" do
39
+ it "rotates accordingly" do
46
40
  robot.place(x: 1, y: 2, face: :south)
47
41
  robot.left
48
42
 
@@ -51,18 +45,17 @@ describe MauxRobot::Robot do
51
45
  end
52
46
  end
53
47
 
54
- describe '#right' do
55
- context 'robot not placed' do
56
- it 'should silently ignore' do
57
- robot.place(x: 0, y: 2, face: :north_west)
58
- robot.right
48
+ describe "#right" do
49
+ context "when robot is not placed" do
50
+ it "raises RobotNotPlacedYet error" do
51
+ expect { robot.right }.to raise_error MauxRobot::RobotNotPlacedYet
59
52
 
60
- expect(robot.position).to be_nil
53
+ expect(robot.position).to eq null_position
61
54
  end
62
55
  end
63
56
 
64
- context 'robot placed' do
65
- it 'should rotate accordingly' do
57
+ context "with robot placed" do
58
+ it "rotates accordingly" do
66
59
  robot.place(x: 3, y: 2, face: :north)
67
60
  robot.right
68
61
 
@@ -71,9 +64,16 @@ describe MauxRobot::Robot do
71
64
  end
72
65
  end
73
66
 
74
- describe '#move' do
75
- context 'to a place on the table' do
76
- it 'should update its position' do
67
+ describe "#move" do
68
+ context "with robot not placed" do
69
+ it "raises RobotNotPlacedYet error" do
70
+ expect { robot.right }.to raise_error MauxRobot::RobotNotPlacedYet
71
+ expect(robot.position).to eq null_position
72
+ end
73
+ end
74
+
75
+ context "when placing on the table" do
76
+ it "updates its position" do
77
77
  robot.place(x: 3, y: 2, face: :north)
78
78
  robot.move
79
79
 
@@ -83,10 +83,11 @@ describe MauxRobot::Robot do
83
83
  end
84
84
  end
85
85
 
86
- context 'to outside the table' do
87
- it 'should stay where it is' do
86
+ context "when outside the table" do
87
+ it "stays where it is" do
88
88
  robot.place(x: 0, y: 0, face: :south)
89
- robot.move
89
+
90
+ expect { robot.move }.to raise_error MauxRobot::NotOkToGo
90
91
 
91
92
  expect(robot.position.x).to eq(0)
92
93
  expect(robot.position.y).to eq(0)
@@ -1,17 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'maux_robot'
4
-
5
3
  describe MauxRobot::Table do
6
4
  subject(:table) { described_class.new(x: [-1, 2], y: [3, 6]) }
7
5
 
8
- context '#contains?' do
9
- it 'should contain a position inside boundaries' do
6
+ describe "#contains?" do
7
+ it "contains a position inside boundaries" do
10
8
  position = MauxRobot::Position.new(0, 4, :north)
11
9
  expect(table.contains?(position)).to be true
12
10
  end
13
11
 
14
- it 'should not contain a position outside boundaries' do
12
+ it "does not contain a position outside boundaries" do
15
13
  position = MauxRobot::Position.new(3, 2, :east)
16
14
  expect(table.contains?(position)).to be false
17
15
  end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift("#{__dir__}/../lib")
4
+
5
+ require "maux_robot"
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.0.3
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mauricio Vieira
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-19 00:00:00.000000000 Z
11
+ date: 2020-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rspec
14
+ name: standard
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '3.6'
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: '3.6'
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:
@@ -44,14 +38,24 @@ files:
44
38
  - bin/maux_robot
45
39
  - lib/maux_robot.rb
46
40
  - lib/maux_robot/cli.rb
41
+ - lib/maux_robot/formatter.rb
42
+ - lib/maux_robot/formatter/csv.rb
43
+ - lib/maux_robot/formatter/json.rb
44
+ - lib/maux_robot/parser.rb
47
45
  - lib/maux_robot/position.rb
48
46
  - lib/maux_robot/robot.rb
49
47
  - lib/maux_robot/table.rb
50
48
  - lib/maux_robot/version.rb
49
+ - lib/tasks/ci.rake
51
50
  - spec/maux_robot/cli_spec.rb
51
+ - spec/maux_robot/formatter/csv_spec.rb
52
+ - spec/maux_robot/formatter/json_spec.rb
53
+ - spec/maux_robot/formatter_spec.rb
54
+ - spec/maux_robot/parser_spec.rb
52
55
  - spec/maux_robot/position_spec.rb
53
56
  - spec/maux_robot/robot_spec.rb
54
57
  - spec/maux_robot/table_spec.rb
58
+ - spec/spec_helper.rb
55
59
  homepage: https://github.com/mauriciovieira/maux_robot
56
60
  licenses:
57
61
  - GPL-3.0
@@ -69,15 +73,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
69
73
  requirements:
70
74
  - - ">="
71
75
  - !ruby/object:Gem::Version
72
- version: 2.0.0
76
+ version: 2.6.0
73
77
  required_rubygems_version: !ruby/object:Gem::Requirement
74
78
  requirements:
75
79
  - - ">="
76
80
  - !ruby/object:Gem::Version
77
81
  version: '0'
78
82
  requirements: []
79
- rubyforge_project:
80
- rubygems_version: 2.6.12
83
+ rubygems_version: 3.0.3
81
84
  signing_key:
82
85
  specification_version: 4
83
86
  summary: Maux version of a Toy Robot Simulator.