
require 'rexml/document'
require 'amrita2'
require 'amrita2/testsupport'
require 'time'

include Amrita2
include Amrita2::Runtime
include Amrita2::Filters

context "Repeat Filter" do
  include Amrita2::Runtime
  include Amrita2::Filters

  specify "with string" do
    #t = Amrita2::Template.new('<div><span am:src="aaa|Repeat[5]" /></div>')

    t = Amrita2::Template.new('<div><<:aaa | Repeat[5] >></div>')
    t.render_with(:aaa => "A").should_be_samexml_as '<div>AAAAA</div>'
  end
end

context "Default Filter" do
  include Amrita2
  include Amrita2::Runtime
  include Amrita2::Filters

  specify "with not nil data" do
    begin
      #t = Amrita2::Template.new('<div><span am:src="aaa|Default[123]">aaa</span></div>')

      t = Amrita2::Template.new('<div><<:aaa | Default[123] >></div>')
      t.test_with(:aaa => "xyz") do |result|
        result.should_be_samexml_as '<div>xyz</div>'
      end
    end
  end

  specify "with nil " do
    t = Amrita2::Template.new('<span><span am:src="aaa|Default[123]">aaa</span></span>')
    t.test_with(:aaa => nil) do |result|
      result.should_be_samexml_as '123'
    end
  end

  specify "append filter in am:filter" do
    text = '<span><span am:src="aaa" am:filter="Default[789]">aaa</span></span>'
    t = Amrita2::Template.new(text)
    t.test_with(:aaa => nil) do |result|
      result.should_be_samexml_as '789'
    end
  end

  specify "append filter in ruby code" do
    text = '<span><span am:src="aaa">aaa</span></span>'
    t = Amrita2::Template.new(text) do |e, src, filters|
      if src == "aaa"
        filters << Amrita2::Filters::Default[456]
      end
    end
    t.test_with(:aaa => nil) do |result|
      result.should_be_samexml_as '456'
    end
  end

  specify "with not nil data" do
    begin
      t = Amrita2::Template.new(%[<div><span am:src='aaa|Default[""]|[:strftime, "%y-%m-%d"]'>aaa</span></div>])
      t.test_with(:aaa => Time.parse('2007-10-01')) do |result|
        result.should_be_samexml_as '<div>07-10-01</div>'
      end
      t.test_with(:aaa => nil) do |result|
        result.should_be_samexml_as '<div />'
      end
    end
  end

end

context "Format Filter" do
  include Amrita2::Runtime
  include Amrita2::Filters

  specify "Integer" do
    #t = Amrita2::Template.new(%q[<span><span am:src="aaa|Format['(%s)']">aaa</span></span>])

    t = Amrita2::Template.new(%q[<span><<:aaa | Format['(%s)']>></span>])
    t.test_with(:aaa => 123) do |result|
      result.should_be_samexml_as '(123)'
    end
  end

  specify "with Default" do
    t = Amrita2::Template.new(%q[<span><span am:src="aaa|Default[456] | Format['(%s)']">aaa</span></span>])
    t.render_with(:aaa => nil).should_be_samexml_as '456'
  end
end

context "Other ways to setup filters" do
  include Amrita2::Runtime
  include Amrita2::Filters

  def test(t)
    t.test_with(:aaa => "A") do |result|
      result.should_be_samexml_as '<div>(A)(A)(A)(A)(A)</div>'
    end
    t.test_with({}) do |result|
      result.should_be_samexml_as '<div>a</div>'
    end
  end

  specify "am:src" do
    t = Amrita2::Template.new <<-END
     <div><span am:src="aaa | Default['a'] | Format['(%s)'] | Repeat[5]" /></div>
    END
    test(t)
  end

  specify "am:filter" do
    t = Amrita2::Template.new <<-END
     <div><span am:src="aaa"
                am:filter="Default['a'] | Format['(%s)'] | Repeat[5]" /></div>
    END
    test(t)
  end

  specify "am:src and am:filter" do
    t = Amrita2::Template.new <<-END
     <div><span am:src="aaa | Default['a']"
                am:filter=" Format['(%s)'] | Repeat[5]" /></div>
    END
    test(t)
  end

  specify "new + block" do
    text = <<-END
     <div><span am:src="aaa"/></div>
    END

    t = Amrita2::Template.new(text) do |e, src, filters|
      if e.name == 'span' and src == "aaa"
        filters << Default['a'] << Format['(%s)'] << Repeat[5]
      end
    end

    test(t)
  end

  specify "inline filter proc" do
    t = Amrita2::Template.new <<-END
     <%(BeforeCompile)
        filter_setup do |e, src, filters|
          if e.name == 'span' and src == "aaa"
            filters << Default['a'] << Format['(%s)'] << Repeat[5]
          end
        end
     %>
     <div><span am:src="aaa" /></div>
    END

    test(t)
  end
end

context "with am:v" do
  include Amrita2::Runtime
  include Amrita2::Filters

  specify "Integer" do
    text = %q[<span><span am:v="aaa" am:filter="Format['(%s)']">aaa</span></span>]
    t = Amrita2::Template.new(text)
    aaa = 123
    t.test_with(binding) do |result|
      result.should_be_samexml_as '(123)'
    end
  end
end

context "with Amrita2:Tuppl" do
  include Amrita2::Runtime
  include Amrita2::Filters

  specify "simple" do
    text = <<-END
    <span>
      <a am:src="aaa|NVar"
         href="http://raa.ruby-lang.org/list.rhtml?name=$1">[$2]</a>
    </span>
    END

    t = Amrita2::Template.new(text)
    t.test_with(:aaa=>Amrita2::Util::Tuple['amrita', 'Amrita template library']) do |result|
      result.should_be_samexml_as '<a href="http://raa.ruby-lang.org/list.rhtml?name=amrita">[Amrita template library]</a>'
    end
  end

  specify "with a hash" do
    text = <<-END
    <span>
      <a am:src="aaa|NVar[:name, :description]"
         href="http://raa.ruby-lang.org/list.rhtml?name=$1">[$2]</a>
    </span>
    END
    data = {
      :name => 'amrita',
      :description => 'Amrita template library'
    }
    t = Amrita2::Template.new(text)
    t.test_with(:aaa=>data) do |result|
      result.should_be_samexml_as '<a href="http://raa.ruby-lang.org/list.rhtml?name=amrita">[Amrita template library]</a>'
    end
  end

  specify "with an array of hash" do
    text = <<-END
    <ul>
      <li am:src="aaa|NVar[:name, :description]">
         <a href="http://raa.ruby-lang.org/list.rhtml?name=$1">[$2]</a>
      </li>
    </ul>
    END
    data = [
      {
        :name => 'amrita',
        :description => 'Amrita template library'
      },
      {
        :name => 'amrita2',
        :description => 'Amrita2 template library'
      }
    ]
    t = Amrita2::Template.new(text)
    t.test_with(:aaa=>data) do |result|
      result.should_be_samexml_as <<-END
      <ul>
        <li>
          <a href='http://raa.ruby-lang.org/list.rhtml?name=amrita'>[Amrita template library]</a>
        </li>
        <li>
          <a href='http://raa.ruby-lang.org/list.rhtml?name=amrita2'>[Amrita2 template library]</a>
        </li>
      </ul>
      END
    end
  end

  specify "with an array of struct" do
    text = <<-END
    <ul>
      <li am:src="aaa|NVar[:name, :description]">
         <a href="http://raa.ruby-lang.org/list.rhtml?name=$1">[$2]</a>
      </li>
    </ul>
    END
    s = Struct.new(:name, :description)
    data = [
      s.new('amrita', 'Amrita template library'),
      s.new('amrita2', 'Amrita2 template library'),
    ]
    t = Amrita2::Template.new(text)
    t.test_with(:aaa=>data) do |result|
      result.should_be_samexml_as <<-END
      <ul>
        <li>
          <a href='http://raa.ruby-lang.org/list.rhtml?name=amrita'>[Amrita template library]</a>
        </li>
        <li>
          <a href='http://raa.ruby-lang.org/list.rhtml?name=amrita2'>[Amrita2 template library]</a>
        </li>
      </ul>
      END
    end
  end
end

context "Method Filter" do
  include Amrita2::Runtime
  include Amrita2::Filters

  specify "with string" do
    t = Amrita2::Template.new('<div><span am:src="aaa|:downcase" /></div>')
    t.render_with(:aaa => "AbC").should_be_samexml_as '<div>abc</div>'
  end

  specify "with parameter" do
    t = Amrita2::Template.new(%[<div><span am:src="aaa | FunctionFilter[:strftime, '%y-%m-%d']" /></div>])
    t.render_with(:aaa => Time.parse("2007/08/31")).should_be_samexml_as '<div>07-08-31</div>'
  end

  specify "with parameter short" do
    t = Amrita2::Template.new(%[<div><span am:src="aaa | [:strftime, '%y-%m-%d']" /></div>])
    t.render_with(:aaa => Time.parse("2007/08/31")).should_be_samexml_as '<div>07-08-31</div>'
  end

  specify "with parameter short" do
    t = Amrita2::Template.new <<-END
        <<div :task<
          <<:memo | Default['(no text)'] | :upcase  >>
    END
    task =
      [
       { :memo => 'Default and filter' },
       { :memo => nil },
       { :memo => 'xyz' }
      ]

    t.render_with(binding).should_be_samexml_as '<div>DEFAULT AND FILTER</div><div>(no text)</div><div>XYZ</div>'
  end
end

context "CommandFilter" do
  include Amrita2::Runtime
  include Amrita2::Filters

  specify "cat -n" do
    t = Amrita2::Template.new(%[<div am:src="aaa|CommandFilter['cat -n']" />])
    t.test_with(:aaa => "abc") do|r|
      r.should_be_samexml_as "1<div>abc</div>"
    end
  end

  specify "tidy" do
    t = Amrita2::Template.new <<-END
    <<div : | CommandFilter['tidy -q -xml -indent '] <
      <ul><li>1</li><li>2</li><li>3</li></ul>
    END
    t.test_with(binding) do|r|
      r.should == <<END
<div>
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
  </ul>
</div>
END
    end
  end

  specify "tidy for only debug" do
    text = <<-END
    <%(BeforeCompile)
      self.class.module_eval { remove_const(:Tidy) } if self.class.const_defined?(:Tidy)
      if ENV['RAILS_ENV'] == "development"
        Tidy = CommandFilter['tidy -q -xml -indent']
      else
        Tidy = nil
      end
    %>
    <<div : | Tidy <
      <ul><li>1<li>2<li>3</ul>
    END

    ENV['RAILS_ENV'] = "development"
    t = Amrita2::Template.new text
    t.test_with(binding) do|r|
      r.should == "    \n<div>\n  <ul>\n    <li>1</li>\n    <li>2</li>\n    <li>3</li>\n  </ul>\n</div>\n"
    end

    ENV['RAILS_ENV'] = "production"
    t = Amrita2::Template.new text
    t.test_with(binding) do |r|
      r.should == "    \n<div>      <ul><li>1</li><li>2</li><li>3</li></ul>\n</div>"
    end
  end
end

context "Join Filter" do
  include Amrita2::Runtime
  include Amrita2::Filters

  specify "Join elements" do
    t = Amrita2::Template.new <<-END
    <<div : | Join[:nbsp] <
       aaaa
       <a href="aaa">aaa</a>
       bbbb
    END
    t.test_with(binding) do|r|
      r.should_be_samexml_as '<div>aaaa&#160;<a href="aaa">aaa</a>&#160;bbbb</div>'
    end
  end

  specify "Join with <br />" do
    t = Amrita2::Template.new <<-END
    <<div : | Join['<br />'] <
       aaaa
       bbbb
    END
    t.test_with(binding) do|r|
      r.should_be_samexml_as '<div>aaaa<br />bbbb</div>'
    end
  end

  specify "Join with nbsp" do
    t = Amrita2::Template.new <<-END
    <<div : | Join['&nbsp;'] <
       aaaa
       bbbb
    END
    t.test_with(binding) do|r|
      r.should_be_samexml_as '<div>aaaa&nbsp;bbbb</div>'
    end
  end

  specify "Join erb with nbsp" do
    t = Amrita2::Template.new <<-END
    <<div : | Join['&nbsp;'] <
       aaaa
       %=1
       bbbb
       %=1+1
       cccc
    END
    t.test_with(binding) do|r|
      r.should_be_samexml_as '<div>aaaa&nbsp;1&nbsp;bbbb&nbsp;2&nbsp;cccc</div>'
    end
  end

end

context "Stream Filter" do
  include Amrita2::Runtime
  include Amrita2::Filters

  specify "Change Stream" do
    t = Amrita2::Template.new <<-END
    <<abc=<
       aaaa
    bbbb
    <<=abc>>
    END
    t.test_with(binding) do|r|
      r.should_be_samexml_as 'bbbb aaaa'
    end
  end

  specify "Change Stream with erb" do
    t = Amrita2::Template.new <<-END
    <<abc=<
       %= "aaaa"

    %= "bbbb"
    <<=abc>>
    END
    t.test_with(binding) do|r|
      r.should_be_samexml_as 'bbbb aaaa'
    end
  end

  specify "multi streams" do
    t = Amrita2::Template.new <<-END
    <<abc=<
       aaa
       <<efg=<
         bbb
       ccc
    ddd
    <<=abc>>
    <<=efg>>
    END
    t.test_with(binding) do|r|
      r.should_be_samexml_as 'ddd aaa ccc bbb'
    end
  end
end

context "Module Extend Filter" do
  include Amrita2::Runtime
  include Amrita2::Filters

  module ModuleExtendFilterTest
    def bbb
      "(#{super})"
    end
  end

  specify "module extend" do
    t = Amrita2::Template.new <<-END
      <<div :aaa | ModuleExtendFilterTest <
        <<:bbb>>
    END
    aaa = Struct.new(:bbb).new('bbb')
    t.test_with(binding) do |r|
      r.should_be_samexml_as '<div>(bbb)</div>'
    end
  end
end


context "ToHash Filter" do
  include Amrita2::Runtime
  include Amrita2::Filters

  specify "with string" do
    t = Amrita2::Template.new <<-END
     <<:a|ToHash[:xxx]<
       <<:xxx>>
    END

    t.render_with(:a => "A").should_be_samexml_as 'A'
  end

  specify "many keys" do
    t = Amrita2::Template.new <<-END
     <<:time | ToHash[:h=>:hour, :m=>:min, :s=>:sec] <
       <<:h>>:<<:m>>:<<:s>>
    END

    tm = Time.local(2008,1,10,9,10,30)
    tm.extend(Amrita2::DictionaryData)
    t.render_with(:time=>tm).should_be_samexml_as '9:10:30'
  end
end
