begin
	require 'rubygems'
rescue
end

require 'pathname'
$LOAD_PATH.unshift Pathname.new(__FILE__).dirname.parent.parent + 'lib/'

require 'bluefeather'
require 'nokogiri'

module NokogiriMatcher
	class HaveElement
		def initialize(selector)
			@selector = selector
		end
		
		def description
			"have element"
		end

		def matches?(target)
			@target = target
			
			return !(@target.search(@selector).empty?)
		end
		
		def failure_message
			%Q|expected an element selected by '#{@selector}', got no element\n(html: #{@target.to_s.inspect})|
	  end
	
	  def negative_failure_message
			%Q|expected no element selected by '#{@selector}', got an element\n(html: #{@target.to_s.inspect})|
	  end
	end
	
	class HaveElements
		def initialize(number, selector)
			@number, @selector = number, selector
		end

		def description
			"have elements"
		end

		def matches?(target)
			@target = target
			
			@found_number = @target.search(@selector).size
			return @found_number == @number
		end
		
		def failure_message
			%Q|expected #{@number} elements selected by '#{@selector}', got #{@found_number} elements\n(html: #{@target.to_s.inspect})|
	  end
	
	  def negative_failure_message
			%Q|not expected #{@number} elements selected by '#{@selector}', got #{@found_number} elements\n(html: #{@target.to_s.inspect})|
	  end
	end

end

# ex) doc.should have_element('div table')
def have_element(selector)
	NokogiriMatcher::HaveElement.new(selector)
end

alias have_element_as have_element

# ex) doc.should have_elements(3, 'p')
def have_elements(number, selector)
	NokogiriMatcher::HaveElements.new(number, selector)
end

alias have_elements_as have_elements





module CUIMatcher
	class WriteToIOBase
		def initialize(expected = nil)
			# if expected is nil, allow any outputs.
			@expected = expected
		end
		
		def description
			"write to IO"
		end
		
		def matches?(cui)
			@cui = cui
			
			if @expected then
				return get_written_string(@cui) == @expected
			else
				return !(get_written_string(@cui).empty?)
			end
			
		end
		
		def get_written_string(cui)
			# not implemented
		end
		
		def failure_message
			if @expected then
				%Q|expected: #{@expected.inspect}\n     got: #{get_written_string(@cui).inspect})|
			else
				%Q|expected: any\n     got: #{get_written_string(@cui).inspect})|
			end
	  end
	
		def negative_failure_message
			if @expected then
				%Q|not expected: #{@expected.inspect}\n         got: #{get_written_string(@cui).inspect})|
			else
				%Q|not expected: any\n         got: #{get_written_string(@cui).inspect})|
			end
	  end
	end

	class WriteToStdout < WriteToIOBase
		def description
			"write to stdout"
		end
		

		def get_written_string(cui)
			cui.stdout.string
		end
		
	end
	
	class WriteToStderr < WriteToIOBase
		def description
			"write to stderr"
		end
		

		def get_written_string(cui)
			cui.stderr.string
		end
		
	end

end

def write_to_stdout(expected = nil)
	CUIMatcher::WriteToStdout.new(expected)
end

alias wrote_to_stdout write_to_stdout

def write_to_stderr(expected = nil)
	CUIMatcher::WriteToStderr.new(expected)
end

alias wrote_to_stderr write_to_stderr



=begin
# new matcher
class String
	def to_xml
		REXML::Document.new("<xml>#{self}</xml>")
	end

	def xml_as?(other)
		a = REXML::Document.new("<xml>#{self}</xml>")
		b = REXML::Document.new("<xml>#{other}</xml>")
		
		a == b
	end
end

# comparable
module REXML
	class Element
		def ==(other)
			text == other.text and attributes == other.attributes and children == other.children
		end
	end
end
=end