gobstones-spec 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8b3c5bb11b693ef447845a080987bf266ed91d49
4
+ data.tar.gz: 4ad74366f324d2280aba57682b946ee2e1989017
5
+ SHA512:
6
+ metadata.gz: 7a8dec77ebcf4cfa31699442077bb7e0093c4539af95ae8e5419da9f89e5e838b8f29d1f81012131868ccca885260a265ce58db08b0a450d43b4ec53b53a91e7
7
+ data.tar.gz: 4eba581631c514205a2b2aa8e5d93600bedff21d09a89d89cba840bcf072265cf23265e1e87c26450c2089c2cb5d6ab9082bde5dcc28907e58a94d25dc9983c9
@@ -0,0 +1,5 @@
1
+ class Array
2
+ def init(n=1)
3
+ take size - n
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ module Gobstones
2
+ end
3
+
4
+ require_relative 'gobstones/board'
5
+ require_relative 'gobstones/cell'
6
+ require_relative 'gobstones/gbb_parser'
7
+ require_relative 'gobstones/position'
8
+ require_relative 'gobstones/with_tempfile'
9
+ require_relative 'gobstones/with_command_line'
10
+ require_relative 'gobstones/spec'
11
+ require_relative 'gobstones/version'
@@ -0,0 +1,55 @@
1
+ module Gobstones
2
+
3
+ class OutOfBoardError < RuntimeError
4
+ end
5
+
6
+ class Board
7
+ attr_reader :size, :cells, :head_position
8
+
9
+ def initialize(x, y)
10
+ @size = [x, y]
11
+ @cells = Hash.new(Cell.new)
12
+ @head_position = Position.new(0, 0)
13
+ end
14
+
15
+ def add_cell(position, cell)
16
+ @cells[position] = cell
17
+ self
18
+ end
19
+
20
+ def move_head_to(position)
21
+ check_is_within_bounds position
22
+ @head_position = position
23
+ self
24
+ end
25
+
26
+ def cell_at(position)
27
+ check_is_within_bounds position
28
+ @cells[position]
29
+ end
30
+
31
+ def ==(other)
32
+ self.class === other &&
33
+ other.size == @size &&
34
+ all_cells_equal?(other)
35
+ end
36
+
37
+ private
38
+
39
+ def within_bounds?(position)
40
+ @size[0] > position.x && @size[1] > position.y
41
+ end
42
+
43
+ def check_is_within_bounds(position)
44
+ raise OutOfBoardError unless within_bounds?(position)
45
+ end
46
+
47
+ def all_cells_equal?(other)
48
+ self.class.includes_cells?(self, other) && self.class.includes_cells?(other, self)
49
+ end
50
+
51
+ def self.includes_cells?(this, that)
52
+ this.cells.all? { |position, cell| that.cell_at(position) == cell }
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,30 @@
1
+ module Gobstones
2
+ class Cell
3
+ attr_accessor :red, :green, :blue, :black
4
+
5
+ def initialize(red: 0, green: 0, blue: 0, black: 0)
6
+ @red = red
7
+ @green = green
8
+ @blue = blue
9
+ @black = black
10
+ end
11
+
12
+ def set(color, quantity)
13
+ send "#{color}=", quantity
14
+ end
15
+
16
+ def ==(other)
17
+ self.class === other &&
18
+ other.red == @red &&
19
+ other.green == @green &&
20
+ other.blue == @blue &&
21
+ other.black == @black
22
+ end
23
+
24
+ alias eql? ==
25
+
26
+ def hash
27
+ @red.hash ^ @green.hash ^ @blue.hash ^ @black.hash
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,52 @@
1
+ require_relative '../extensions/array.rb'
2
+
3
+
4
+ class MatchData
5
+ def to_position
6
+ Gobstones::Position.new self[1].to_i, self[2].to_i
7
+ end
8
+ end
9
+
10
+ module Gobstones
11
+ class GbbParser
12
+ COLORS = {'Azul' => :blue, 'Negro' => :black, 'Rojo' => :red, 'Verde' => :green}
13
+
14
+ def from_string(gbb_string)
15
+ board = nil
16
+
17
+ lines = gbb_string.lines.reject { |it| it.start_with? 'GBB', '%%' }
18
+
19
+ /size (\d+) (\d+)/.match(lines[0]) { |match| board = Board.new(match[1].to_i, match[2].to_i) }
20
+ /head (\d+) (\d+)/.match(lines.last) { |match| board.move_head_to match.to_position }
21
+
22
+ lines.drop(1).init.each do |cell_line|
23
+ position = get_position_from cell_line
24
+ cell = create_cell_from cell_line
25
+
26
+ board.add_cell position, cell
27
+ end
28
+
29
+ board
30
+ end
31
+
32
+ private
33
+
34
+ def get_position_from(cell_line)
35
+ /cell (\d+) (\d+)/.match(cell_line).to_position
36
+ end
37
+
38
+ def create_cell_from(cell_line)
39
+ cell = Cell.new
40
+
41
+ cell_line.scan(/(Azul|Negro|Rojo|Verde) (\d+)/) do |match|
42
+ cell.set to_color(match[0]), match[1].to_i
43
+ end
44
+
45
+ cell
46
+ end
47
+
48
+ def to_color(gbb_color_string)
49
+ COLORS[gbb_color_string]
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,22 @@
1
+ module Gobstones
2
+ class Position
3
+ attr_reader :x, :y
4
+
5
+ def initialize(x, y)
6
+ @x = x
7
+ @y = y
8
+ end
9
+
10
+ def ==(other)
11
+ self.class === other &&
12
+ other.x == @x &&
13
+ other.y == @y
14
+ end
15
+
16
+ alias eql? ==
17
+
18
+ def hash
19
+ @x.hash ^ @y.hash
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,8 @@
1
+ module Gobstones
2
+ module Spec
3
+ end
4
+ end
5
+
6
+ require_relative './spec/error_message_parser'
7
+ require_relative './spec/example'
8
+ require_relative './spec/runner'
@@ -0,0 +1,19 @@
1
+ module Gobstones::Spec
2
+ class ErrorMessageParser
3
+ def remove_traceback (x)
4
+ x.take_while { |str| not str.start_with? 'Traceback' }
5
+ end
6
+
7
+ def remove_line_specification(x)
8
+ x.drop(3)
9
+ end
10
+
11
+ def remove_boom_line_specification(x)
12
+ x.take_while { |str| not str.strip.start_with? 'En:' }
13
+ end
14
+
15
+ def parse(result)
16
+ remove_boom_line_specification(remove_traceback(remove_line_specification(result.lines))).join.strip
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,81 @@
1
+ module Gobstones::Spec
2
+ class Example
3
+ include Gobstones::WithTempfile
4
+
5
+ attr_reader :gobstones_path
6
+
7
+ def initialize(gobstones_path, check_head_position)
8
+ @gobstones_path = gobstones_path
9
+ @check_head_position = check_head_position
10
+ end
11
+
12
+ def start!(source_file, initial_board, final_board)
13
+ @source_file = source_file
14
+ @expected_final_board_gbb = final_board
15
+ @expected_final_board = Gobstones::GbbParser.new.from_string final_board
16
+
17
+ @html_output_file = Tempfile.new %w(gobstones.output .html)
18
+ @actual_final_board_file = Tempfile.new %w(gobstones.output .gbb)
19
+ @initial_board_file = write_tempfile initial_board, 'gbb'
20
+
21
+ "#{run_on_gobstones @source_file, @initial_board_file, @actual_final_board_file} 2>&1 &&" +
22
+ "#{run_on_gobstones @source_file, @initial_board_file, @html_output_file}"
23
+ end
24
+
25
+ def result
26
+ actual = Gobstones::GbbParser.new.from_string(@actual_final_board_file.read)
27
+
28
+ if matches_with_expected_board? actual
29
+ ["<div>#{@html_output_file.read}</div>", :passed]
30
+ else
31
+ initial_board_html = get_html_board @initial_board_file.open.read
32
+ expected_board_html = get_html_board @expected_final_board_gbb
33
+
34
+ output =
35
+ "<div>
36
+ #{add_caption initial_board_html, 'Tablero inicial'}
37
+ #{add_caption @html_output_file.read, 'Tablero final obtenido'}
38
+ #{add_caption expected_board_html, 'Tablero final esperado'}
39
+ </div>"
40
+
41
+ [output, :failed]
42
+ end
43
+ end
44
+
45
+ def parse_error_message(result)
46
+ ErrorMessageParser.new.parse(result)
47
+ end
48
+
49
+ def stop!
50
+ [@html_output_file, @actual_final_board_file, @initial_board_file].each { |it| it.unlink }
51
+ end
52
+
53
+ private
54
+
55
+ def matches_with_expected_board?(actual_board)
56
+ actual_board == @expected_final_board && (!@check_head_position || actual_board.head_position == @expected_final_board.head_position)
57
+ end
58
+
59
+ def run_on_gobstones(source_file, initial_board_file, final_board_file)
60
+ "#{gobstones_path} #{source_file.path} --from #{initial_board_file.path} --to #{final_board_file.path}"
61
+ end
62
+
63
+ def get_html_board(gbb_representation)
64
+ identity = write_tempfile 'program {}', '.gbs'
65
+
66
+ board = write_tempfile gbb_representation, '.gbb'
67
+
68
+ board_html = Tempfile.new %w(gobstones.board .html)
69
+
70
+ %x"#{run_on_gobstones(identity, board, board_html)}"
71
+
72
+ result = board_html.read
73
+ board_html.unlink
74
+ result
75
+ end
76
+
77
+ def add_caption(board_html, caption)
78
+ board_html.sub '<table class="gbs_board">', "<table class=\"gbs_board\">\n<caption>#{caption}</caption>"
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,50 @@
1
+ module Gobstones::Spec
2
+ class Runner
3
+ include Gobstones::WithCommandLine
4
+ include Gobstones::WithTempfile
5
+
6
+ attr_reader :gobstones_path
7
+
8
+ def initialize(gobstones_path)
9
+ @gobstones_path = gobstones_path
10
+ end
11
+
12
+ def run!(test_definition)
13
+ source_file = write_tempfile test_definition[:source], 'gbs'
14
+ results = test_definition[:examples].map do |example_definition|
15
+ example_definition[:check_head_position] = test_definition[:check_head_position]
16
+ run_example!(example_definition, source_file)
17
+ end
18
+ aggregate_results(results)
19
+ ensure
20
+ source_file.unlink
21
+ end
22
+
23
+ private
24
+
25
+ def run_example!(example_definition, source_file)
26
+ command = start_example(source_file, example_definition)
27
+ result, status = run_command command
28
+ post_process result, status
29
+ end
30
+
31
+ def aggregate_results(results)
32
+ [results.map { |it| it[0] }.join("\n<hr>\n"), results.all? { |it| it[1] == :passed } ? :passed : :failed]
33
+ end
34
+
35
+ def post_process(result, status)
36
+ if status == :passed
37
+ @example.result
38
+ else
39
+ [@example.parse_error_message(result), status]
40
+ end
41
+ ensure
42
+ @example.stop!
43
+ end
44
+
45
+ def start_example(source, example_definition)
46
+ @example = Gobstones::Spec::Example.new(gobstones_path, example_definition[:check_head_position])
47
+ @example.start!(source, example_definition[:initial_board], example_definition[:final_board])
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,3 @@
1
+ module Gobstones
2
+ VERSION = '0.2.0'
3
+ end
@@ -0,0 +1,7 @@
1
+ module Gobstones
2
+ module WithCommandLine
3
+ def run_command(command)
4
+ [%x{#{command}}, $?.success? ? :passed : :failed]
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,13 @@
1
+ require 'tempfile'
2
+
3
+ module Gobstones
4
+ module WithTempfile
5
+
6
+ def write_tempfile(content, extension)
7
+ file = Tempfile.new %W(gobstones. .#{extension})
8
+ file.write content
9
+ file.close
10
+ file
11
+ end
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gobstones-spec
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Federico Aloi
8
+ - Franco Bulgarelli
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-05-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ~>
19
+ - !ruby/object:Gem::Version
20
+ version: '1.7'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ version: '1.7'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: '10.0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ version: '10.0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ~>
47
+ - !ruby/object:Gem::Version
48
+ version: '2'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: '2'
56
+ - !ruby/object:Gem::Dependency
57
+ name: codeclimate-test-reporter
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ description: Write Gobstones specs within Ruby
71
+ email:
72
+ - federico.aloi@gmail.com
73
+ - flbulgarelli@yahoo.com.ar
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - lib/gobstones/with_command_line.rb
79
+ - lib/gobstones/with_tempfile.rb
80
+ - lib/gobstones/gbb_parser.rb
81
+ - lib/gobstones/position.rb
82
+ - lib/gobstones/spec/error_message_parser.rb
83
+ - lib/gobstones/spec/example.rb
84
+ - lib/gobstones/spec/runner.rb
85
+ - lib/gobstones/spec.rb
86
+ - lib/gobstones/version.rb
87
+ - lib/gobstones/cell.rb
88
+ - lib/gobstones/board.rb
89
+ - lib/gobstones.rb
90
+ - lib/extensions/array.rb
91
+ homepage: https://github.com/uqbar-project/gobstones-spec
92
+ licenses:
93
+ - MIT
94
+ metadata: {}
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ requirements: []
110
+ rubyforge_project:
111
+ rubygems_version: 2.0.14
112
+ signing_key:
113
+ specification_version: 4
114
+ summary: Minimal test framework for the Gobstones language
115
+ test_files: []