require 'logger'
require File.dirname(__FILE__) << "/../test_helper"

# Simple class I can write some tests for
class ExampleClass
  
  def self.logger
    @logger ||= Logger.new(STDERR)
  end
  
  attr_reader :number, :directory
  def initialize(number, directory)
    @number = number
    @directory = directory
  end
  
  def write!
    number.times do |i|
      File.open(File.join(directory, "#{i}.txt"), 'w') do |f|
        f.puts "Stub"
      end
      log :info, "Wrote file #{i}"
    end
  end
  
  #######
  private
  #######

  def log(level, text)
    self.class.logger.send(level, text)
  end
  
end

# For reuse
module LoggerMocking
  def captures_logging_from(klass)
    setup do
      @capture = StringIO.new
      @original_logger = klass.logger
      klass.instance_variable_set(:@logger, Logger.new(@capture))
    end
    teardown do
      klass.instance_variable_set(:@logger, @original_logger)
    end
    test_unit_class.class_eval do
      def captured_log
        @capture.rewind
        @capture.read
      end
      def times_logged(pattern)
        captured_log.scan(pattern).size
      end
    end
  end
end

# Make available to all contexts; would be nice to
# have a hook to do this
class Thoughtbot::Shoulda::Context
  include LoggerMocking
end
    
class ExampleofMultipleCleanupsTest < Test::Unit::TestCase

  context 'ExampleClass' do
  
    # Add the necessary setup & teardown for log capture
    captures_logging_from ExampleClass
    
    # Just for this context; shouldn't clobber or be clobbered
    # by mixed-in setups.
    setup do
      FileUtils.mkdir_p tmp_dir
      @klass = ExampleClass.new(3, tmp_dir)
    end
    
    # Just for this context; shouldn't clobber or be clobbered
    # by mixed-in teardowns.
    teardown do
      FileUtils.rm_rf tmp_dir
    end
    
    should "doesn't write when instantiated" do
      assert_equal 0, number_of_files
    end
    
    should "write correct number of files on write!" do
      @klass.write!
      assert_equal 3, number_of_files
    end
    
    should "add log entries when writing files" do
      assert_equal 0, times_logged(/Wrote file/)
      @klass.write!
      assert_equal 3, times_logged(/Wrote file/)
    end
    
  end
  
  #######
  private
  #######
  
  def number_of_files
    Dir[File.join(tmp_dir, '*')].size
  end

  def tmp_dir
    @tmp_dir ||= File.dirname(__FILE__) << "/tmp"
  end

end