#This is a utility script for generating tests from reported warnings.
#
#It is not heavily tested. It is mostly for the convenience of coders. Sometimes
#it generates broken code which will need to be fixed manually.
#
#Usage:
#
#  ruby to_test.rb apps/some_app > tests/test_some_app.rb`

# Set paths
$LOAD_PATH.unshift "#{File.expand_path(File.dirname(__FILE__))}/../lib"

require 'brakeman'
require 'ruby_parser'
require 'ruby_parser/bm_sexp'
require 'brakeman/options'
require 'brakeman/report/report_base'

class Brakeman::Report::Tests < Brakeman::Report::Base
  def generate_report
    counter = 0

    name = camelize File.basename(tracker.app_path)

    output = <<-RUBY
abort "Please run using test/test.rb" unless defined? BrakemanTester

#{name} = BrakemanTester.run_scan "#{File.basename tracker.app_path}", "#{name}"

class #{name}Tests < Test::Unit::TestCase
  include BrakemanTester::FindWarning
  include BrakemanTester::CheckExpected

  def expected
    @expected ||= {
      :controller => #{@checks.controller_warnings.length},
      :model => #{@checks.model_warnings.length},
      :template => #{@checks.template_warnings.length},
      :warning => #{@checks.warnings.length} }
  end

  def report
    #{name}
  end

    RUBY

    output << @checks.all_warnings.map do |w|
      counter += 1

      <<-RUBY
  def test_#{w.warning_type.to_s.downcase.tr(" -", "__")}_#{counter}
    assert_warning check_name: #{w.check_name.inspect},
      type: #{w.warning_set.inspect},
      warning_code: #{w.warning_code},
      fingerprint: #{w.fingerprint.inspect},
      warning_type: #{w.warning_type.inspect},
      line: #{w.line.inspect},
      message: /^#{Regexp.escape w.message.to_s[0,40]}/,
      confidence: #{w.confidence},
      relative_path: #{w.file.relative.inspect},
      code: #{w.code.inspect},
      user_input: #{w.user_input.inspect}
  end
      RUBY
    end.join("\n")

    output << "\nend"
  end
end

options, _ = Brakeman::Options.parse!(ARGV)

unless options[:app_path]
  if ARGV[-1].nil?
    options[:app_path] = "."
  else
    options[:app_path] = ARGV[-1]
  end
end

tracker = Brakeman.run options

puts Brakeman::Report::Tests.new(tracker).generate_report
