#!/usr/local/bin/ruby -w

# TODO: Probably has dup code with ZenTest.
# TODO: Map controller assert_assigns to view test ivar assignments.
# TODO: Make this a rake task, rake test:audit.

# test_cases[test_case][test][ivar] = value
def build_test_cases(type)
  test_cases = Hash.new { |h,k|
    h[k] = Hash.new { |h,k|
      h[k] = Hash.new { |h,k|
        h[k] = {} } } }

  test_case = nil
  test = nil

  fixtures = Hash.new { |h,k| h[k] = [] }

  Dir["test/#{type}/*rb"].each do |test|
    File.open test do |fp|
      fp.each_line do |line|
        case line
        when /^class (.*)(View|Controller)Test </
          test_case = $1
        when /^\s+def (test_\S+)/
          test = $1
        when /^\s+controller\[(.+?)\] = (.*)$/,
             /^\s+assert_assigned (.*?), (.*)/
          ivar = $1
          value = $2
          test_cases[test_case][test][ivar] = value
        when /fixtures (.*)/ then
          fixtures[test_case].push(*$1.split(', '))
        end
      end
    end
  end

  return test_cases, fixtures
end

view_test_cases, view_fixtures = build_test_cases 'views'
controller_test_cases, controller_fixtures = build_test_cases 'controller'

out = []

view_test_cases.sort_by { |tc,_| tc }.each do |test_case, tests|
  out << "require 'test/test_helper'"
  out << nil
  out << "class #{test_case}ControllerTest < Test::Rails::ControllerTestCase"
  out << nil

  fixtures = controller_fixtures[test_case] - view_fixtures[test_case]

  unless fixtures.empty? then
    fixtures.each do |fixture|
      out << "  fixtures #{fixture}"
    end
    out << nil
  end

  tests.sort_by { |t,_| t }.each do |test, ivars|
    ivars = view_test_cases[test_case][test].keys -
            controller_test_cases[test_case][test].keys

    next if ivars.empty?

    out << "  def #{test}"
    ivars.sort.each do |ivar|
      value = view_test_cases[test_case][test][ivar]
      out << "    assert_assigned #{ivar}, #{value}"
    end
    out << "  end"
    out << nil
  end
  out << "end"
  out << nil
end

puts out.join("\n")
