Add specs to fully cover cli.rb
This commit is contained in:
parent
19c32b58dc
commit
2b28ef622d
@ -24,7 +24,7 @@ EOF
|
|||||||
log_file = args[i]
|
log_file = args[i]
|
||||||
end
|
end
|
||||||
when "--version"
|
when "--version"
|
||||||
puts "propane v#{VERSION}"
|
puts "propane version #{VERSION}"
|
||||||
return 0
|
return 0
|
||||||
when "-h", "--help"
|
when "-h", "--help"
|
||||||
puts USAGE
|
puts USAGE
|
||||||
|
@ -13,7 +13,7 @@ describe Propane do
|
|||||||
File.write("spec/run/testparser#{options[:name]}.propane", grammar)
|
File.write("spec/run/testparser#{options[:name]}.propane", grammar)
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_parser(options = {})
|
def run_propane(options = {})
|
||||||
@statics[:build_test_id] ||= 0
|
@statics[:build_test_id] ||= 0
|
||||||
@statics[:build_test_id] += 1
|
@statics[:build_test_id] += 1
|
||||||
if ENV["dist_specs"]
|
if ENV["dist_specs"]
|
||||||
@ -49,7 +49,11 @@ ENV["TERM"] = nil
|
|||||||
EOF
|
EOF
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
command += %W[spec/run/testparser#{options[:name]}.propane spec/run/testparser#{options[:name]}.#{options[:language]} --log spec/run/testparser#{options[:name]}.log]
|
if options[:args]
|
||||||
|
command += options[:args]
|
||||||
|
else
|
||||||
|
command += %W[spec/run/testparser#{options[:name]}.propane spec/run/testparser#{options[:name]}.#{options[:language]} --log spec/run/testparser#{options[:name]}.log]
|
||||||
|
end
|
||||||
if (options[:capture])
|
if (options[:capture])
|
||||||
stdout, stderr, status = Open3.capture3(*command)
|
stdout, stderr, status = Open3.capture3(*command)
|
||||||
Results.new(stdout, stderr, status)
|
Results.new(stdout, stderr, status)
|
||||||
@ -74,7 +78,7 @@ EOF
|
|||||||
expect(result).to be_truthy
|
expect(result).to be_truthy
|
||||||
end
|
end
|
||||||
|
|
||||||
def run
|
def run_test
|
||||||
stdout, stderr, status = Open3.capture3("spec/run/testparser")
|
stdout, stderr, status = Open3.capture3("spec/run/testparser")
|
||||||
File.binwrite("spec/run/.stderr", stderr)
|
File.binwrite("spec/run/.stderr", stderr)
|
||||||
File.binwrite("spec/run/.stdout", stdout)
|
File.binwrite("spec/run/.stdout", stdout)
|
||||||
@ -112,6 +116,38 @@ EOF
|
|||||||
FileUtils.mkdir_p("spec/run")
|
FileUtils.mkdir_p("spec/run")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "reports its version" do
|
||||||
|
results = run_propane(args: %w[--version], capture: true)
|
||||||
|
expect(results.stdout).to match /propane version \d+\.\d+/
|
||||||
|
expect(results.stderr).to eq ""
|
||||||
|
expect(results.status).to eq 0
|
||||||
|
end
|
||||||
|
|
||||||
|
it "shows help usage" do
|
||||||
|
results = run_propane(args: %w[-h], capture: true)
|
||||||
|
expect(results.stdout).to match /Usage/i
|
||||||
|
expect(results.stderr).to eq ""
|
||||||
|
expect(results.status).to eq 0
|
||||||
|
end
|
||||||
|
|
||||||
|
it "errors with unknown option" do
|
||||||
|
results = run_propane(args: %w[-i], capture: true)
|
||||||
|
expect(results.stderr).to match /Error: unknown option -i/
|
||||||
|
expect(results.status).to_not eq 0
|
||||||
|
end
|
||||||
|
|
||||||
|
it "errors when input and output files are not specified" do
|
||||||
|
results = run_propane(args: [], capture: true)
|
||||||
|
expect(results.stderr).to match /Error: specify input and output files/
|
||||||
|
expect(results.status).to_not eq 0
|
||||||
|
end
|
||||||
|
|
||||||
|
it "errors when input file is not readable" do
|
||||||
|
results = run_propane(args: %w[nope.txt out.d], capture: true)
|
||||||
|
expect(results.stderr).to match /Error: cannot read nope.txt/
|
||||||
|
expect(results.status).to_not eq 0
|
||||||
|
end
|
||||||
|
|
||||||
%w[d c].each do |language|
|
%w[d c].each do |language|
|
||||||
|
|
||||||
context "#{language.upcase} language" do
|
context "#{language.upcase} language" do
|
||||||
@ -126,9 +162,9 @@ Start -> Foo;
|
|||||||
Foo -> int <<>>
|
Foo -> int <<>>
|
||||||
Foo -> plus <<>>
|
Foo -> plus <<>>
|
||||||
EOF
|
EOF
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
compile("spec/test_lexer.#{language}", language: language)
|
compile("spec/test_lexer.#{language}", language: language)
|
||||||
results = run
|
results = run_test
|
||||||
expect(results.stderr).to eq ""
|
expect(results.stderr).to eq ""
|
||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
end
|
end
|
||||||
@ -164,9 +200,9 @@ token int /\\d+/ <<
|
|||||||
Start -> int << $$ = $1; >>
|
Start -> int << $$ = $1; >>
|
||||||
EOF
|
EOF
|
||||||
end
|
end
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
compile("spec/test_lexer_unknown_character.#{language}", language: language)
|
compile("spec/test_lexer_unknown_character.#{language}", language: language)
|
||||||
results = run
|
results = run_test
|
||||||
expect(results.stderr).to eq ""
|
expect(results.stderr).to eq ""
|
||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
end
|
end
|
||||||
@ -184,7 +220,7 @@ E -> B;
|
|||||||
B -> zero;
|
B -> zero;
|
||||||
B -> one;
|
B -> one;
|
||||||
EOF
|
EOF
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "generates a parser that does basic math - user guide example" do
|
it "generates a parser that does basic math - user guide example" do
|
||||||
@ -258,9 +294,9 @@ E4 -> integer << $$ = $1; >>
|
|||||||
E4 -> lparen E1 rparen << $$ = $2; >>
|
E4 -> lparen E1 rparen << $$ = $2; >>
|
||||||
EOF
|
EOF
|
||||||
end
|
end
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
compile("spec/test_basic_math_grammar.#{language}", language: language)
|
compile("spec/test_basic_math_grammar.#{language}", language: language)
|
||||||
results = run
|
results = run_test
|
||||||
expect(results.stderr).to eq ""
|
expect(results.stderr).to eq ""
|
||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
end
|
end
|
||||||
@ -272,7 +308,7 @@ Start -> E;
|
|||||||
E -> one E;
|
E -> one E;
|
||||||
E -> one;
|
E -> one;
|
||||||
EOF
|
EOF
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "distinguishes between multiple identical rules with lookahead symbol" do
|
it "distinguishes between multiple identical rules with lookahead symbol" do
|
||||||
@ -284,9 +320,9 @@ Start -> R2 b;
|
|||||||
R1 -> a b;
|
R1 -> a b;
|
||||||
R2 -> a b;
|
R2 -> a b;
|
||||||
EOF
|
EOF
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
compile("spec/test_parser_identical_rules_lookahead.#{language}", language: language)
|
compile("spec/test_parser_identical_rules_lookahead.#{language}", language: language)
|
||||||
results = run
|
results = run_test
|
||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -299,9 +335,9 @@ Start -> a R1;
|
|||||||
Start -> b R1;
|
Start -> b R1;
|
||||||
R1 -> b;
|
R1 -> b;
|
||||||
EOF
|
EOF
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
compile("spec/test_parser_rule_from_multiple_states.#{language}", language: language)
|
compile("spec/test_parser_rule_from_multiple_states.#{language}", language: language)
|
||||||
results = run
|
results = run_test
|
||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -334,9 +370,9 @@ Abcs -> ;
|
|||||||
Abcs -> abc Abcs;
|
Abcs -> abc Abcs;
|
||||||
EOF
|
EOF
|
||||||
end
|
end
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
compile("spec/test_user_code.#{language}", language: language)
|
compile("spec/test_user_code.#{language}", language: language)
|
||||||
results = run
|
results = run_test
|
||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
verify_lines(results.stdout, [
|
verify_lines(results.stdout, [
|
||||||
"abc!",
|
"abc!",
|
||||||
@ -370,9 +406,9 @@ token abc;
|
|||||||
Start -> abc;
|
Start -> abc;
|
||||||
EOF
|
EOF
|
||||||
end
|
end
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
compile("spec/test_pattern.#{language}", language: language)
|
compile("spec/test_pattern.#{language}", language: language)
|
||||||
results = run
|
results = run_test
|
||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
verify_lines(results.stdout, [
|
verify_lines(results.stdout, [
|
||||||
"def!",
|
"def!",
|
||||||
@ -412,9 +448,9 @@ token abc;
|
|||||||
Start -> abc;
|
Start -> abc;
|
||||||
EOF
|
EOF
|
||||||
end
|
end
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
compile("spec/test_return_token_from_pattern.#{language}", language: language)
|
compile("spec/test_return_token_from_pattern.#{language}", language: language)
|
||||||
results = run
|
results = run_test
|
||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
verify_lines(results.stdout, [
|
verify_lines(results.stdout, [
|
||||||
"def!",
|
"def!",
|
||||||
@ -470,9 +506,9 @@ string: /"/ <<
|
|||||||
Start -> abc string def;
|
Start -> abc string def;
|
||||||
EOF
|
EOF
|
||||||
end
|
end
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
compile("spec/test_lexer_modes.#{language}", language: language)
|
compile("spec/test_lexer_modes.#{language}", language: language)
|
||||||
results = run
|
results = run_test
|
||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
verify_lines(results.stdout, [
|
verify_lines(results.stdout, [
|
||||||
"begin string mode",
|
"begin string mode",
|
||||||
@ -509,9 +545,9 @@ A -> a << writeln("A!"); >>
|
|||||||
B -> b << writeln("B!"); >>
|
B -> b << writeln("B!"); >>
|
||||||
EOF
|
EOF
|
||||||
end
|
end
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
compile("spec/test_parser_rule_user_code.#{language}", language: language)
|
compile("spec/test_parser_rule_user_code.#{language}", language: language)
|
||||||
results = run
|
results = run_test
|
||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
verify_lines(results.stdout, [
|
verify_lines(results.stdout, [
|
||||||
"A!",
|
"A!",
|
||||||
@ -528,9 +564,9 @@ Start -> As << $$ = $1; >>
|
|||||||
As -> << $$ = 0u; >>
|
As -> << $$ = 0u; >>
|
||||||
As -> As a << $$ = $1 + 1u; >>
|
As -> As a << $$ = $1 + 1u; >>
|
||||||
EOF
|
EOF
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
compile("spec/test_parsing_lists.#{language}", language: language)
|
compile("spec/test_parsing_lists.#{language}", language: language)
|
||||||
results = run
|
results = run_test
|
||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
expect(results.stderr).to eq ""
|
expect(results.stderr).to eq ""
|
||||||
end
|
end
|
||||||
@ -549,7 +585,7 @@ Start -> b E d;
|
|||||||
E -> e;
|
E -> e;
|
||||||
F -> e;
|
F -> e;
|
||||||
EOF
|
EOF
|
||||||
results = build_parser(capture: true, language: language)
|
results = run_propane(capture: true, language: language)
|
||||||
expect(results.status).to_not eq 0
|
expect(results.status).to_not eq 0
|
||||||
expect(results.stderr).to match %r{reduce/reduce conflict.*\(E\).*\(F\)}
|
expect(results.stderr).to match %r{reduce/reduce conflict.*\(E\).*\(F\)}
|
||||||
end
|
end
|
||||||
@ -581,9 +617,9 @@ token id /[a-zA-Z_][a-zA-Z0-9_]*/ <<
|
|||||||
Start -> id;
|
Start -> id;
|
||||||
EOF
|
EOF
|
||||||
end
|
end
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
compile("spec/test_lexer_match_text.#{language}", language: language)
|
compile("spec/test_lexer_match_text.#{language}", language: language)
|
||||||
results = run
|
results = run_test
|
||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
verify_lines(results.stdout, [
|
verify_lines(results.stdout, [
|
||||||
"Matched token is identifier_123",
|
"Matched token is identifier_123",
|
||||||
@ -614,9 +650,9 @@ Start -> word <<
|
|||||||
>>
|
>>
|
||||||
EOF
|
EOF
|
||||||
end
|
end
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
compile("spec/test_lexer_result_value.#{language}", language: language)
|
compile("spec/test_lexer_result_value.#{language}", language: language)
|
||||||
results = run
|
results = run_test
|
||||||
expect(results.stderr).to eq ""
|
expect(results.stderr).to eq ""
|
||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
end
|
end
|
||||||
@ -629,16 +665,16 @@ drop /\\s+/;
|
|||||||
Start -> a num Start;
|
Start -> a num Start;
|
||||||
Start -> a num;
|
Start -> a num;
|
||||||
EOF
|
EOF
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
compile("spec/test_error_positions.#{language}", language: language)
|
compile("spec/test_error_positions.#{language}", language: language)
|
||||||
results = run
|
results = run_test
|
||||||
expect(results.stderr).to eq ""
|
expect(results.stderr).to eq ""
|
||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
end
|
end
|
||||||
|
|
||||||
it "allows creating a JSON parser" do
|
it "allows creating a JSON parser" do
|
||||||
write_grammar(File.read("spec/json_parser.#{language}.propane"))
|
write_grammar(File.read("spec/json_parser.#{language}.propane"))
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
compile(["spec/test_parsing_json.#{language}", "spec/json_types.#{language}"], language: language)
|
compile(["spec/test_parsing_json.#{language}", "spec/json_types.#{language}"], language: language)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -650,16 +686,16 @@ token num /\\d+/;
|
|||||||
drop /\\s+/;
|
drop /\\s+/;
|
||||||
Start -> a num;
|
Start -> a num;
|
||||||
EOF
|
EOF
|
||||||
build_parser(name: "myp1", language: language)
|
run_propane(name: "myp1", language: language)
|
||||||
write_grammar(<<EOF, name: "myp2")
|
write_grammar(<<EOF, name: "myp2")
|
||||||
prefix myp2_;
|
prefix myp2_;
|
||||||
token b;
|
token b;
|
||||||
token c;
|
token c;
|
||||||
Start -> b c b;
|
Start -> b c b;
|
||||||
EOF
|
EOF
|
||||||
build_parser(name: "myp2", language: language)
|
run_propane(name: "myp2", language: language)
|
||||||
compile("spec/test_multiple_parsers.#{language}", parsers: %w[myp1 myp2], language: language)
|
compile("spec/test_multiple_parsers.#{language}", parsers: %w[myp1 myp2], language: language)
|
||||||
results = run
|
results = run_test
|
||||||
expect(results.stderr).to eq ""
|
expect(results.stderr).to eq ""
|
||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
end
|
end
|
||||||
@ -676,9 +712,9 @@ Any -> a;
|
|||||||
Any -> b;
|
Any -> b;
|
||||||
Any -> c;
|
Any -> c;
|
||||||
EOF
|
EOF
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
compile("spec/test_user_terminate_lexer.#{language}", language: language)
|
compile("spec/test_user_terminate_lexer.#{language}", language: language)
|
||||||
results = run
|
results = run_test
|
||||||
expect(results.stderr).to eq ""
|
expect(results.stderr).to eq ""
|
||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
end
|
end
|
||||||
@ -694,9 +730,9 @@ Any -> b Any << $terminate(4200); >>
|
|||||||
Any -> c Any;
|
Any -> c Any;
|
||||||
Any -> ;
|
Any -> ;
|
||||||
EOF
|
EOF
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
compile("spec/test_user_terminate.#{language}", language: language)
|
compile("spec/test_user_terminate.#{language}", language: language)
|
||||||
results = run
|
results = run_test
|
||||||
expect(results.stderr).to eq ""
|
expect(results.stderr).to eq ""
|
||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
end
|
end
|
||||||
@ -738,9 +774,9 @@ tokenid t;
|
|||||||
Start -> t;
|
Start -> t;
|
||||||
EOF
|
EOF
|
||||||
end
|
end
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
compile("spec/test_match_backslashes.#{language}", language: language)
|
compile("spec/test_match_backslashes.#{language}", language: language)
|
||||||
results = run
|
results = run_test
|
||||||
expect(results.stderr).to eq ""
|
expect(results.stderr).to eq ""
|
||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
verify_lines(results.stdout, [
|
verify_lines(results.stdout, [
|
||||||
@ -765,7 +801,7 @@ Start -> ;
|
|||||||
Opt -> two;
|
Opt -> two;
|
||||||
Opt -> ;
|
Opt -> ;
|
||||||
EOF
|
EOF
|
||||||
build_parser(language: language)
|
run_propane(language: language)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user