gobstones 0.0.1.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -3
- data/.ruby-version +1 -1
- data/.travis.yml +1 -1
- data/CHANGELOG +22 -2
- data/Gemfile +3 -3
- data/Gemfile.lock +32 -27
- data/bin/gobstones +1 -1
- data/examples/.gitkeep +0 -0
- data/gobstones.gemspec +2 -2
- data/lib/gobstones/cli/board_template +1 -1
- data/lib/gobstones/cli/printer.rb +1 -1
- data/lib/gobstones/cli/runner.rb +8 -2
- data/lib/gobstones/extensions/all.rb +2 -1
- data/lib/gobstones/extensions/boolean.rb +1 -1
- data/lib/gobstones/extensions/fixnum.rb +1 -1
- data/lib/gobstones/extensions/string.rb +9 -0
- data/lib/gobstones/lang/all.rb +1 -1
- data/lib/gobstones/lang/commands/all.rb +3 -2
- data/lib/gobstones/lang/commands/boom_cmd.rb +6 -3
- data/lib/gobstones/lang/commands/command_block.rb +1 -1
- data/lib/gobstones/lang/commands/conditional_cmd.rb +5 -1
- data/lib/gobstones/lang/commands/ir_al_origen_cmd.rb +1 -1
- data/lib/gobstones/lang/commands/mover_cmd.rb +4 -2
- data/lib/gobstones/lang/commands/multiple_assignment.rb +35 -0
- data/lib/gobstones/lang/commands/poner_cmd.rb +8 -4
- data/lib/gobstones/lang/commands/procedure_call.rb +1 -9
- data/lib/gobstones/lang/commands/repeat_with_cmd.rb +10 -6
- data/lib/gobstones/lang/commands/sacar_cmd.rb +9 -7
- data/lib/gobstones/lang/commands/{assignments.rb → single_assignment.rb} +5 -3
- data/lib/gobstones/lang/commands/skip_cmd.rb +2 -2
- data/lib/gobstones/lang/commands/vaciar_tablero_cmd.rb +1 -1
- data/lib/gobstones/lang/commands/while_cmd.rb +1 -1
- data/lib/gobstones/lang/definitions/all.rb +1 -1
- data/lib/gobstones/lang/definitions/definition.rb +47 -5
- data/lib/gobstones/lang/definitions/definition_call.rb +17 -5
- data/lib/gobstones/lang/definitions/function.rb +9 -0
- data/lib/gobstones/lang/definitions/main.rb +1 -1
- data/lib/gobstones/lang/definitions/no_return_statement.rb +7 -3
- data/lib/gobstones/lang/definitions/procedure.rb +5 -20
- data/lib/gobstones/lang/definitions/return_from_function.rb +12 -2
- data/lib/gobstones/lang/definitions/return_from_main.rb +5 -1
- data/lib/gobstones/lang/definitions/var_tuple.rb +13 -1
- data/lib/gobstones/lang/expressions/all.rb +1 -1
- data/lib/gobstones/lang/expressions/arithmetic_expressions.rb +1 -1
- data/lib/gobstones/lang/expressions/boolean_expressions.rb +3 -2
- data/lib/gobstones/lang/expressions/enclosed_by_parens_expression.rb +17 -0
- data/lib/gobstones/lang/expressions/function_call.rb +1 -1
- data/lib/gobstones/lang/expressions/one_arg_expression.rb +16 -4
- data/lib/gobstones/lang/expressions/primitive_functions.rb +18 -12
- data/lib/gobstones/lang/expressions/two_arg_expression.rb +7 -3
- data/lib/gobstones/lang/expressions/type_bound_functions.rb +1 -1
- data/lib/gobstones/lang/expressions/var_name.rb +9 -3
- data/lib/gobstones/lang/literals/all.rb +1 -1
- data/lib/gobstones/lang/literals/colors.rb +1 -1
- data/lib/gobstones/lang/literals/literal.rb +31 -21
- data/lib/gobstones/lang/literals/number.rb +1 -1
- data/lib/gobstones/lang/program.rb +13 -4
- data/lib/gobstones/modules/equal_by_class.rb +1 -1
- data/lib/gobstones/parser/ast/ast.rb +12 -8
- data/lib/gobstones/parser/grammar/gobstones.treetop +4 -4
- data/lib/gobstones/parser/parse_error.rb +1 -1
- data/lib/gobstones/runner/all.rb +1 -2
- data/lib/gobstones/runner/board.rb +13 -4
- data/lib/gobstones/runner/cell.rb +10 -0
- data/lib/gobstones/runner/errors/all.rb +1 -1
- data/lib/gobstones/runner/errors/definition_not_found_error.rb +1 -1
- data/lib/gobstones/runner/execution_context.rb +66 -16
- data/lib/gobstones/runner/head.rb +17 -3
- data/spec/gobstones_lang_test_objects.rb +75 -0
- data/spec/lang/commands/boom_cmd_spec.rb +3 -3
- data/spec/lang/commands/cmd_block_spec.rb +14 -14
- data/spec/lang/commands/if_cmd_spec.rb +21 -20
- data/spec/lang/commands/ir_al_origen_cmd_spec.rb +3 -3
- data/spec/lang/commands/mover_cmd_spec.rb +12 -14
- data/spec/lang/commands/multiple_assignment_spec.rb +37 -0
- data/spec/lang/commands/poner_cmd_spec.rb +13 -14
- data/spec/lang/commands/procedure_call_spec.rb +19 -24
- data/spec/lang/commands/procedure_spec.rb +32 -36
- data/spec/lang/commands/repeat_with_cmd_spec.rb +39 -20
- data/spec/lang/commands/sacar_cmd_spec.rb +17 -16
- data/spec/lang/commands/single_assignment_spec.rb +13 -0
- data/spec/lang/commands/skip_cmd_spec.rb +2 -2
- data/spec/lang/commands/vaciar_tablero_cmd_spec.rb +7 -6
- data/spec/lang/commands/while_cmd_spec.rb +21 -15
- data/spec/lang/definitions/no_return_statement_spec.rb +10 -0
- data/spec/lang/definitions/var_tuple_spec.rb +16 -0
- data/spec/lang/expressions/arithmetic_expressions_spec.rb +15 -15
- data/spec/lang/expressions/boolean_expressions_spec.rb +35 -25
- data/spec/lang/expressions/comparison_expressions_spec.rb +25 -28
- data/spec/lang/expressions/enclosed_by_parens_expression_spec.rb +11 -0
- data/spec/lang/expressions/function_call_spec.rb +29 -0
- data/spec/lang/expressions/primitive_functions_spec.rb +60 -62
- data/spec/lang/expressions/type_bound_functions_spec.rb +13 -13
- data/spec/lang/expressions/var_name_spec.rb +20 -8
- data/spec/lang/literals/booleans_spec.rb +5 -7
- data/spec/lang/literals/colors_spec.rb +4 -4
- data/spec/lang/literals/directions_spec.rb +12 -12
- data/spec/lang/literals/numbers_spec.rb +2 -2
- data/spec/matchers/parse_matcher.rb +9 -10
- data/spec/parser/arithmetic_expressions_spec.rb +19 -19
- data/spec/parser/assignments_spec.rb +24 -10
- data/spec/parser/boolean_expressions_spec.rb +18 -18
- data/spec/parser/command_block_spec.rb +17 -19
- data/spec/parser/data_types_spec.rb +23 -23
- data/spec/parser/function_calls_spec.rb +13 -12
- data/spec/parser/function_definitions_spec.rb +13 -18
- data/spec/parser/gobstones_program_spec.rb +15 -15
- data/spec/parser/if_command_spec.rb +13 -12
- data/spec/parser/main_definition_spec.rb +12 -12
- data/spec/parser/nested_expressions_spec.rb +16 -20
- data/spec/parser/primitive_expressions_spec.rb +27 -33
- data/spec/parser/procedure_calls_spec.rb +12 -12
- data/spec/parser/procedure_definitions_spec.rb +10 -16
- data/spec/parser/repeat_with_command_spec.rb +7 -10
- data/spec/parser/simple_commands_spec.rb +10 -10
- data/spec/parser/treetop_parser_spec.rb +11 -10
- data/spec/parser/var_tuple_spec.rb +7 -11
- data/spec/parser/while_command_spec.rb +9 -9
- data/spec/runner/board_spec.rb +23 -27
- data/spec/runner/cell_spec.rb +34 -38
- data/spec/runner/execution_context_spec.rb +38 -24
- data/spec/runner/head_spec.rb +54 -63
- data/spec/spec_helper.rb +4 -1
- data/spec/type_checker_spec.rb +13 -13
- metadata +33 -18
- data/lib/gobstones/lang/expressions/parentheses_expression.rb +0 -13
- data/spec/lang/commands/assignments_spec.rb +0 -13
@@ -1,18 +1,16 @@
|
|
1
1
|
describe Mover do
|
2
2
|
|
3
|
-
let(:context) {
|
4
|
-
let(:north) { Norte.new }
|
5
|
-
let(:south) { Sur.new }
|
3
|
+
let(:context) { clean_context }
|
6
4
|
|
7
|
-
it "
|
8
|
-
Mover.new(
|
5
|
+
it "moves the head to the specified direction when evaluating" do
|
6
|
+
Mover.new(norte).evaluate(context)
|
9
7
|
|
10
8
|
expect(context.head.x_pos).to eq(0)
|
11
9
|
expect(context.head.y_pos).to eq(1)
|
12
10
|
end
|
13
11
|
|
14
|
-
it "
|
15
|
-
cmd = Mover.new
|
12
|
+
it "undoes the given movement" do
|
13
|
+
cmd = Mover.new norte
|
16
14
|
|
17
15
|
cmd.evaluate context
|
18
16
|
cmd.undo context
|
@@ -21,18 +19,18 @@ describe Mover do
|
|
21
19
|
expect(context.head.y_pos).to eq(0)
|
22
20
|
end
|
23
21
|
|
24
|
-
it "
|
25
|
-
expect(Mover.new(
|
22
|
+
it "returns the opposite command" do
|
23
|
+
expect(Mover.new(norte).opposite).to eq(Mover.new(sur))
|
26
24
|
end
|
27
25
|
|
28
|
-
it "
|
29
|
-
expect { Mover.new(
|
26
|
+
it "fails if the argument is not a direction" do
|
27
|
+
expect { Mover.new(verde).evaluate(context) }.
|
30
28
|
to raise_error(GobstonesTypeError, /is not a direction/)
|
31
29
|
end
|
32
30
|
|
33
|
-
it "
|
34
|
-
expect { Mover.new(
|
31
|
+
it "fails when the resulting position is out of board" do
|
32
|
+
expect { Mover.new(sur).evaluate(context) }.
|
35
33
|
to raise_error(OutOfBoardError)
|
36
34
|
end
|
37
35
|
|
38
|
-
end
|
36
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
describe MultipleAssignment do
|
2
|
+
|
3
|
+
let(:my_function_return) { ReturnFromFunction.new [42.to_gbs_num, verde, MinDir.new] }
|
4
|
+
let(:my_function_def) { Function.new 'myFunction', no_arguments, empty_body, my_function_return }
|
5
|
+
let(:program) { Program.new [my_function_def], no_return_statement }
|
6
|
+
let(:context) { program_context_for program }
|
7
|
+
let(:a) { 'a'.to_var_name }
|
8
|
+
let(:b) { 'b'.to_var_name }
|
9
|
+
let(:c) { 'c'.to_var_name }
|
10
|
+
|
11
|
+
context "success" do
|
12
|
+
|
13
|
+
it "evaluates and set all the variables with the return values of a function call" do
|
14
|
+
var_tuple = VarTuple.new [a, b, c]
|
15
|
+
function_call = FunctionCall.new 'myFunction', []
|
16
|
+
assign = MultipleAssignment.new var_tuple, function_call
|
17
|
+
assign.evaluate context
|
18
|
+
expect(context.has_variable_named?('a')).to be true
|
19
|
+
expect(context.get(a)).to eq(42.to_gbs_num)
|
20
|
+
expect(context.has_variable_named?('b')).to be true
|
21
|
+
expect(context.get(b)).to eq(verde)
|
22
|
+
expect(context.has_variable_named?('c')).to be true
|
23
|
+
expect(context.get(c)).to eq(norte)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
context "failure" do
|
29
|
+
|
30
|
+
it "fails if there are more variables to be assigned on the left"
|
31
|
+
|
32
|
+
it "fails if there are more things to assign on the right"
|
33
|
+
|
34
|
+
it "fails if the expression on the right is not a function call"
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -1,29 +1,28 @@
|
|
1
1
|
describe Poner do
|
2
2
|
|
3
|
-
let(:context) {
|
4
|
-
let(:green) { Verde.new }
|
3
|
+
let(:context) { clean_context }
|
5
4
|
|
6
|
-
it "
|
7
|
-
Poner.new(
|
5
|
+
it "puts a ball of the given color in the current cell when evaluating" do
|
6
|
+
Poner.new(verde).evaluate(context)
|
8
7
|
|
9
|
-
expect(context.head.number_of_balls(
|
8
|
+
expect(context.head.number_of_balls(verde)).to eq(1)
|
10
9
|
end
|
11
10
|
|
12
|
-
it "
|
13
|
-
context.head.put
|
11
|
+
it "undoes the command" do
|
12
|
+
context.head.put verde
|
14
13
|
|
15
|
-
Poner.new(
|
14
|
+
Poner.new(verde).undo context
|
16
15
|
|
17
|
-
expect(context.head.number_of_balls(
|
16
|
+
expect(context.head.number_of_balls(verde)).to eq(0)
|
18
17
|
end
|
19
18
|
|
20
|
-
it "
|
21
|
-
expect(Poner.new(
|
19
|
+
it "returns the opposite command" do
|
20
|
+
expect(Poner.new(verde).opposite).to eq(Sacar.new(verde))
|
22
21
|
end
|
23
22
|
|
24
|
-
it "
|
25
|
-
expect { Poner.new(
|
23
|
+
it "fails if the argument is not a color" do
|
24
|
+
expect { Poner.new(norte).evaluate(context) }.
|
26
25
|
to raise_error(GobstonesTypeError, /is not a color/)
|
27
26
|
end
|
28
27
|
|
29
|
-
end
|
28
|
+
end
|
@@ -1,44 +1,39 @@
|
|
1
1
|
describe "procedure calls" do
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
my_procedure = Procedure.new 'MyProcedure', empty_args, body
|
10
|
-
program = Program.new [my_procedure], nil
|
11
|
-
context = ProgramExecutionContext.for program
|
3
|
+
it "evaluates an existing procedure when calling it" do
|
4
|
+
poner_cmd = Poner.new verde
|
5
|
+
body = CommandBlock.new [poner_cmd]
|
6
|
+
my_procedure = Procedure.new 'MyProcedure', no_arguments, body
|
7
|
+
program = Program.new [my_procedure], no_return_statement
|
8
|
+
context = program_context_for program
|
12
9
|
|
13
10
|
proc_call = ProcedureCall.new 'MyProcedure', []
|
14
11
|
proc_call.evaluate context
|
15
12
|
|
16
|
-
expect(context.head.are_there_balls?(
|
13
|
+
expect(context.head.are_there_balls?(verde)).to be true
|
17
14
|
end
|
18
15
|
|
19
|
-
it "
|
20
|
-
poner_cmd = Poner.new
|
21
|
-
inner_procedure_body =
|
22
|
-
inner_procedure = Procedure.new 'Inner',
|
16
|
+
it "allows to call a procedure from another procedure" do
|
17
|
+
poner_cmd = Poner.new azul
|
18
|
+
inner_procedure_body = CommandBlock.new [poner_cmd]
|
19
|
+
inner_procedure = Procedure.new 'Inner', no_arguments, inner_procedure_body
|
23
20
|
call_to_inner_procedure = ProcedureCall.new 'Inner', []
|
24
|
-
outer_procedure_body =
|
25
|
-
outer_procedure = Procedure.new 'Outer',
|
26
|
-
program = Program.new [outer_procedure, inner_procedure],
|
27
|
-
program_context =
|
21
|
+
outer_procedure_body = CommandBlock.new [call_to_inner_procedure]
|
22
|
+
outer_procedure = Procedure.new 'Outer', no_arguments, outer_procedure_body
|
23
|
+
program = Program.new [outer_procedure, inner_procedure], no_return_statement
|
24
|
+
program_context = program_context_for program
|
28
25
|
|
29
26
|
call_to_outer_procedure = ProcedureCall.new 'Outer', []
|
30
27
|
call_to_outer_procedure.evaluate program_context
|
31
28
|
|
32
|
-
expect(program_context.head.are_there_balls?(
|
29
|
+
expect(program_context.head.are_there_balls?(azul)).to be true
|
33
30
|
end
|
34
31
|
|
35
|
-
it "
|
36
|
-
program = Program.new [], nil
|
37
|
-
context = ProgramExecutionContext.for program
|
32
|
+
it "fails to execute an undefined procedure" do
|
38
33
|
proc_call = ProcedureCall.new 'UndefinedProcedure', []
|
39
34
|
|
40
|
-
expect { proc_call.evaluate
|
35
|
+
expect { proc_call.evaluate clean_context }
|
41
36
|
.to raise_error(DefinitionNotFound, DefinitionNotFound.message_for('UndefinedProcedure'))
|
42
37
|
end
|
43
38
|
|
44
|
-
end
|
39
|
+
end
|
@@ -1,67 +1,63 @@
|
|
1
1
|
describe Procedure do
|
2
2
|
|
3
|
-
let(:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
procedure.evaluate program_context
|
12
|
-
expect(program_context.head.are_there_balls?(Rojo.new)).to be_true
|
3
|
+
let(:context) { clean_context }
|
4
|
+
|
5
|
+
it "executes its body and leaves state in the program context" do
|
6
|
+
poner_cmd = Poner.new rojo
|
7
|
+
body = CommandBlock.new [poner_cmd]
|
8
|
+
procedure = Procedure.new 'MyProcedure', no_arguments, body
|
9
|
+
procedure.evaluate context
|
10
|
+
expect(context.head.are_there_balls?(rojo)).to be true
|
13
11
|
end
|
14
12
|
|
15
|
-
it "
|
16
|
-
var_name =
|
17
|
-
|
13
|
+
it "fails getting a variable which is in the outer context" do
|
14
|
+
var_name = 'var'.to_var_name
|
15
|
+
context.set var_name, verde
|
18
16
|
|
19
17
|
poner_cmd = Poner.new var_name
|
20
|
-
body =
|
21
|
-
procedure = Procedure.new 'MyProcedure',
|
22
|
-
expect { procedure.evaluate
|
23
|
-
.to raise_error(UndefinedVariableError)
|
18
|
+
body = CommandBlock.new [poner_cmd]
|
19
|
+
procedure = Procedure.new 'MyProcedure', no_arguments, body
|
20
|
+
expect { procedure.evaluate context }.to raise_error(UndefinedVariableError)
|
24
21
|
end
|
25
22
|
|
26
|
-
it "
|
27
|
-
a_color =
|
28
|
-
a_direction =
|
23
|
+
it "sets arguments in the new context so they can be used" do
|
24
|
+
a_color = 'a_color'.to_var_name
|
25
|
+
a_direction = 'a_direction'.to_var_name
|
29
26
|
args = VarTuple.new [a_color, a_direction]
|
30
27
|
mover_cmd = Mover.new a_direction
|
31
28
|
poner_cmd = Poner.new a_color
|
32
|
-
body =
|
29
|
+
body = CommandBlock.new [mover_cmd, poner_cmd]
|
33
30
|
procedure = Procedure.new 'MyProc', args, body
|
34
31
|
|
35
|
-
procedure.evaluate
|
32
|
+
procedure.evaluate context, [negro, norte]
|
36
33
|
|
37
|
-
expect(
|
38
|
-
expect(
|
34
|
+
expect(context.head.are_there_balls?(negro)).to be true
|
35
|
+
expect(context.head.y_pos).to eq(1)
|
39
36
|
end
|
40
37
|
|
41
|
-
it "
|
42
|
-
a_direction =
|
38
|
+
it "does not set arguments as var names in outer context" do
|
39
|
+
a_direction = 'a_direction'.to_var_name
|
43
40
|
args = VarTuple.new [a_direction]
|
44
41
|
procedure = Procedure.new 'MyProc', args, empty_body
|
45
42
|
|
46
|
-
procedure.evaluate
|
43
|
+
procedure.evaluate context, [oeste]
|
47
44
|
|
48
|
-
expect(
|
45
|
+
expect(context.has_variable_named?('a_direction')).to be false
|
49
46
|
end
|
50
47
|
|
51
|
-
it "
|
52
|
-
procedure = Procedure.new 'MyProcedure',
|
48
|
+
it "fails if it is executed with more arguments than expected" do
|
49
|
+
procedure = Procedure.new 'MyProcedure', no_arguments, empty_body
|
53
50
|
error_message = "Wrong number of arguments in procedure 'MyProcedure': expected 0, got 1"
|
54
|
-
expect { procedure.evaluate
|
51
|
+
expect { procedure.evaluate context, [norte] }
|
55
52
|
.to raise_error(WrongArgumentsError, error_message)
|
56
53
|
end
|
57
54
|
|
58
|
-
it "
|
59
|
-
|
60
|
-
args = VarTuple.new [arg1, arg2]
|
55
|
+
it "fails if it is executed with less arguments than expected" do
|
56
|
+
args = VarTuple.new ['arg1'.to_var_name, 'arg2'.to_var_name]
|
61
57
|
procedure = Procedure.new 'MyProcedure2', args, empty_body
|
62
58
|
error_message = "Wrong number of arguments in procedure 'MyProcedure2': expected 2, got 1"
|
63
|
-
expect { procedure.evaluate
|
59
|
+
expect { procedure.evaluate context, [verde] }
|
64
60
|
.to raise_error(WrongArgumentsError, error_message)
|
65
61
|
end
|
66
62
|
|
67
|
-
end
|
63
|
+
end
|
@@ -1,41 +1,60 @@
|
|
1
1
|
describe RepeatWithCmd do
|
2
2
|
|
3
|
-
let(:context) {
|
4
|
-
let(:var_name) {
|
3
|
+
let(:context) { clean_context }
|
4
|
+
let(:var_name) { 'var'.to_var_name }
|
5
|
+
|
6
|
+
it "iterates over numbers when evaluating" do
|
7
|
+
command_block = CommandBlock.new [Poner.new(rojo)]
|
8
|
+
repeat_with = RepeatWithCmd.new var_name, 1.to_gbs_num, 10.to_gbs_num, command_block
|
5
9
|
|
6
|
-
it "should iterate over numbers" do
|
7
|
-
repeat_with = RepeatWithCmd.new var_name, 1.to_gbs_num, 10.to_gbs_num, CmdBlock.new([Poner.new(Rojo.new)])
|
8
10
|
repeat_with.evaluate context
|
9
|
-
|
11
|
+
|
12
|
+
expect(context.head.number_of_balls(rojo)).to eq(10)
|
10
13
|
end
|
11
14
|
|
12
|
-
it "
|
13
|
-
repeat_with = RepeatWithCmd.new var_name, 1.to_gbs_num,
|
15
|
+
it "raises an error if the range values have not the same type" do
|
16
|
+
repeat_with = RepeatWithCmd.new var_name, 1.to_gbs_num, este, empty_body
|
17
|
+
|
14
18
|
expect { repeat_with.evaluate context }
|
15
19
|
.to raise_error(GobstonesTypeError, /types don't match in range values/)
|
16
20
|
end
|
17
21
|
|
18
|
-
it "
|
19
|
-
repeat_with = RepeatWithCmd.new var_name, 1.to_gbs_num, 5.to_gbs_num,
|
22
|
+
it "raises an error if the index variable is previously defined" do
|
23
|
+
repeat_with = RepeatWithCmd.new var_name, 1.to_gbs_num, 5.to_gbs_num, empty_body
|
24
|
+
|
20
25
|
context.set var_name, 42.to_gbs_num
|
26
|
+
|
21
27
|
expect { repeat_with.evaluate context }
|
22
28
|
.to raise_error(GobstonesRuntimeError, /index variable can't be used because it's already defined/)
|
23
29
|
end
|
24
30
|
|
25
|
-
it "
|
26
|
-
repeat_with = RepeatWithCmd.new var_name,
|
31
|
+
it "removes the index variable assignment after execution" do
|
32
|
+
repeat_with = RepeatWithCmd.new var_name, azul, verde, empty_body
|
33
|
+
|
34
|
+
repeat_with.evaluate context
|
35
|
+
|
36
|
+
expect(context.has_variable_named?('var')).to be false
|
37
|
+
end
|
38
|
+
|
39
|
+
it "allows to use the index variable inside the command block" do
|
40
|
+
cmd_block = CommandBlock.new [Poner.new(var_name)]
|
41
|
+
repeat_with = RepeatWithCmd.new var_name, azul, verde, cmd_block
|
42
|
+
|
27
43
|
repeat_with.evaluate context
|
28
|
-
|
44
|
+
|
45
|
+
expect(context.head.are_there_balls?(azul)).to be true
|
46
|
+
expect(context.head.are_there_balls?(negro)).to be true
|
47
|
+
expect(context.head.are_there_balls?(rojo)).to be true
|
48
|
+
expect(context.head.are_there_balls?(verde)).to be true
|
29
49
|
end
|
30
50
|
|
31
|
-
it "
|
32
|
-
cmd_block =
|
33
|
-
repeat_with = RepeatWithCmd.new var_name,
|
51
|
+
it "does no iterations if the from is higher than the to" do
|
52
|
+
cmd_block = CommandBlock.new [Poner.new(verde)]
|
53
|
+
repeat_with = RepeatWithCmd.new var_name, 8.to_gbs_num, 4.to_gbs_num, cmd_block
|
54
|
+
|
34
55
|
repeat_with.evaluate context
|
35
|
-
|
36
|
-
expect(context.head.are_there_balls?(
|
37
|
-
expect(context.head.are_there_balls?(Rojo.new)).to be_true
|
38
|
-
expect(context.head.are_there_balls?(Verde.new)).to be_true
|
56
|
+
|
57
|
+
expect(context.head.are_there_balls?(verde)).to be false
|
39
58
|
end
|
40
59
|
|
41
|
-
end
|
60
|
+
end
|
@@ -1,34 +1,35 @@
|
|
1
1
|
describe Sacar do
|
2
2
|
|
3
|
-
let(:context) {
|
4
|
-
let(:red) { Rojo.new }
|
3
|
+
let(:context) { clean_context }
|
5
4
|
|
6
|
-
it "
|
7
|
-
3.times { context.head.put
|
5
|
+
it "take off balls from the board when evaluating" do
|
6
|
+
3.times { context.head.put rojo }
|
8
7
|
|
9
|
-
Sacar.new(
|
8
|
+
Sacar.new(rojo).evaluate context
|
10
9
|
|
11
|
-
expect(context.head.number_of_balls(
|
10
|
+
expect(context.head.number_of_balls(rojo)).to eq(2)
|
12
11
|
end
|
13
12
|
|
14
|
-
it "
|
15
|
-
Sacar.new(
|
13
|
+
it "undoes a command" do
|
14
|
+
Sacar.new(rojo).undo context
|
16
15
|
|
17
|
-
expect(context.head.number_of_balls(
|
16
|
+
expect(context.head.number_of_balls(rojo)).to eq(1)
|
18
17
|
end
|
19
18
|
|
20
|
-
it "
|
21
|
-
|
19
|
+
it "returns the opposite command" do
|
20
|
+
opposite_command = Sacar.new(rojo).opposite
|
21
|
+
|
22
|
+
expect(opposite_command).to eq(Poner.new(rojo))
|
22
23
|
end
|
23
24
|
|
24
|
-
it "
|
25
|
-
expect { Sacar.new(
|
25
|
+
it "fails if there are no balls in the board" do
|
26
|
+
expect { Sacar.new(rojo).evaluate(context) }.
|
26
27
|
to raise_error(EmptyCellError)
|
27
28
|
end
|
28
29
|
|
29
|
-
it "
|
30
|
-
expect { Sacar.new(
|
30
|
+
it "fails if the argument is not a color" do
|
31
|
+
expect { Sacar.new(true_value).evaluate(context) }.
|
31
32
|
to raise_error(GobstonesTypeError, /is not a color/)
|
32
33
|
end
|
33
34
|
|
34
|
-
end
|
35
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
describe SingleAssignment do
|
2
|
+
|
3
|
+
let(:context) { clean_context }
|
4
|
+
let(:a) { 'a'.to_var_name }
|
5
|
+
|
6
|
+
it "evaluates the associated expression to the var name" do
|
7
|
+
assign = SingleAssignment.new a, Add.new(3.to_gbs_num, 4.to_gbs_num)
|
8
|
+
assign.evaluate context
|
9
|
+
expect(context.has_variable_named?('a')).to be true
|
10
|
+
expect(context.get(a)).to eq(7.to_gbs_num)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
describe Skip do
|
2
2
|
|
3
|
-
let(:context) {
|
3
|
+
let(:context) { clean_context }
|
4
4
|
|
5
5
|
it "evaluates and does nothing" do
|
6
6
|
Skip.new.evaluate context
|
@@ -9,4 +9,4 @@ describe Skip do
|
|
9
9
|
expect(context.head.board).to be_empty
|
10
10
|
end
|
11
11
|
|
12
|
-
end
|
12
|
+
end
|