require "#{File.dirname(__FILE__)}/test_setup"
require 'gauge/base'
require 'stringio'

class BaseTest < Test::Unit::TestCase
  class MockBase < Gauge::Base
    class <<self
      def reset!
        @@config = {}
        @@hooks = Hash.new { |h,k| h[k] = {} }
        Thread.current[:gauge_logger] = nil
      end
    end
  end

  def setup
    MockBase.reset!
    @log = StringIO.new
    MockBase[:application] = "test"
    MockBase[:directory] = @log
  end

  def teardown
    MockBase.reset!
  end

  def test_config
    MockBase.config[:one] = "two"
    assert_equal "two", MockBase.config[:one]

    MockBase[:three] = "four"
    assert_equal "four", MockBase[:three]
  end

  def test_logger_per_thread
    log1 = log2 = log3 = nil
    t1 = Thread.new { log1 = MockBase.logger; log2 = MockBase.logger }
    t2 = Thread.new { log3 = MockBase.logger }
    t1.join
    t2.join
    assert_same log1, log2
    assert_not_same log1, log3
  end

  def test_log_hook_with_no_hooks
    MockBase.log(:test)
    assert @log.string.empty?
  end

  def test_log_hook_with_no_data
    MockBase.register(:test, :demo) do |name, data|
      assert_equal(:demo, name)
      ""
    end

    now = Time.now
    MockBase.log(:test)
    io = StringIO.new(@log.string)
    length = io.read(4).unpack("N").first
    assert_equal 17, length
    time, pid, nlen = io.read(13).unpack("GNC")
    assert_equal now.to_i, time.to_i
    assert_equal $$, pid
    assert_equal 4, nlen
    assert_equal "demo", io.read(4)
    assert io.eof?
  end

  def test_log_hook_with_data
    MockBase.register(:test, :demo) { |name, data| "\005hello\001\002" }
    now = Time.now
    MockBase.log(:test)
    io = StringIO.new(@log.string)
    length = io.read(4).unpack("N").first
    assert_equal 25, length
    time, pid, nlen = io.read(13).unpack("GNC")
    assert_equal now.to_i, time.to_i
    assert_equal $$, pid
    assert_equal 4, nlen
    assert_equal "demo", io.read(4)
    assert_equal "\005hello\001\002", io.read
    assert io.eof?
  end

end
