Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests for sample dir and tweak samples #217

Merged
merged 2 commits into from
May 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions sample/array2.y
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ end
when /\A\s+/
str = $'
when /\A\w+/
yield :ITEM, $&
yield [:ITEM, $&]
str = $'
else
c = str[0,1]
yield c, c
yield [c, c]
str = str[1..-1]
end
end
yield false, '$' # is optional from Racc 1.3.7
yield [false, '$'] # is optional from Racc 1.3.7
end

def next_token
Expand Down
26 changes: 14 additions & 12 deletions sample/calc.y
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,20 @@ end

---- footer

parser = Calcp.new
puts
puts 'type "Q" to quit.'
puts
while true
if $0 == __FILE__
parser = Calcp.new
puts
print '? '
str = gets.chop!
break if /q/i =~ str
begin
puts "= #{parser.parse(str)}"
rescue ParseError
puts $!
puts 'type "Q" to quit.'
puts
while true
puts
print '? '
str = gets.chop!
break if /q/i =~ str
begin
puts "= #{parser.parse(str)}"
rescue ParseError
puts $!
end
end
end
8 changes: 4 additions & 4 deletions sample/hash.y
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,18 @@ end
when /\A\s+/
str = $'
when /\A\w+/
yield :IDENT, $&
yield [:IDENT, $&]
str = $'
when /\A=>/
yield '=>', '=>'
yield ['=>', '=>']
str = $'
else
c = str[0,1]
yield c, c
yield [c, c]
str = str[1..-1]
end
end
yield false, '$' # is optional from Racc 1.3.7
yield [false, '$'] # is optional from Racc 1.3.7
end

---- footer
Expand Down
9 changes: 5 additions & 4 deletions test/case.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
module Racc
class TestCase < Test::Unit::TestCase
PROJECT_DIR = File.expand_path(File.join(__dir__, '..'))
SAMPLE_DIR = File.join(PROJECT_DIR, 'sample')

test_dir = File.join(PROJECT_DIR, 'test')
test_dir = File.join(PROJECT_DIR, 'racc') unless File.exist?(test_dir)
Expand All @@ -23,6 +24,8 @@ class TestCase < Test::Unit::TestCase
ASSET_DIR = File.join(TEST_DIR, 'assets') # test grammars
REGRESS_DIR = File.join(TEST_DIR, 'regress') # known-good generated outputs

LIB_DIR = File.expand_path("../../lib", __FILE__)

INC = [
File.join(PROJECT_DIR, 'lib'),
File.join(PROJECT_DIR, 'ext'),
Expand Down Expand Up @@ -73,9 +76,8 @@ def assert_debugfile(asset, ok)
end

def assert_exec(asset)
lib_path = File.expand_path("../../lib", __FILE__)
file = File.basename(asset, '.y')
ruby "-I#{lib_path}", "#{@TAB_DIR}/#{file}"
ruby "-I#{LIB_DIR}", "#{@TAB_DIR}/#{file}"
end

def strip_version(source)
Expand All @@ -96,8 +98,7 @@ def assert_output_unchanged(asset)
end

def racc(*arg, **opt)
lib_path = File.expand_path("../../lib", __FILE__)
ruby "-I#{lib_path}", "-S", RACC, *arg, **opt
ruby "-I#{LIB_DIR}", "-S", RACC, *arg, **opt
end

def ruby(*arg, **opt)
Expand Down
80 changes: 80 additions & 0 deletions test/test_sample.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
require File.expand_path('lib/helper', __dir__)

module Racc
class TestSample < TestCase
# working samples
[
{
grammar_file: "array.y",
parser_class: :ArrayParser,
testcases: [
{ input: "[1]", expected: ["1"] },
{ input: "[1, 2]", expected: ["1", "2"] },
]
},
{
grammar_file: "array2.y",
parser_class: :ArrayParser2,
testcases: [
{ input: "[1]", expected: ["1"] },
{ input: "[1, 2]", expected: ["1", "2"] },
]
},
{
grammar_file: "calc.y",
parser_class: :Calcp,
testcases: [
{ input: "1", expected: 1 },
{ input: "10", expected: 10 },
{ input: "2 + 1", expected: 3 },
{ input: "2 - 1", expected: 1 },
{ input: "3 * 4", expected: 12 },
{ input: "4 / 2", expected: 2 },
{ input: "3 / 2", expected: 1 },
{ input: "2 + 3 * 4", expected: 14 },
{ input: "(2 + 3) * 4", expected: 20 },
{ input: "2 + (3 * 4)", expected: 14 },
]
},
{
grammar_file: "hash.y",
parser_class: :HashParser,
testcases: [
{ input: "{}", expected: {} },
{ input: "{ a => b }", expected: { "a" => "b" } },
{ input: "{ a => b, 1 => 2 }", expected: { "a" => "b", "1" => "2" } },
]
},
].each do |data|
define_method "test_#{data[:grammar_file]}" do
outfile = compile_sample(data[:grammar_file])

load(outfile)

parser_class = Object.const_get(data[:parser_class])
data[:testcases].each do |testcase|
input = testcase[:input]
actual = parser_class.new.parse(input)
expected = testcase[:expected]
assert_equal(expected, actual, "expected #{expected} but got #{actual} when input is #{input}")
end
ensure
remove_const_f(data[:parser_class])
end
end

private

# returns the generated file's path
def compile_sample(yfile)
file = File.basename(yfile, '.y')
out = File.join(@OUT_DIR, file)
ruby "-I#{LIB_DIR}", RACC, File.join(SAMPLE_DIR, yfile), "-o#{out}"
out
end

def remove_const_f(const_name)
Object.send(:remove_const, const_name) if Object.const_defined?(const_name, false)
end
end
end