gobstones 0.0.1.1
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 +7 -0
- data/.gitignore +6 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/.simplecov +3 -0
- data/.travis.yml +4 -0
- data/CHANGELOG +4 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +47 -0
- data/LICENSE +675 -0
- data/README.md +17 -0
- data/Rakefile +4 -0
- data/bin/gobstones +12 -0
- data/gobstones.gemspec +24 -0
- data/lib/gobstones/cli/board_template +39 -0
- data/lib/gobstones/cli/printer.rb +106 -0
- data/lib/gobstones/cli/runner.rb +52 -0
- data/lib/gobstones/extensions/all.rb +2 -0
- data/lib/gobstones/extensions/boolean.rb +17 -0
- data/lib/gobstones/extensions/fixnum.rb +9 -0
- data/lib/gobstones/lang/all.rb +5 -0
- data/lib/gobstones/lang/commands/all.rb +13 -0
- data/lib/gobstones/lang/commands/assignments.rb +29 -0
- data/lib/gobstones/lang/commands/boom_cmd.rb +28 -0
- data/lib/gobstones/lang/commands/command_block.rb +37 -0
- data/lib/gobstones/lang/commands/conditional_cmd.rb +27 -0
- data/lib/gobstones/lang/commands/if_cmd.rb +38 -0
- data/lib/gobstones/lang/commands/ir_al_origen_cmd.rb +19 -0
- data/lib/gobstones/lang/commands/mover_cmd.rb +25 -0
- data/lib/gobstones/lang/commands/poner_cmd.rb +31 -0
- data/lib/gobstones/lang/commands/procedure_call.rb +23 -0
- data/lib/gobstones/lang/commands/repeat_with_cmd.rb +73 -0
- data/lib/gobstones/lang/commands/sacar_cmd.rb +31 -0
- data/lib/gobstones/lang/commands/skip_cmd.rb +19 -0
- data/lib/gobstones/lang/commands/vaciar_tablero_cmd.rb +19 -0
- data/lib/gobstones/lang/commands/while_cmd.rb +25 -0
- data/lib/gobstones/lang/definitions/all.rb +4 -0
- data/lib/gobstones/lang/definitions/definition.rb +32 -0
- data/lib/gobstones/lang/definitions/definition_call.rb +24 -0
- data/lib/gobstones/lang/definitions/function.rb +14 -0
- data/lib/gobstones/lang/definitions/main.rb +26 -0
- data/lib/gobstones/lang/definitions/no_return_statement.rb +15 -0
- data/lib/gobstones/lang/definitions/procedure.rb +44 -0
- data/lib/gobstones/lang/definitions/return_from_function.rb +22 -0
- data/lib/gobstones/lang/definitions/return_from_main.rb +22 -0
- data/lib/gobstones/lang/definitions/var_tuple.rb +26 -0
- data/lib/gobstones/lang/expressions/all.rb +8 -0
- data/lib/gobstones/lang/expressions/arithmetic_expressions.rb +52 -0
- data/lib/gobstones/lang/expressions/boolean_expressions.rb +29 -0
- data/lib/gobstones/lang/expressions/comparison_expressions.rb +45 -0
- data/lib/gobstones/lang/expressions/function_call.rb +15 -0
- data/lib/gobstones/lang/expressions/one_arg_expression.rb +21 -0
- data/lib/gobstones/lang/expressions/parentheses_expression.rb +13 -0
- data/lib/gobstones/lang/expressions/primitive_functions.rb +68 -0
- data/lib/gobstones/lang/expressions/two_arg_expression.rb +34 -0
- data/lib/gobstones/lang/expressions/type_bound_functions.rb +66 -0
- data/lib/gobstones/lang/expressions/var_name.rb +31 -0
- data/lib/gobstones/lang/literals/all.rb +4 -0
- data/lib/gobstones/lang/literals/booleans.rb +109 -0
- data/lib/gobstones/lang/literals/colors.rb +94 -0
- data/lib/gobstones/lang/literals/directions.rb +137 -0
- data/lib/gobstones/lang/literals/literal.rb +63 -0
- data/lib/gobstones/lang/literals/number.rb +49 -0
- data/lib/gobstones/lang/program.rb +32 -0
- data/lib/gobstones/modules/equal_by_class.rb +13 -0
- data/lib/gobstones/parser/ast/ast.rb +210 -0
- data/lib/gobstones/parser/grammar/gobstones.treetop +316 -0
- data/lib/gobstones/parser/parse_error.rb +17 -0
- data/lib/gobstones/parser/treetop_parser.rb +73 -0
- data/lib/gobstones/runner/all.rb +6 -0
- data/lib/gobstones/runner/board.rb +57 -0
- data/lib/gobstones/runner/cell.rb +60 -0
- data/lib/gobstones/runner/errors/all.rb +8 -0
- data/lib/gobstones/runner/errors/boom_error.rb +11 -0
- data/lib/gobstones/runner/errors/definition_not_found_error.rb +19 -0
- data/lib/gobstones/runner/errors/empty_cell_error.rb +11 -0
- data/lib/gobstones/runner/errors/gobstones_runtime_error.rb +11 -0
- data/lib/gobstones/runner/errors/gobstones_type_error.rb +11 -0
- data/lib/gobstones/runner/errors/out_of_board_error.rb +11 -0
- data/lib/gobstones/runner/errors/undefined_variable_error.rb +11 -0
- data/lib/gobstones/runner/errors/wrong_arguments_error.rb +11 -0
- data/lib/gobstones/runner/execution_context.rb +89 -0
- data/lib/gobstones/runner/head.rb +101 -0
- data/lib/gobstones/type_check_result.rb +16 -0
- data/spec/lang/commands/assignments_spec.rb +13 -0
- data/spec/lang/commands/boom_cmd_spec.rb +8 -0
- data/spec/lang/commands/cmd_block_spec.rb +21 -0
- data/spec/lang/commands/if_cmd_spec.rb +49 -0
- data/spec/lang/commands/ir_al_origen_cmd_spec.rb +16 -0
- data/spec/lang/commands/mover_cmd_spec.rb +38 -0
- data/spec/lang/commands/poner_cmd_spec.rb +29 -0
- data/spec/lang/commands/procedure_call_spec.rb +44 -0
- data/spec/lang/commands/procedure_spec.rb +67 -0
- data/spec/lang/commands/repeat_with_cmd_spec.rb +41 -0
- data/spec/lang/commands/sacar_cmd_spec.rb +34 -0
- data/spec/lang/commands/skip_cmd_spec.rb +12 -0
- data/spec/lang/commands/vaciar_tablero_cmd_spec.rb +13 -0
- data/spec/lang/commands/while_cmd_spec.rb +37 -0
- data/spec/lang/expressions/arithmetic_expressions_spec.rb +108 -0
- data/spec/lang/expressions/boolean_expressions_spec.rb +56 -0
- data/spec/lang/expressions/comparison_expressions_spec.rb +285 -0
- data/spec/lang/expressions/primitive_functions_spec.rb +126 -0
- data/spec/lang/expressions/type_bound_functions_spec.rb +39 -0
- data/spec/lang/expressions/var_name_spec.rb +16 -0
- data/spec/lang/literals/booleans_spec.rb +13 -0
- data/spec/lang/literals/colors_spec.rb +13 -0
- data/spec/lang/literals/directions_spec.rb +45 -0
- data/spec/lang/literals/numbers_spec.rb +8 -0
- data/spec/matchers/parse_matcher.rb +84 -0
- data/spec/parser/arithmetic_expressions_spec.rb +129 -0
- data/spec/parser/assignments_spec.rb +39 -0
- data/spec/parser/boolean_expressions_spec.rb +111 -0
- data/spec/parser/command_block_spec.rb +50 -0
- data/spec/parser/data_types_spec.rb +67 -0
- data/spec/parser/function_calls_spec.rb +37 -0
- data/spec/parser/function_definitions_spec.rb +50 -0
- data/spec/parser/gobstones_program_spec.rb +55 -0
- data/spec/parser/if_command_spec.rb +46 -0
- data/spec/parser/main_definition_spec.rb +42 -0
- data/spec/parser/nested_expressions_spec.rb +39 -0
- data/spec/parser/primitive_expressions_spec.rb +105 -0
- data/spec/parser/procedure_calls_spec.rb +36 -0
- data/spec/parser/procedure_definitions_spec.rb +39 -0
- data/spec/parser/repeat_with_command_spec.rb +23 -0
- data/spec/parser/simple_commands_spec.rb +62 -0
- data/spec/parser/treetop_parser_spec.rb +109 -0
- data/spec/parser/var_tuple_spec.rb +30 -0
- data/spec/parser/while_command_spec.rb +30 -0
- data/spec/runner/board_spec.rb +85 -0
- data/spec/runner/cell_spec.rb +72 -0
- data/spec/runner/execution_context_spec.rb +64 -0
- data/spec/runner/head_spec.rb +139 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/type_checker_spec.rb +37 -0
- metadata +242 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
describe Gobstones::Parser, "var tuples" do
|
2
|
+
|
3
|
+
it "should parse an empty var tuple" do
|
4
|
+
var_tuple = VarTuple.new []
|
5
|
+
|
6
|
+
expect('()').to be_parsed_as(:var_tuple).and_return(var_tuple)
|
7
|
+
expect('( )').to be_parsed_as(:var_tuple).and_return(var_tuple)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should parse a var tuple with one arg" do
|
11
|
+
var = VarName.new 'myVar'
|
12
|
+
var_tuple = VarTuple.new [var]
|
13
|
+
|
14
|
+
expect('(myVar)').to be_parsed_as(:var_tuple).and_return(var_tuple)
|
15
|
+
expect('( myVar )').to be_parsed_as(:var_tuple).and_return(var_tuple)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should parse a var tuple with many args" do
|
19
|
+
first = VarName.new 'firstVar'
|
20
|
+
second = VarName.new 'secondVar'
|
21
|
+
third = VarName.new 'thirdVar'
|
22
|
+
var_tuple = VarTuple.new [first, second, third]
|
23
|
+
|
24
|
+
expect('(firstVar, secondVar, thirdVar)').
|
25
|
+
to be_parsed_as(:var_tuple).and_return(var_tuple)
|
26
|
+
expect('( firstVar , secondVar,thirdVar )').
|
27
|
+
to be_parsed_as(:var_tuple).and_return(var_tuple)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
describe Gobstones::Parser, "while statements" do
|
2
|
+
|
3
|
+
it "should parse a statement with a simple boolean and an empty block" do
|
4
|
+
while_cmd = WhileCmd.new True.new, CmdBlock.empty
|
5
|
+
|
6
|
+
expect('while (True) {}').to be_parsed_as(:command).and_return(while_cmd)
|
7
|
+
expect('while (True) {
|
8
|
+
}').to be_parsed_as(:command).and_return(while_cmd)
|
9
|
+
expect('while (True)
|
10
|
+
{}').to be_parsed_as(:command).and_return(while_cmd)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should parse a statement with a simple boolean and a block with commands" do
|
14
|
+
cmd_block = CmdBlock.new [Poner.new(Verde.new), Skip.new]
|
15
|
+
while_cmd = WhileCmd.new False.new, cmd_block
|
16
|
+
|
17
|
+
expect('while(False){Poner(Verde); Skip}').
|
18
|
+
to be_parsed_as(:command).and_return(while_cmd)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should parse a statement with a complex boolean expression" do
|
22
|
+
and_expr = And.new VarName.new('a'), False.new
|
23
|
+
exp = Or.new PuedeMover.new(Norte.new), ParenthesesExpr.new(and_expr)
|
24
|
+
while_cmd = WhileCmd.new exp, CmdBlock.empty
|
25
|
+
|
26
|
+
expect('while (puedeMover(Norte) || (a && False)) {}').
|
27
|
+
to be_parsed_as(:command).and_return(while_cmd)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
describe Board do
|
2
|
+
|
3
|
+
let(:black) { Negro.new }
|
4
|
+
let(:blue) { Azul.new }
|
5
|
+
let(:green) { Verde.new }
|
6
|
+
let(:red) { Rojo.new }
|
7
|
+
let(:colors) { [blue, black, red, green] }
|
8
|
+
|
9
|
+
it "can be created with a number of rows and columns" do
|
10
|
+
board = Board.new 8, 5
|
11
|
+
expect(board.rows).to eq(8)
|
12
|
+
expect(board.columns).to eq(5)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should have cells in every position" do
|
16
|
+
board = Board.new 3, 3
|
17
|
+
|
18
|
+
board.each_cell { |cell| expect(cell).to be_a(Cell) }
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should access cells in a x&y dimension" do
|
22
|
+
board = Board.new 3, 5
|
23
|
+
|
24
|
+
3.times do |x|
|
25
|
+
5.times do |y|
|
26
|
+
expect(board.cell_at(x, y)).to be
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should raise errors if it is accessed out of the bounds" do
|
32
|
+
board = Board.new 9, 6
|
33
|
+
|
34
|
+
expect { board.cell_at(9, 4) }.to raise_error(OutOfBoardError)
|
35
|
+
expect { board.cell_at(3, 6) }.to raise_error(OutOfBoardError)
|
36
|
+
expect { board.cell_at(-1, 2) }.to raise_error(OutOfBoardError)
|
37
|
+
expect { board.cell_at(8, -1) }.to raise_error(OutOfBoardError)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should put balls in a given position" do
|
41
|
+
board = Board.new 5, 5
|
42
|
+
|
43
|
+
2.times { board.put 0, 0, blue }
|
44
|
+
10.times { board.put 2, 3, red }
|
45
|
+
|
46
|
+
expect(board.are_there_balls?(0, 0, blue)).to be_true
|
47
|
+
expect(board.number_of_balls(0, 0, blue)).to eq(2)
|
48
|
+
expect(board.are_there_balls?(2, 3, red)).to be_true
|
49
|
+
expect(board.number_of_balls(2, 3, red)).to eq(10)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should put and take out balls in a given position" do
|
53
|
+
board = Board.new 2, 2
|
54
|
+
|
55
|
+
3.times { board.put 1, 1, green }
|
56
|
+
3.times { board.take_out 1, 1, green }
|
57
|
+
|
58
|
+
expect(board.are_there_balls?(1, 1, green)).to be_false
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should empty the entire board" do
|
62
|
+
board = Board.new 3, 4
|
63
|
+
board.each_cell { |cell| cell.put colors.sample }
|
64
|
+
|
65
|
+
board.empty!
|
66
|
+
|
67
|
+
board.each_cell do |cell|
|
68
|
+
colors.each do |color|
|
69
|
+
expect(cell.are_there_balls?(color)).to be_false
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should be empty if there are no balls" do
|
75
|
+
board = Board.new 3, 4
|
76
|
+
expect(board.empty?).to be_true
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should not be empty if there are balls" do
|
80
|
+
board = Board.new 3, 4
|
81
|
+
board.put 0, 0, black
|
82
|
+
expect(board.empty?).to be_false
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
describe Cell do
|
2
|
+
|
3
|
+
let(:black) { Negro.new }
|
4
|
+
let(:blue) { Azul.new }
|
5
|
+
let(:green) { Verde.new }
|
6
|
+
let(:red) { Rojo.new }
|
7
|
+
let(:colors) { [blue, black, red, green] }
|
8
|
+
let(:cell) { Cell.new }
|
9
|
+
|
10
|
+
it "should answer that there are no balls of a given color" do
|
11
|
+
expect(cell.are_there_balls?(blue)).to be_false
|
12
|
+
expect(cell.are_there_balls?(black)).to be_false
|
13
|
+
expect(cell.are_there_balls?(red)).to be_false
|
14
|
+
expect(cell.are_there_balls?(green)).to be_false
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should answer that there are balls of a given color when adding some" do
|
18
|
+
cell.put blue
|
19
|
+
cell.put red
|
20
|
+
|
21
|
+
expect(cell.are_there_balls?(blue)).to be_true
|
22
|
+
expect(cell.are_there_balls?(black)).to be_false
|
23
|
+
expect(cell.are_there_balls?(red)).to be_true
|
24
|
+
expect(cell.are_there_balls?(green)).to be_false
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should answer the number of balls of a given color" do
|
28
|
+
5.times { cell.put green }
|
29
|
+
|
30
|
+
expect(cell.number_of_balls(blue)).to eq(0)
|
31
|
+
expect(cell.number_of_balls(black)).to eq(0)
|
32
|
+
expect(cell.number_of_balls(red)).to eq(0)
|
33
|
+
expect(cell.number_of_balls(green)).to eq(5)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should allow to take out some balls" do
|
37
|
+
5.times { cell.put blue }
|
38
|
+
3.times { cell.take_out blue }
|
39
|
+
|
40
|
+
expect(cell.are_there_balls?(blue)).to be_true
|
41
|
+
expect(cell.number_of_balls(blue)).to eq(2)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should raise an error if it's not possible to take out balls" do
|
45
|
+
expect { cell.take_out red }.to raise_error(EmptyCellError)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should fail passing something that is not a color" do
|
49
|
+
expect { cell.put("not a color") }.to raise_error
|
50
|
+
expect { cell.take_out(42) }.to raise_error
|
51
|
+
expect { cell.are_there_balls?(Norte) }.to raise_error
|
52
|
+
expect { cell.number_of_balls(nil) }.to raise_error
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should empty its contents" do
|
56
|
+
colors.each { |color| cell.put color }
|
57
|
+
|
58
|
+
cell.empty!
|
59
|
+
|
60
|
+
colors.each { |color| expect(cell.are_there_balls?(color)).to be_false }
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should be empty if it doesn't have any balls" do
|
64
|
+
expect(cell.empty?).to be_true
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should not be empty it it has some balls" do
|
68
|
+
colors.each { |color| cell.put color }
|
69
|
+
expect(cell.empty?).to be_false
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
describe ExecutionContext do
|
2
|
+
|
3
|
+
let(:context) { ExecutionContext.new }
|
4
|
+
|
5
|
+
describe "variables context" do
|
6
|
+
|
7
|
+
let(:negro) { Negro.new }
|
8
|
+
let(:norte) { Norte.new }
|
9
|
+
|
10
|
+
it "should allow to set & get a variable" do
|
11
|
+
context.set 'myColor', negro
|
12
|
+
|
13
|
+
expect(context.get('myColor')).to eq(negro)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should allow to set/get more than one variable" do
|
17
|
+
context.set 'dir', norte
|
18
|
+
context.set 'bool', true.to_gbs_bool
|
19
|
+
|
20
|
+
expect(context.get('dir')).to eq(norte)
|
21
|
+
expect(context.get('bool')).to eq(true.to_gbs_bool)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should raise an error when getting an undefined variable" do
|
25
|
+
expect {
|
26
|
+
context.get('undefined')
|
27
|
+
}.to raise_error(UndefinedVariableError)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
describe ProgramExecutionContext do
|
33
|
+
|
34
|
+
let(:context) { ProgramExecutionContext.for program }
|
35
|
+
let(:program) { Program.new [], nil }
|
36
|
+
|
37
|
+
it "should return self as program_context" do
|
38
|
+
expect(context.program_context).to eq(context)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should have a head" do
|
42
|
+
expect(context.head).to be_a Head
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should have a board" do
|
46
|
+
expect(context.board).to be_a Board
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
describe ProcedureExecutionContext do
|
52
|
+
|
53
|
+
it "should return the program_context in which it is based" do
|
54
|
+
program = Program.new [], nil
|
55
|
+
program_context = ProgramExecutionContext.for program
|
56
|
+
procedure_context = ProcedureExecutionContext.based_on program_context
|
57
|
+
|
58
|
+
expect(procedure_context.program_context).to eq(program_context)
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
@@ -0,0 +1,139 @@
|
|
1
|
+
describe Head do
|
2
|
+
|
3
|
+
it "should have a position, default 0;0" do
|
4
|
+
head = Head.new
|
5
|
+
|
6
|
+
expect(head.x_pos).to eq(0)
|
7
|
+
expect(head.y_pos).to eq(0)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should answer the max size" do
|
11
|
+
expect(Head::MAX_ROWS).to eq(9)
|
12
|
+
expect(Head::MAX_COLS).to eq(9)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should allow to be created at a random position" do
|
16
|
+
head = Head.at_random
|
17
|
+
|
18
|
+
100.times { expect(head.x_pos.between?(0, Head::MAX_ROWS-1)).to be_true }
|
19
|
+
100.times { expect(head.y_pos.between?(0, Head::MAX_COLS-1)).to be_true }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "movements" do
|
23
|
+
|
24
|
+
let(:head) { Head.new }
|
25
|
+
let(:north) { Norte.new }
|
26
|
+
let(:south) { Sur.new }
|
27
|
+
let(:east) { Este.new }
|
28
|
+
let(:west) { Oeste.new }
|
29
|
+
|
30
|
+
context "valid" do
|
31
|
+
|
32
|
+
it "should move north" do
|
33
|
+
expect(head.can_move?(north)).to be_true
|
34
|
+
expect { head.move(north) }.to_not raise_error
|
35
|
+
expect(head.x_pos).to eq(0)
|
36
|
+
expect(head.y_pos).to eq(1)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should move south" do
|
40
|
+
head.move north
|
41
|
+
expect(head.can_move?(south)).to be_true
|
42
|
+
expect { head.move(south) }.to_not raise_error
|
43
|
+
expect(head.x_pos).to eq(0)
|
44
|
+
expect(head.y_pos).to eq(0)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should move east" do
|
48
|
+
expect(head.can_move?(east)).to be_true
|
49
|
+
expect { head.move(east) }.to_not raise_error
|
50
|
+
expect(head.x_pos).to eq(1)
|
51
|
+
expect(head.y_pos).to eq(0)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should move west" do
|
55
|
+
head.move east
|
56
|
+
expect(head.can_move?(west)).to be_true
|
57
|
+
expect { head.move(west) }.to_not raise_error
|
58
|
+
expect(head.x_pos).to eq(0)
|
59
|
+
expect(head.y_pos).to eq(0)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should go to the origin" do
|
63
|
+
head.move east
|
64
|
+
head.move north
|
65
|
+
head.go_to_origin
|
66
|
+
expect(head.x_pos).to eq(0)
|
67
|
+
expect(head.y_pos).to eq(0)
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
context "non valid" do
|
73
|
+
|
74
|
+
it "should fail moving north" do
|
75
|
+
(Head::MAX_COLS-1).times { head.move north }
|
76
|
+
|
77
|
+
expect(head.can_move?(north)).to be_false
|
78
|
+
expect { head.move north }.to raise_error(OutOfBoardError)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should fail moving south" do
|
82
|
+
expect(head.can_move?(south)).to be_false
|
83
|
+
expect { head.move south }.to raise_error(OutOfBoardError)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should fail moving east" do
|
87
|
+
(Head::MAX_ROWS-1).times { head.move east }
|
88
|
+
|
89
|
+
expect(head.can_move?(east)).to be_false
|
90
|
+
expect { head.move east }.to raise_error(OutOfBoardError)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should fail moving west" do
|
94
|
+
expect(head.can_move?(west)).to be_false
|
95
|
+
expect { head.move west }.to raise_error(OutOfBoardError)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should fail if the argument is not a direction" do
|
99
|
+
expect { head.move Azul.new }.
|
100
|
+
to raise_error(GobstonesTypeError, /is not a direction/)
|
101
|
+
expect { head.move "not a direction" }.
|
102
|
+
to raise_error(GobstonesTypeError, /is not a direction/)
|
103
|
+
expect { head.move True.new }.
|
104
|
+
to raise_error(GobstonesTypeError, /is not a direction/)
|
105
|
+
expect { head.move 42 }.
|
106
|
+
to raise_error(GobstonesTypeError, /is not a direction/)
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "board actions" do
|
114
|
+
|
115
|
+
let(:head) { Head.new }
|
116
|
+
let(:black) { Negro.new }
|
117
|
+
|
118
|
+
it "should put balls across the board" do
|
119
|
+
3.times { head.put black }
|
120
|
+
expect(head.are_there_balls?(black)).to be_true
|
121
|
+
expect(head.number_of_balls(black)).to eq(3)
|
122
|
+
head.move Norte.new
|
123
|
+
2.times { head.put black }
|
124
|
+
expect(head.number_of_balls(black)).to eq(2)
|
125
|
+
head.move Este.new
|
126
|
+
5.times { head.put black }
|
127
|
+
expect(head.number_of_balls(black)).to eq(5)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should take out balls across the board" do
|
131
|
+
4.times { head.put black }
|
132
|
+
4.times { head.take_out black }
|
133
|
+
|
134
|
+
expect(head.are_there_balls?(black)).to be_false
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'coveralls'
|
2
|
+
Coveralls.wear!
|
3
|
+
|
4
|
+
require 'simplecov'
|
5
|
+
|
6
|
+
require 'matchers/parse_matcher'
|
7
|
+
|
8
|
+
require 'gobstones/extensions/all'
|
9
|
+
require 'gobstones/lang/all'
|
10
|
+
require 'gobstones/runner/all'
|
11
|
+
require 'gobstones/parser/treetop_parser'
|
12
|
+
|
13
|
+
include Gobstones::Lang
|
14
|
+
include Gobstones::Runner
|
15
|
+
include Gobstones::Parser
|
@@ -0,0 +1,37 @@
|
|
1
|
+
describe Gobstones, "type checker" do
|
2
|
+
|
3
|
+
describe "board expressions" do
|
4
|
+
|
5
|
+
describe "puedeMover()" do
|
6
|
+
|
7
|
+
it "should allow a direction as argument" do
|
8
|
+
[Norte.new, Sur.new, Este.new, Oeste.new].each do |dir|
|
9
|
+
puede_mover_dir = PuedeMover.new dir
|
10
|
+
result = puede_mover_dir.type_check
|
11
|
+
expect(result.ok?).to be_true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should not allow a number as argument" do
|
16
|
+
puede_mover_number = PuedeMover.new Number.new(42)
|
17
|
+
result = puede_mover_number.type_check
|
18
|
+
expect(result.ok?).to be_false
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should not allow a color as argument" do
|
22
|
+
puede_mover_color = PuedeMover.new Verde.new
|
23
|
+
result = puede_mover_color.type_check
|
24
|
+
expect(result.ok?).to be_false
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should not allow a boolean as argument" do
|
28
|
+
puede_mover_bool = PuedeMover.new True.new
|
29
|
+
result = puede_mover_bool.type_check
|
30
|
+
expect(result.ok?).to be_false
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|