lib/rgot/cli.rb in rgot-1.1.0 vs lib/rgot/cli.rb in rgot-1.2.0

- old
+ new

@@ -1,5 +1,7 @@ +# frozen_string_literal: true + require 'optparse' require_relative '../rgot' module Rgot @@ -9,11 +11,11 @@ end def run opts = Rgot::M::Options.new parse_option(opts) - process_start(opts) + main_process(opts) end private def parse_option(opts) @@ -72,83 +74,84 @@ end end.compact end end - def process_start(opts) + def main_process(opts) code = 0 - testing_files.map do |testing_file| - begin - pid = fork do - require testing_file - modules = Object.constants.select { |c| - next if c == :FileTest - /.*Test\z/ =~ c - }.map { |c| - Object.const_get(c) - } + testing_files.each do |testing_file| + result = child_process(opts, testing_file) + unless result == 0 + code = 1 + end + end - modules.each do |test_module| - tests = [] - benchmarks = [] - examples = [] - main = nil - methods = test_module.instance_methods - methods.grep(/\Atest_/).each do |m| - if m == :test_main && main.nil? - main = Rgot::InternalTest.new(test_module, m) - else - tests << Rgot::InternalTest.new(test_module, m) - end - end + code + end - methods.grep(/\Abenchmark_/).each do |m| - benchmarks << Rgot::InternalBenchmark.new(test_module, m) - end + def child_process(opts, testing_file) + node = RubyVM::AbstractSyntaxTree.parse_file(testing_file).children[2] + test_module_name = find_toplevel_name(node) - methods.grep(/\Aexample_?/).each do |m| - examples << Rgot::InternalExample.new(test_module, m) - end + load testing_file - duration = Rgot.now - at_exit do - template = "%s\t%s\t%.3fs" - - case $! - when SystemExit - if $!.success? - # exit 0 - puts sprintf(template, "ok ", test_module, Rgot.now - duration) - else - # exit 1 - puts "exit status #{$!.status}" - puts sprintf(template, "FAIL", test_module, Rgot.now - duration) - end - when NilClass - # not raise, not exit - else - # any exception - puts sprintf(template, "FAIL", test_module, Rgot.now - duration) - end - end - m = Rgot::M.new(tests: tests, benchmarks: benchmarks, examples: examples, opts: opts) - if main - main.module.extend main.module - main.module.instance_method(main.name).bind(main.module).call(m) - else - exit m.run - end - end - end - ensure - _, status = Process.waitpid2(pid) - unless status.success? - code = 1 - end + test_module = Object.const_get(test_module_name) + tests = [] + benchmarks = [] + examples = [] + main = nil + methods = test_module.public_instance_methods + methods.grep(/\Atest_/).each do |m| + if m == :test_main && main.nil? + main = Rgot::InternalTest.new(test_module, m) + else + tests << Rgot::InternalTest.new(test_module, m) end end - exit code + methods.grep(/\Abenchmark_/).each do |m| + benchmarks << Rgot::InternalBenchmark.new(test_module, m) + end + + methods.grep(/\Aexample_?/).each do |m| + examples << Rgot::InternalExample.new(test_module, m) + end + + m = Rgot::M.new(test_module: test_module, tests: tests, benchmarks: benchmarks, examples: examples, opts: opts) + if main + main.module.extend main.module + main.module.instance_method(:test_main).bind(main.module).call(m) + else + m.run + end + end + + private + + def find_toplevel_name(node) + case node.type + when :MODULE + find_toplevel_name(node.children.first) + when :CONST, :COLON3 + node.children.first + when :COLON2 + case node.children + in [nil, sym] + # module Foo + sym + in [namespace, sym] + # module Foo::Bar + find_toplevel_name(namespace) + end + when :BLOCK + module_node = node.children.find { |c| c.type == :MODULE } + unless module_node + raise "no module found" + end + find_toplevel_name(module_node) + else + raise node.type.to_s + end end end end