require 'test/unit'

module Borges; end
require 'Borges/Extensions/Array'
require 'Borges/Extensions/Numeric'
require 'Borges/Extensions/Object'
require 'Borges/Extensions/Proc'
require 'Borges/Extensions/String'

require 'Borges/HTML/HtmlAttributes'
require 'Borges/HTML/HtmlElement'
require 'Borges/HTML/HtmlBuilder'
require 'Borges/TestCase/Util/HtmlDocument'

class HtmlBuilderTest < Test::Unit::TestCase

  def render
    str = ''
    document = HtmlDocument.new
    yield ::Borges::HtmlBuilder.new(document)
    document.print_html_on str
    return str
  end

  def assert_head_renders(expected, message = nil, &block)
    assert_equal "<html><head>#{expected}</head><body></body></html>",
                 render(&block), message
  end

  def assert_body_renders(expected, message = nil, &block)
    assert_equal "<html><head></head><body>#{expected}</body></html>",
                 render(&block), message
  end

  Borges::HtmlBuilder::SIMPLE_ELEMENTS.each do |method, element|
    eval %^
    def test_#{method}
      assert_body_renders("<#{element}>text</#{element}>") do |r|
        r.send :#{method}, "text"
      end

      assert_body_renders("<#{element}>text</#{element}>") do |r|
        r.send(:#{method}) do
          r.text "text"
        end
      end
    end
    ^
  end

  def test_break
    assert_body_renders("<br>") do |r|
      r.break
    end
  end

  def test_css_class
    assert_body_renders("<p class=\"class\">text</p>") do |r|
      r.css_class "class"
      r.paragraph "text"
    end
  end

  def test_div_named
    assert_body_renders("<div id=\"id\">text</div>") do |r|
      r.div_named "id", "text"
    end
  end

  def test_div_with_class
    assert_body_renders("<div class=\"class\">text</div>") do |r|
      r.div_with_class "class", "text"
    end
  end

  def test_element_id
    assert_body_renders("<p id=\"id\">text</p>") do |r|
      r.element_id "id"
      r.paragraph "text"
    end
  end

  def test_encode_text
    expected = "&#0;&#1;&#2;&#3;&#4;&#5;&#6;&#7;&#8;\t\n\v\f\r" +
      "&#14;&#15;&#16;&#17;&#18;&#19;&#20;&#21;&#22;&#23;" +
      "&#24;&#25;&#26;&#27;&#28;&#29;&#30;&#31; !&quot;\#$%" +
      "&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQR" +
      "STUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~&#127;" +
      "&#128;&#129;&#130;&#131;&#132;&#133;&#134;&#135;&#136;" +
      "&#137;&#138;&#139;&#140;&#141;&#142;&#143;&#144;&#145;" +
      "&#146;&#147;&#148;&#149;&#150;&#151;&#152;&#153;&#154;" +
      "&#155;&#156;&#157;&#158;&#159;&nbsp;&iexcl;&cent;" +
      "&pound;&curren;&yen;&brvbar;&sect;&uml;&copy;&ordf;" +
      "&laquo;&not;&shy;&reg;&macr;&deg;&plusmn;&sup2;&sup3;" +
      "&acute;&micro;&para;&middot;&cedil;&sup1;&ordm;&raquo;" +
      "&frac14;&frac12;&frac34;&iquest;&Agrave;&Aacute;&Acirc;" +
      "&Atilde;&Auml;&Aring;&AElig;&Ccedil;&Egrave;&Eacute;" +
      "&Ecirc;&Euml;&Igrave;&Iacute;&Icirc;&Iuml;&ETH;&Ntilde;" +
      "&Ograve;&Oacute;&Ocirc;&Otilde;&Ouml;&times;&Oslash;" +
      "&Ugrave;&Uacute;&Ucirc;&Uuml;&Yacute;&THORN;&szlig;" +
      "&agrave;&aacute;&acirc;&atilde;&auml;&aring;&aelig;" +
      "&ccedil;&egrave;&eacute;&ecirc;&euml;&igrave;&iacute;" +
      "&icirc;&iuml;&eth;&ntilde;&ograve;&oacute;&ocirc;" +
      "&otilde;&ouml;&divide;&oslash;&ugrave;&uacute;&ucirc;" +
      "&uuml;&yacute;&thorn;&yuml;"

    input = (0..255).map do |c| c.chr end.join

    assert_body_renders(expected) do |r|
      r.encode_text input
    end
  end

  def test_fieldset
    expected = "<fieldset><legend>text</legend>stuff</fieldset>"
    assert_body_renders(expected) do |r|
      r.fieldset("text") do
        r.text "stuff"
      end
    end
  end

  def test_head_tag
    assert_head_renders("<mytag></mytag>") do |r|
      r.head_tag "mytag"
    end
  end

  def test_head_tag_with
    assert_head_renders("<mytag>text</mytag>") do |r|
      r.head_tag_with "mytag", "text"
    end
  end

  def test_heading
    assert_body_renders("<h1>text</h1>") do |r|
      r.heading "text"
    end
  end

  def test_heading_level
    1.upto(6) do |level|
      assert_body_renders("<h#{level}>text</h#{level}>") do |r|
        r.heading_level "text", level
      end
    end
  end

  def test_horizontal_rule
    assert_body_renders("<hr>") do |r|
      r.horizontal_rule
    end
  end

  def test_image
    html = "<img src=\"/path/to/image.jpg\" alt=\"\">"
    assert_body_renders(html) do |r|
      r.image "/path/to/image.jpg"
    end
  end
  
  def test_image_url_anchor
    html = "<a href=\"/path/to/html/file.html\"><img src=\"/path/to/image.jpg\" alt=\"alternate\"></a>"
    assert_body_renders(html) do |r|
      r.image_url_anchor "/path/to/html/file.html", "/path/to/image.jpg", "alternate"
    end
  end 

  def test_image_alt
    html = "<img src=\"/path/to/image.jpg\" alt=\"alternate text\">"
    assert_body_renders(html) do |r|
      r.image "/path/to/image.jpg", "alternate text"
    end
  end

  def test_input_type
    html = "<input type=\"type\">"
    assert_body_renders(html) do |r|
      r.input "type"
    end
  end

  def test_input_safe
    output = render do |r|
      r.input "type", "name", "&"
    end

    assert_match(/value="&amp;"/, output, "Escape unsafe characters")
  end

  def test_input_type_name
    output = render do |r|
      r.input "type", "name"
    end

    assert_match(/<input/, output, "Is an input element")
    assert_match(/type="type"/, output, "Type is \"type\"")
    assert_match(/name="name"/, output, "Name is \"name\"")
  end

  def test_input_type_name_value
    output = render do |r|
      r.input "type", "name", "value"
    end

    assert_match(/<input/, output, "Is an input element")
    assert_match(/type="type"/, output, "Type is \"type\"")
    assert_match(/name="name"/, output, "Name is \"name\"")
    assert_match(/value="value"/, output, "Value is \"value\"")
  end

  def test_list
    assert_body_renders("<ul><li>1</li><li>2</li></ul>") do |r|
      r.list [1, 2]
    end
  end

  def test_list_do
    html = "<ul><li><b>1</b></li><li><b>2</b></li></ul>"
    assert_body_renders(html) do |r|
      r.list_do([1, 2]) do |item|
        r.bold item
      end
    end
  end

  def test_set_attribute
    assert_body_renders("<p foo=\"bar\">text</p>") do |r|
      r.set_attribute "foo", "bar"
      r.paragraph "text"
    end
  end

  def test_space
    assert_body_renders("&nbsp;") do |r|
      r.space
    end
  end

  def test_style_link
    output = render do |r|
      r.style_link "http://localhost/css/style.css"
    end

    assert_match(/<link/, output, "Has a link")
    assert_match(/media="all"/, output, "media is set to \"all\"")
    assert_match(/type="text\/css"/, output, "type is set to \"text/css")
    assert_match(/rel="stylesheet"/, output, "rel is set to \"stylesheet\"")
    assert_match(/href="http:\/\/localhost\/css\/style.css"/, output,
                 "href is set to \"http://localhost/css/style.css\"")
  end

  def test_table
    html = "<table><tr><td>A</td><td>B</td></tr></table>"
    assert_body_renders(html) do |r|
      r.table do
        r.table_row do
          r.table_data "A"
          r.table_data "B"
        end
      end
    end
  end

  def test_table_headings
    html = "<table><tr><th>1</th><th>2</th></tr></table>"
    assert_body_renders(html) do |r|
      r.table do
        r.table_headings "1", "2"
      end
    end
  end

  def test_table_row_span
    html = "<table><tr><td colspan=\"2\">1</td></tr></table>"
    assert_body_renders(html) do |r|
      r.table do
        r.table_row_span(2) do
          r.text "1"
        end
      end
    end
  end

  def test_table_row_with
    html = "<table><tr><td>1</td></tr></table>"
    assert_body_renders(html) do |r|
      r.table do
        r.table_row_with "1"
      end
    end
  end

  def test_table_row_labeled
    html = "<table><tr><td class=\"label\">A</td><td>1</td></tr></table>"
    assert_body_renders(html) do |r|
      r.table do
        r.table_row_labeled "A", "1"
      end
    end
  end

  def test_table_spacer_row
    html = "<table><tr>&nbsp;</tr></table>"
    assert_body_renders(html) do |r|
      r.table do
        r.table_spacer_row
      end
    end
  end

  def test_text
    assert_body_renders("text") do |r|
      r.text "text"
    end
  end

  def test_title
    assert_head_renders("<title>text</title>") do |r|
      r.title "text"
    end
  end

  def test_url_anchor
    html ="<a href=\"http://www.reddwarf.co.uk\">Red Dwarf</a>"
    assert_body_renders(html) do |r|
      r.url_anchor "http://www.reddwarf.co.uk", "Red Dwarf"
    end
  end

=begin
  def test_anchorWithUrl_title_do
    flunk "anchorWithUrl_title_do"
  end

  def test_attributes=
    flunk "attributes="
  end

  def test_buttonForUrl_withText
    flunk "buttonForUrl_withText"
  end

  def test_buttonForUrl_withText_data
    flunk "buttonForUrl_withText_data"
  end

  def test_doesNotUnderstand
    flunk "doesNotUnderstand"
  end

  def test_formWithAction_do
    flunk "formWithAction_do"
  end

  def test_formWithMethod_action_do
    flunk "formWithMethod_action_do"
  end

  def test_image
    flunk "image"
  end

  def test_image_altText
    flunk "image_altText"
  end

  def test_image_width_height
    flunk "image_width_height"
  end

  def test_image_width_height_altText
    flunk "image_width_height_altText"
  end

  def test_inputWithType
    flunk "inputWithType"
  end

  def test_inputWithType_named
    flunk "inputWithType_named"
  end

  def test_layoutTable
    flunk "layoutTable"
  end

  def test_layoutTableOfWidth_do
    flunk "layoutTableOfWidth_do"
  end

  def test_metaTagNamed_content
    flunk "metaTagNamed_content"
  end

  def test_self_on
    flunk "self.on"
  end

  def test_scriptWithUrl
    flunk "scriptWithUrl"
  end

  def test_spanClass_with
    flunk "spanClass_with"
  end

  def test_spanNamed_with
    flunk "spanNamed_with"
  end

  def test_submitButton
    flunk "submitButton"
  end

  def test_submitButtonWithText
    flunk "submitButtonWithText"
  end

  def test_tableRowWith
    flunk "tableRowWith"
  end

  def test_tableRowWith_with
    flunk "tableRowWith_with"
  end

  def test_tableRowWith_with_with
    flunk "tableRowWith_with_with"
  end

  def test_tableRowWithLabel_column_column
    flunk "tableRowWithLabel_column_column"
  end
=end

end # class HtmlBuilderTest

