mumuki-gobstones-runner 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/lib/assets_server.rb +37 -0
- data/lib/checker.rb +101 -0
- data/lib/expectations_hook.rb +8 -96
- data/lib/extensions/string.rb +17 -0
- data/lib/gobstones.rb +11 -0
- data/lib/gobstones/batch.rb +38 -0
- data/lib/gobstones/batch_parser.rb +68 -0
- data/lib/gobstones/error_builder.rb +6 -0
- data/lib/gobstones/example_code_builder.rb +35 -0
- data/lib/gobstones_runner.rb +17 -4
- data/lib/locales/en.yml +13 -0
- data/lib/locales/es.yml +13 -0
- data/lib/metadata_hook.rb +29 -7
- data/lib/multiple_executions_runner.rb +28 -0
- data/lib/precompile_hook.rb +30 -0
- data/lib/render/boards.html.erb +58 -0
- data/lib/render/editor/editor.css +12 -0
- data/lib/render/editor/editor.js +9 -0
- data/lib/render/html_board.rb +12 -0
- data/lib/render/html_renderer.rb +95 -0
- data/lib/render/with_renderer.rb +22 -0
- data/lib/test_hook.rb +8 -21
- metadata +66 -55
- data/lib/assets/boom.png +0 -0
- data/lib/stones_spec.rb +0 -21
- data/lib/stones_spec/error_message_parser.rb +0 -17
- data/lib/stones_spec/example.rb +0 -47
- data/lib/stones_spec/gobstones.rb +0 -55
- data/lib/stones_spec/hash.rb +0 -5
- data/lib/stones_spec/html_board_renderer.rb +0 -77
- data/lib/stones_spec/postcondition/expected_boom.rb +0 -55
- data/lib/stones_spec/postcondition/expected_final_board.rb +0 -56
- data/lib/stones_spec/postcondition/expected_return_value.rb +0 -44
- data/lib/stones_spec/postcondition/postcondition.rb +0 -35
- data/lib/stones_spec/precondition.rb +0 -26
- data/lib/stones_spec/runner.rb +0 -41
- data/lib/stones_spec/string.rb +0 -10
- data/lib/stones_spec/subject.rb +0 -80
- data/lib/stones_spec/version.rb +0 -3
- data/lib/stones_spec/with_command_line.rb +0 -7
- data/lib/stones_spec/with_gbb_html_rendering.rb +0 -60
- data/lib/stones_spec/with_gobstones_css.rb +0 -112
- data/lib/stones_spec/with_tempfile.rb +0 -13
- data/lib/with_test_parser.rb +0 -8
data/lib/stones_spec/runner.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
module StonesSpec
|
2
|
-
class Runner
|
3
|
-
include StonesSpec::WithTempfile
|
4
|
-
|
5
|
-
def run!(test_definition)
|
6
|
-
subject = Subject.from(test_definition[:subject])
|
7
|
-
source = test_definition[:source]
|
8
|
-
check_head_position = test_definition[:check_head_position]
|
9
|
-
show_initial_board = test_definition.fetch(:show_initial_board, true)
|
10
|
-
|
11
|
-
begin
|
12
|
-
[test_definition[:examples].map do |example_definition|
|
13
|
-
run_example!(example_definition, check_head_position, show_initial_board, source, subject)
|
14
|
-
end]
|
15
|
-
rescue Gobstones::AbortedError => e
|
16
|
-
test_definition[:expect_endless_while] ? [e.message, :passed] : [e.message, e.status]
|
17
|
-
rescue Gobstones::Error => e
|
18
|
-
[e.message, e.status]
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def run_example!(example_definition, check_head_position, show_initial_board, source, subject)
|
25
|
-
example = Example.new(subject, example_definition)
|
26
|
-
|
27
|
-
data = example.execution_data source
|
28
|
-
files = {
|
29
|
-
source: Gobstones.source_code_extension,
|
30
|
-
initial_board: Gobstones.board_extension,
|
31
|
-
final_board: Gobstones.board_extension
|
32
|
-
}.map_values { |name, extension| write_tempfile(data[name], extension) }
|
33
|
-
|
34
|
-
execution = example.execute! files
|
35
|
-
|
36
|
-
example.result files, execution, Postcondition.from(example, check_head_position, show_initial_board)
|
37
|
-
ensure
|
38
|
-
files.each_value(&:unlink)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
data/lib/stones_spec/string.rb
DELETED
data/lib/stones_spec/subject.rb
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
module StonesSpec
|
2
|
-
module Subject
|
3
|
-
def self.from(name)
|
4
|
-
if name
|
5
|
-
infer_subject_type_for(name).new(name)
|
6
|
-
else
|
7
|
-
Program
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.infer_subject_type_for(string)
|
12
|
-
string.start_with_lowercase? ? StonesSpec::Subject::Function : StonesSpec::Subject::Procedure
|
13
|
-
end
|
14
|
-
|
15
|
-
module Program
|
16
|
-
def self.test_program(source, _arguments)
|
17
|
-
source
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.default_title(_arguments)
|
21
|
-
nil
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.ast_regexp
|
25
|
-
/AST\(entrypoint\s*program/
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.default_expectations
|
29
|
-
[{ 'binding' => 'program', 'inspection' => 'HasBinding' }]
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
class Callable
|
34
|
-
def initialize(name)
|
35
|
-
@name = name
|
36
|
-
end
|
37
|
-
|
38
|
-
def call_string(arguments)
|
39
|
-
"#{@name}(#{arguments.join(', ')})"
|
40
|
-
end
|
41
|
-
|
42
|
-
def default_title(arguments)
|
43
|
-
call_string arguments
|
44
|
-
end
|
45
|
-
|
46
|
-
def default_expectations
|
47
|
-
[ { 'binding' => 'program', 'inspection' => 'Not:HasBinding' },
|
48
|
-
{ 'binding' => "#{@name}", 'inspection' => 'HasBinding' } ]
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
class Procedure < Callable
|
53
|
-
def test_program(source, arguments)
|
54
|
-
"program {
|
55
|
-
#{call_string arguments}
|
56
|
-
}
|
57
|
-
|
58
|
-
#{source}"
|
59
|
-
end
|
60
|
-
|
61
|
-
def ast_regexp
|
62
|
-
/AST\(procedure\s*#{@name}$/
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
class Function < Callable
|
67
|
-
def test_program(source, arguments)
|
68
|
-
"program {
|
69
|
-
return (#{call_string arguments})
|
70
|
-
}
|
71
|
-
|
72
|
-
#{source}"
|
73
|
-
end
|
74
|
-
|
75
|
-
def ast_regexp
|
76
|
-
/AST\(function\s*#{@name}/
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
data/lib/stones_spec/version.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
module StonesSpec
|
2
|
-
module WithGbbHtmlRendering
|
3
|
-
def get_html_board(caption, gbb_representation)
|
4
|
-
HtmlBoardRenderer.new(caption: caption).render(Stones::GbbReader.new.from_string gbb_representation)
|
5
|
-
end
|
6
|
-
|
7
|
-
def make_error_output(result, initial_board_gbb)
|
8
|
-
error_message = Gobstones.parse_error_message result
|
9
|
-
if Gobstones.runtime_error? error_message
|
10
|
-
"#{get_html_board 'Tablero inicial', initial_board_gbb}\n#{get_boom_board initial_board_gbb}\n#{error_message}"
|
11
|
-
else
|
12
|
-
error_message
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def make_boards_output(title, gbb_boards, status, extra = nil)
|
17
|
-
boards = gbb_boards.map { |gbb_with_caption| get_html_board *gbb_with_caption }.join("\n")
|
18
|
-
output = "<div>#{boards}</div>"
|
19
|
-
|
20
|
-
output = "<p>#{extra}</p>\n#{output}" if extra
|
21
|
-
|
22
|
-
[title, status, output]
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def get_boom_board(initial_board_gbb)
|
28
|
-
gbb = empty_board_gbb_like initial_board_gbb
|
29
|
-
|
30
|
-
boom_css =
|
31
|
-
"<style type=\"text/css\">
|
32
|
-
table.boom {
|
33
|
-
background-image: url('#{boom_image_url}');
|
34
|
-
background-size: contain;
|
35
|
-
background-repeat: no-repeat;
|
36
|
-
background-position: center;
|
37
|
-
}
|
38
|
-
</style>"
|
39
|
-
|
40
|
-
without_header with_boom_css_class "#{boom_css}\n#{get_html_board '¡Se produjo BOOM!', gbb}"
|
41
|
-
end
|
42
|
-
|
43
|
-
def boom_image_url
|
44
|
-
'https://raw.githubusercontent.com/mumuki/mumuki-gobstones-server/master/lib/assets/boom.png'
|
45
|
-
end
|
46
|
-
|
47
|
-
def empty_board_gbb_like(initial_board_gbb)
|
48
|
-
x, y = Stones::Gbb.read(initial_board_gbb).size
|
49
|
-
Stones::Gbb.write Stones::Board.empty(x, y)
|
50
|
-
end
|
51
|
-
|
52
|
-
def with_boom_css_class(html)
|
53
|
-
html.sub('class="gbs_board"', 'class="gbs_board boom"')
|
54
|
-
end
|
55
|
-
|
56
|
-
def without_header(html)
|
57
|
-
html.sub('class="gc gh"', 'class="gc"')
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -1,112 +0,0 @@
|
|
1
|
-
module StonesSpec
|
2
|
-
module WithGobstonesCSS
|
3
|
-
def gobstones_css(font_size, size)
|
4
|
-
unit = 'px'
|
5
|
-
|
6
|
-
full_size = "#{size}#{unit}"
|
7
|
-
half_size = "#{size / 2}#{unit}"
|
8
|
-
|
9
|
-
"table.gbs_board {
|
10
|
-
border-style: none;
|
11
|
-
border: solid black 0px;
|
12
|
-
border-spacing: 0;
|
13
|
-
border-collapse: collapse;
|
14
|
-
font-family: Arial, Helvetica, sans-serif;
|
15
|
-
font-size: #{font_size};
|
16
|
-
display: inline-block;
|
17
|
-
vertical-align: top;
|
18
|
-
}
|
19
|
-
.gbs_board td {
|
20
|
-
margin: 0;
|
21
|
-
padding: 2px;
|
22
|
-
border: solid #888 1px;
|
23
|
-
width: #{full_size};
|
24
|
-
height: #{full_size};
|
25
|
-
}
|
26
|
-
.gbs_board td.gh { /* position of the header in the board */
|
27
|
-
margin: 0;
|
28
|
-
padding: 2px;
|
29
|
-
border: dotted #440 3px;
|
30
|
-
background: #dd8;
|
31
|
-
width: #{full_size};
|
32
|
-
height: #{full_size};
|
33
|
-
}
|
34
|
-
.gbs_board td.lv { /* labels at the side */
|
35
|
-
text-align: center;
|
36
|
-
vertical-align: middle;
|
37
|
-
border-style: none;
|
38
|
-
border: solid black 0px;
|
39
|
-
background: #ddd;
|
40
|
-
width: #{half_size};
|
41
|
-
}
|
42
|
-
.gbs_board td.lh { /* labels at the top / bottom */
|
43
|
-
text-align: center;
|
44
|
-
vertical-align: middle;
|
45
|
-
border-style: none;
|
46
|
-
border: solid black 0px;
|
47
|
-
background: #ddd;
|
48
|
-
height: #{half_size};
|
49
|
-
}
|
50
|
-
.gbs_board td.lx { /* corner */
|
51
|
-
border-style: none;
|
52
|
-
border: solid black 0px;
|
53
|
-
background: #ddd;
|
54
|
-
width: #{half_size};
|
55
|
-
height: #{half_size};
|
56
|
-
}
|
57
|
-
.gbs_board td.top_left {
|
58
|
-
-webkit-border-top-left-radius: 10px;
|
59
|
-
-moz-border-top-left-radius: 10px;
|
60
|
-
border-top-left-radius: 10px;
|
61
|
-
}
|
62
|
-
.gbs_board td.top_right {
|
63
|
-
-webkit-border-top-right-radius: 10px;
|
64
|
-
-moz-border-top-right-radius: 10px;
|
65
|
-
border-top-right-radius: 10px;
|
66
|
-
}
|
67
|
-
.gbs_board td.bottom_left {
|
68
|
-
-webkit-border-bottom-left-radius: 10px;
|
69
|
-
-moz-border-bottom-left-radius: 10px;
|
70
|
-
border-bottom-left-radius: 10px;
|
71
|
-
}
|
72
|
-
.gbs_board td.bottom_right {
|
73
|
-
-webkit-border-bottom-right-radius: 10px;
|
74
|
-
-moz-border-bottom-right-radius: 10px;
|
75
|
-
border-bottom-right-radius: 10px;
|
76
|
-
}
|
77
|
-
.gbs_board table.gc { /* cell table */
|
78
|
-
border-style: none;
|
79
|
-
border: solid black 0px;
|
80
|
-
}
|
81
|
-
.gbs_board .gc tr {
|
82
|
-
border-style: none;
|
83
|
-
border: 0px;
|
84
|
-
}
|
85
|
-
.gbs_board .gc td {
|
86
|
-
border-style: none;
|
87
|
-
border: solid black 0px;
|
88
|
-
width: #{half_size};
|
89
|
-
height: #{half_size};
|
90
|
-
text-align: center;
|
91
|
-
color: black;
|
92
|
-
}
|
93
|
-
.gbs_board .gc td div {
|
94
|
-
line-height: 2;
|
95
|
-
}
|
96
|
-
.gbs_board div.A { background: #88f; border: solid 1px #008; }
|
97
|
-
.gbs_board div.N { background: #aaa; border: solid 1px #222; }
|
98
|
-
.gbs_board div.R { background: #f88; border: solid 1px #800; }
|
99
|
-
.gbs_board div.V { background: #8f8; border: solid 1px #080; }
|
100
|
-
.gbs_board div.O { width: 20px; height: 20px; background: none; } /* empty */
|
101
|
-
.gbs_stone {
|
102
|
-
font-weight: bold;
|
103
|
-
font-size: 8pt;
|
104
|
-
width: 20px;
|
105
|
-
height: 20px;
|
106
|
-
-webkit-border-radius: 10px;
|
107
|
-
-moz-border-radius: 10px;
|
108
|
-
border-radius: 10px;
|
109
|
-
}"
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|