class Rgot::Cli

Public Class Methods

new(argv) click to toggle source
# File lib/rgot/cli.rb, line 9
def initialize(argv)
  @argv = argv
end

Public Instance Methods

run() click to toggle source
# File lib/rgot/cli.rb, line 13
def run
  opts = Rgot::M::Options.new
  parse_option(opts)
  main_process(opts)
end

Private Instance Methods

child_process(opts, testing_file) click to toggle source
# File lib/rgot/cli.rb, line 101
def child_process(opts, testing_file)
  node = RubyVM::AbstractSyntaxTree.parse_file(testing_file).children[2]
  test_module_name = find_toplevel_name(node)

  if opts.fuzz
    # fuzzing observes changes in coverage.
    require 'coverage'
    Coverage.start(oneshot_lines: true)
  end
  load testing_file

  test_module = Object.const_get(test_module_name)
  tests = []
  benchmarks = []
  examples = []
  fuzz_targets = []
  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

  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

  methods.grep(/\Afuzz_/).each do |m|
    fuzz_targets << Rgot::InternalFuzzTarget.new(test_module, m)
  end

  m = Rgot::M.new(
    test_module: test_module,
    tests: tests,
    benchmarks: benchmarks,
    examples: examples,
    fuzz_targets: fuzz_targets,
    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
find_toplevel_name(node) click to toggle source
# File lib/rgot/cli.rb, line 155
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_nodes = node.children.select do |c|
      c.type == :MODULE && find_toplevel_name(c).end_with?("Test")
    end
    raise "no module found" if module_nodes.empty?
    raise "*Test module should be one for each file" if 1 < module_nodes.length

    find_toplevel_name(module_nodes.first)
  else
    raise node.type.to_s
  end
end
main_process(opts) click to toggle source
# File lib/rgot/cli.rb, line 88
def main_process(opts)
  code = 0

  testing_files.each do |testing_file|
    result = child_process(opts, testing_file)
    unless result == 0
      code = 1
    end
  end

  code
end
parse_option(opts) click to toggle source
# File lib/rgot/cli.rb, line 21
def parse_option(opts)
  require_paths = []
  parser = OptionParser.new do |o|
    o.on '-v', '--verbose', "log all tests" do |arg|
      Rgot.class_eval { @chatty = arg }
    end
    o.on '--version', "show Rgot version" do |arg|
      puts "rgot #{Rgot::VERSION} (ruby #{RUBY_VERSION})"
      exit 0
    end
    o.on '--bench [regexp]', "benchmark" do |arg|
      unless arg
        raise Rgot::OptionError, "missing argument for flag --bench"
      end
      opts.bench = arg
    end
    o.on '--benchtime [sec]', "benchmark running time" do |arg|
      opts.benchtime = arg
    end
    o.on '--timeout [sec]', "set timeout sec to testing" do |arg|
      opts.timeout = arg
    end
    o.on '--cpu [count,...]', "set cpu counts of comma split" do |arg|
      opts.cpu = arg
    end
    o.on '--thread [count,...]', "set thread counts of comma split" do |arg|
      opts.thread = arg
    end
    o.on '--require [path]', "load some code before running" do |arg|
      require_paths << arg
    end
    o.on '--load-path [path]', "Specify $LOAD_PATH directory" do |arg|
      $LOAD_PATH.unshift(arg)
    end
    o.on '--fuzz [regexp]', "run the fuzz test matching `regexp`" do |arg|
      unless arg
        raise Rgot::OptionError, "missing argument for flag --fuzz"
      end
      opts.fuzz = arg
    end
    o.on '--fuzztime [sec]', "time to spend fuzzing; default is to run indefinitely" do |arg|
      opts.fuzztime = arg
    end
  end
  parser.parse!(@argv)

  require_paths.each do |path|
    require path
  end
end
testing_files() click to toggle source
# File lib/rgot/cli.rb, line 72
def testing_files
  if @argv.empty?
    Dir.glob("./**/*_test.rb")
  else
    @argv.flat_map do |target|
      if File.file?(target)
        File.expand_path(target)
      elsif File.directory?(target)
        Dir.glob("./#{target}/**/*_test.rb")
      else
        warn "#{target} is not file or directory"
      end
    end.compact
  end
end