# encoding: utf-8
#
#  = MO Test Suites
#
#  This is the "boot" script for out unit tests.  The important sequence is:
#
#  1) Set environment to "TEST".
#  2) Run config/environment.rb, booting our application and rails.
#  3) Include the rails test extensions (test_help).
#  4) Include out own core extensions (everything else is auto-loaded).
#  5) Load our own test cases and extensions (all the files in this directory).
#  6) Test::Unit magically runs everything in an +atexit+ hook.
#
#  It is, furthermore, worth knowing how and where rails meddles with the
#  standard Test::Unit process.  Its extensions are scattered among all the
#  "frameworks":
#
#  active_support/test_case::       Adds +setup+ and +teardown+ callback support.
#  active_record/fixtures::         Adds +fixtures+ support.
#  action_controller/test_case::    Adds a handy +setup+ callback.
#  action_controller/test_process:: Defines fake request and response classes and much more.
#  action_controller/integration::  Very confusing mix of Session and TestCase, I'm stumped.
#  action_mailer/test_case::        ...
#  active_support/core_ext/test::   ...
#
#  == MO Test Cases
#
#  UnitTestCase::        Used by unit tests, just derives from Test::Unit::TestCase.
#  FunctionalTestCase::  Used by functional tests, derives from ActionController::TestCase.
#  IntegrationTestCase:: Used by integration tests, similar to ActionController::IntegrationTest.
#  IntegrationSession::  Used by integration tests, derived from ActionController::Integration::Session
#
#  == MO Test Extensions
#
#  GeneralExtensions::     Generally useful MO-specific assertions.
#  ControllerExtensions::  Several additional helpers used by functional tests.
#  FlashExtensions::       Encapsulates flash error mechanism (used by functional and integration tests).
#  IntegrationExtensions:: Some high-level integration test helpers.
#  SessionExtensions::     Several very handy extensions to the Rails integration tester.
#
#  == Notes
#
#  The Rails integration test case did not allow us to subclass the test
#  session class, and did not give us proper control over things like cookies.
#  So I've rewritten it minimally.  It did very little to start with, so this
#  was actually the easiest way to go.  See the notes on IntegrationTestCase
#  for better documentation of the (few) differences.
#
#  Beware, Rails has polluted Test::Unit::TestCase with a bunch of
#  controller-related stuff.  This all comes from ActionController::TestProcess
#  module.
#
#  Also note that this file used to be called +test_helper.rb+.  However it
#  turns out that rake would include it once, while all our test units were
#  including it a second time.  We _must_ do the latter, because that's how
#  this file gets included when running tests individually from the command
#  line: 
#
#    ruby -Ilib:test test/units/api_test.rb
#
#  Ergo, the former must go.  Thus, I renamed it to something rake doesn't know
#  about.  The problem was it was registering our application-wide setup and
#  teardown callbacks twice, with highly erratic and unpleasant results.
#
################################################################################

ENV['RAILS_ENV'] = 'test'
require File.expand_path(File.dirname(__FILE__) + '/../config/environment')
require 'test_help'
require 'extensions'

# Load all of our test cases and extensions.
for file in %w(
  general_extensions
  flash_extensions
  controller_extensions
  integration_extensions
  session_extensions
  session_form_extensions
  test_case
  unit_test_case
  functional_test_case
  integration_test_case
  integration_session
  language_extensions
)
  require File.expand_path(File.dirname(__FILE__) + "/#{file}")
end

# Used to test image uploads.  The normal "live" params[:upload] is
# essentially a file with a "content_type" field added to it.  This is
# meant to take its place.
class FilePlus < File
  attr_accessor :content_type
  def size
    File.size(path)
  end
end

# Create subclasses of StringIO that has a content_type member to replicate the
# dynamic method addition that happens in Rails cgi.rb.
class StringIOPlus < StringIO
  attr_accessor :content_type
end

# Re-raise errors caught by the controller.
class ApplicationController
  def rescue_action(e)
    raise e
  end
end

require 'test/unit/ui/console/testrunner'

# Apparently bugs in the new version of Test::Unit?  Probably because we're using
# old version of rails...
module Test
  module Unit
    module UI
      module Console
        class TestRunner
          # When running in "show_detail_immediately" and "need_detail_faults"
          # mode it totally screws up the assertion message. 
          def output_fault_message(fault)
            output_single(fault.message, fault_color(fault))
          end

          # It no longer prints dots for successful tests.
          alias old_attach_to_mediator attach_to_mediator
          def attach_to_mediator
            old_attach_to_mediator
            @mediator.add_listener(TestResult::FINISHED, &method(:test_finished))
          end
        end
      end
    end
  end
end
