Skip to content

Commit

Permalink
clean up arg processor interface a bit
Browse files Browse the repository at this point in the history
- no more throwing exit, instead commands check to see if the processor says it should exit.
- use stderr for printing arg errors
- tests for arg processor
  • Loading branch information
baroquebobcat committed Apr 23, 2012
1 parent 040d276 commit 79c6c66
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 15 deletions.
5 changes: 4 additions & 1 deletion lib/mirah/commands/base.rb
Expand Up @@ -33,12 +33,15 @@ def initialize(args)
attr_accessor :state, :args, :argument_processor

def execute_base
argument_processor.process
if argument_processor.exit?
exit argument_processor.exit_status_code
end
# because MirahCommand is a JRuby Java class, SystemExit bubbles through and makes noise
# so we use a catch/throw to early exit instead
# see util/process_errors.rb
status = catch(:exit) do
begin
argument_processor.process
yield
rescue Mirah::InternalCompilerError => ice
Mirah.print_error(ice.message, ice.position) if ice.node
Expand Down
33 changes: 22 additions & 11 deletions lib/mirah/util/argument_processor.rb
Expand Up @@ -24,7 +24,9 @@ def initialize(state, args)
@args = args
end

attr_accessor :state, :args
attr_accessor :state, :args, :exit_status_code

alias exit? exit_status_code

def process
state.args = args
Expand All @@ -46,16 +48,17 @@ def process
Mirah::AST::Script.explicit_packages = true
when '--help', '-h'
print_help
throw :exit, 0

self.exit_status_code = 0
when '--java', '-j'
if state.command == :compile
require 'mirah/jvm/compiler/java_source'
state.compiler_class = Mirah::JVM::Compiler::JavaSource
args.shift
else
puts "-j/--java flag only applies to \"compile\" mode."
print_help
throw :exit, 1
$stderr.puts "-j/--java flag only applies to \"compile\" mode."

self.exit_status_code = 1
end
when '--jvm'
args.shift
Expand Down Expand Up @@ -87,22 +90,31 @@ def process
when '--version', '-v'
args.shift
print_version
throw :exit, 0 if args.empty?

self.exit_status_code = 0 if args.empty?
when '--no-save-extensions'
args.shift
state.save_extensions = false
else
puts "unrecognized flag: " + args[0]
print_help
throw :exit, 1
$stderr.puts "unrecognized flag: " + args[0]

self.exit_status_code = 1
end
end

return if exit?

state.destination ||= File.join(File.expand_path('.'), '')
state.compiler_class ||= Mirah::JVM::Compiler::JVMBytecode
end

def print_help
puts "#{$0} [flags] <files or -e SCRIPT>
puts help_message
state.help_printed = true
end

def help_message
"#{$0} [flags] <files or -e SCRIPT>
-c, --classpath PATH\tAdd PATH to the Java classpath for compilation
--cd DIR\t\tSwitch to the specified DIR befor compilation
-d, --dir DIR\t\tUse DIR as the base dir for compilation, packages
Expand All @@ -118,7 +130,6 @@ def print_help
-v, --version\t\tPrint the version of Mirah to the console
-V, --verbose\t\tVerbose logging
--vmodule logger.name=LEVEL[,...]\t\tSet the Level for the specified Java loggers"
state.help_printed = true
end

def print_version
Expand Down
12 changes: 10 additions & 2 deletions test/core/commands_test.rb
Expand Up @@ -51,10 +51,11 @@ def test_on_bad_argument_has_non_zero_exit_code
end

def test_on_v_with_no_args_exits_without_running_command
assert RaisesMirahErrorCommand.new(['-v']).execute
assert_zero_exit do
RaisesMirahErrorCommand.new(['-v']).execute
end
end


def test_on_j_option_when_command_is_not_compile_has_non_zero_exit_code
assert_non_zero_exit do
RaisesMirahErrorCommand.new(['-j']).execute
Expand All @@ -78,4 +79,11 @@ def assert_non_zero_exit
assert_not_equal 0, ex.status
end

def assert_zero_exit
ex = assert_raise SystemExit do
yield
end
assert_equal 0, ex.status
end

end
64 changes: 64 additions & 0 deletions test/core/util/argument_processor_test.rb
@@ -0,0 +1,64 @@
require 'test_helper'

class ArgumentProcessorTest < Test::Unit::TestCase

def test_arg_dash_v_prints_version_and_has_exit_0
state = Mirah::Util::CompilationState.new
processor = Mirah::Util::ArgumentProcessor.new state, ["-v"]

assert_output "Mirah v#{Mirah::VERSION}\n" do
processor.process
end

assert processor.exit?
assert_equal 0, processor.exit_status_code
end


def test_on_invalid_arg_prints_error_and_exits_1
state = Mirah::Util::CompilationState.new
processor = Mirah::Util::ArgumentProcessor.new state, ["--some-arg"]

assert_output "unrecognized flag: --some-arg\n" do
processor.process
end

assert processor.exit?
assert_equal 1, processor.exit_status_code
end

def test_arg_bootclasspath_sets_bootclasspath_on_type_factory_ugh
Mirah::AST.type_factory = Mirah::JVM::Types::TypeFactory.new # global state grumble grumble

path = "class:path"
state = Mirah::Util::CompilationState.new
processor = Mirah::Util::ArgumentProcessor.new state, ["--bootclasspath", path]
processor.process

assert_equal path, Mirah::AST.type_factory.bootclasspath
end

def test_dash_j_fails_when_not_compiling
state = Mirah::Util::CompilationState.new
processor = Mirah::Util::ArgumentProcessor.new state, ["-j"]

assert_output "-j/--java flag only applies to \"compile\" mode.\n" do
processor.process
end

assert processor.exit?
assert_equal 1, processor.exit_status_code
end

def test_dash_h_prints_help_and_exits
state = Mirah::Util::CompilationState.new
processor = Mirah::Util::ArgumentProcessor.new state, ["-h"]

assert_output processor.help_message + "\n" do
processor.process
end

assert processor.exit?
assert_equal 0, processor.exit_status_code
end
end
1 change: 0 additions & 1 deletion test/jvm/bytecode_test_helper.rb
Expand Up @@ -162,7 +162,6 @@ def assert_output(expected, &block)

class Test::Unit::TestCase
include JVMCompiler
include CommonAssertions

def setup
@tmp_classes = []
Expand Down
40 changes: 40 additions & 0 deletions test/test_helper.rb
Expand Up @@ -17,3 +17,43 @@
require 'mirah'
require 'jruby'
require 'turn'

module CommonAssertions
import java.lang.System
import java.io.PrintStream

def assert_include(value, array, message=nil)
message = build_message message, '<?> does not include <?>', array, value
assert_block message do
array.include? value
end
end

def capture_output
saved_output = System.out
saved_stdout = $stdout
saved_stderr = $stderr
output = StringIO.new
System.setOut(PrintStream.new(output.to_outputstream))
$stdout = output
$stderr = output
begin
yield
output.rewind
output.read
ensure
System.setOut(saved_output)
$stdout = saved_stdout
$stderr = saved_stderr
end
end

def assert_output(expected, &block)
assert_equal(expected, capture_output(&block))
end

end

class Test::Unit::TestCase
include CommonAssertions
end

0 comments on commit 79c6c66

Please sign in to comment.