prototype_helper_test.rb 18.7 KB
Newer Older
1 2 3 4 5
require File.dirname(__FILE__) + '/../abstract_unit'

module BaseTest
  include ActionView::Helpers::JavaScriptHelper
  include ActionView::Helpers::PrototypeHelper
6
  include ActionView::Helpers::ScriptaculousHelper
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
  
  include ActionView::Helpers::UrlHelper
  include ActionView::Helpers::TagHelper
  include ActionView::Helpers::TextHelper
  include ActionView::Helpers::FormHelper
  include ActionView::Helpers::CaptureHelper
  
  def setup
    @controller = Class.new do
      def url_for(options, *parameters_for_method_reference)
        url =  "http://www.example.com/"
        url << options[:action].to_s if options and options[:action]
        url
      end
    end.new
  end

protected
  def create_generator
    block = Proc.new { |*args| yield *args if block_given? } 
    JavaScriptGenerator.new self, &block
  end
end

class PrototypeHelperTest < Test::Unit::TestCase
  include BaseTest
  
  def test_link_to_remote
    assert_dom_equal %(<a class=\"fine\" href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true}); return false;\">Remote outpost</a>),
      link_to_remote("Remote outpost", { :url => { :action => "whatnot"  }}, { :class => "fine"  })
    assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onComplete:function(request){alert(request.reponseText)}}); return false;\">Remote outpost</a>),
      link_to_remote("Remote outpost", :complete => "alert(request.reponseText)", :url => { :action => "whatnot"  })      
    assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onSuccess:function(request){alert(request.reponseText)}}); return false;\">Remote outpost</a>),
      link_to_remote("Remote outpost", :success => "alert(request.reponseText)", :url => { :action => "whatnot"  })
    assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onFailure:function(request){alert(request.reponseText)}}); return false;\">Remote outpost</a>),
      link_to_remote("Remote outpost", :failure => "alert(request.reponseText)", :url => { :action => "whatnot"  })
  end
  
  def test_periodically_call_remote
    assert_dom_equal %(<script type="text/javascript">\n//<![CDATA[\nnew PeriodicalExecuter(function() {new Ajax.Updater('schremser_bier', 'http://www.example.com/mehr_bier', {asynchronous:true, evalScripts:true})}, 10)\n//]]>\n</script>),
      periodically_call_remote(:update => "schremser_bier", :url => { :action => "mehr_bier" })
  end
  
  def test_form_remote_tag
    assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">),
      form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast  })
    assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({success:'glass_of_beer'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">),
      form_remote_tag(:update => { :success => "glass_of_beer" }, :url => { :action => :fast  })
    assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({failure:'glass_of_water'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">),
      form_remote_tag(:update => { :failure => "glass_of_water" }, :url => { :action => :fast  })
    assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({success:'glass_of_beer',failure:'glass_of_water'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">),
      form_remote_tag(:update => { :success => 'glass_of_beer', :failure => "glass_of_water" }, :url => { :action => :fast  })
  end
  
  def test_on_callbacks
    callbacks = [:uninitialized, :loading, :loaded, :interactive, :complete, :success, :failure]
    callbacks.each do |callback|
      assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on#{callback.to_s.capitalize}:function(request){monkeys();}, parameters:Form.serialize(this)}); return false;">),
        form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast  }, callback=>"monkeys();")
      assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({success:'glass_of_beer'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on#{callback.to_s.capitalize}:function(request){monkeys();}, parameters:Form.serialize(this)}); return false;">),
        form_remote_tag(:update => { :success => "glass_of_beer" }, :url => { :action => :fast  }, callback=>"monkeys();")
      assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({failure:'glass_of_beer'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on#{callback.to_s.capitalize}:function(request){monkeys();}, parameters:Form.serialize(this)}); return false;">),
        form_remote_tag(:update => { :failure => "glass_of_beer" }, :url => { :action => :fast  }, callback=>"monkeys();")
      assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({success:'glass_of_beer',failure:'glass_of_water'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on#{callback.to_s.capitalize}:function(request){monkeys();}, parameters:Form.serialize(this)}); return false;">),
        form_remote_tag(:update => { :success => "glass_of_beer", :failure => "glass_of_water" }, :url => { :action => :fast  }, callback=>"monkeys();")
    end
    
    #HTTP status codes 200 up to 599 have callbacks
    #these should work
    100.upto(599) do |callback|
      assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on#{callback.to_s.capitalize}:function(request){monkeys();}, parameters:Form.serialize(this)}); return false;">),
        form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast  }, callback=>"monkeys();")
    end
    
    #test 200 and 404
    assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on200:function(request){monkeys();}, on404:function(request){bananas();}, parameters:Form.serialize(this)}); return false;">),
      form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast  }, 200=>"monkeys();", 404=>"bananas();")
    
    #these shouldn't
    1.upto(99) do |callback|
      assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;">),
        form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast  }, callback=>"monkeys();")
    end
    600.upto(999) do |callback|
      assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;">),
        form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast  }, callback=>"monkeys();")
    end
    
    #test ultimate combo
    assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on200:function(request){monkeys();}, on404:function(request){bananas();}, onComplete:function(request){c();}, onFailure:function(request){f();}, onLoading:function(request){c1()}, onSuccess:function(request){s()}, parameters:Form.serialize(this)}); return false;\">),
      form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast  }, :loading => "c1()", :success => "s()", :failure => "f();", :complete => "c();", 200=>"monkeys();", 404=>"bananas();")
    
  end
  
  def test_submit_to_remote
    assert_dom_equal %(<input name=\"More beer!\" onclick=\"new Ajax.Updater('empty_bottle', 'http://www.example.com/', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)}); return false;\" type=\"button\" value=\"1000000\" />),
      submit_to_remote("More beer!", 1_000_000, :update => "empty_bottle")
  end
  
  def test_observe_field
    assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Element.Observer('glass', 300, function(element, value) {new Ajax.Request('http://www.example.com/reorder_if_empty', {asynchronous:true, evalScripts:true})})\n//]]>\n</script>),
      observe_field("glass", :frequency => 5.minutes, :url => { :action => "reorder_if_empty" })
  end
  
  def test_observe_form
    assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Observer('cart', 2, function(element, value) {new Ajax.Request('http://www.example.com/cart_changed', {asynchronous:true, evalScripts:true})})\n//]]>\n</script>),
      observe_form("cart", :frequency => 2, :url => { :action => "cart_changed" })
  end

  def test_update_element_function
    assert_equal %($('myelement').innerHTML = 'blub';\n),
      update_element_function('myelement', :content => 'blub')
    assert_equal %($('myelement').innerHTML = 'blub';\n),
      update_element_function('myelement', :action => :update, :content => 'blub')
    assert_equal %($('myelement').innerHTML = '';\n),
      update_element_function('myelement', :action => :empty)
    assert_equal %(Element.remove('myelement');\n),
      update_element_function('myelement', :action => :remove)
      
    assert_equal %(new Insertion.Bottom('myelement','blub');\n),
      update_element_function('myelement', :position => 'bottom', :content => 'blub')
    assert_equal %(new Insertion.Bottom('myelement','blub');\n),
      update_element_function('myelement', :action => :update, :position => :bottom, :content => 'blub')
      
    _erbout = ""
    assert_equal %($('myelement').innerHTML = 'test';\n),
      update_element_function('myelement') { _erbout << "test" }
      
    _erbout = ""
    assert_equal %($('myelement').innerHTML = 'blockstuff';\n),
      update_element_function('myelement', :content => 'paramstuff') { _erbout << "blockstuff" }
  end
  
  def test_update_page
    block = Proc.new { |page| page.replace_html('foo', 'bar') }
    assert_equal create_generator(&block).to_s, update_page(&block)
  end
  
  def test_update_page_tag
    block = Proc.new { |page| page.replace_html('foo', 'bar') }
    assert_equal javascript_tag(create_generator(&block).to_s), update_page_tag(&block)
  end
end

151 152
ActionView::Helpers::JavaScriptCollectionProxy.send :public, :enumerate

153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
class JavaScriptGeneratorTest < Test::Unit::TestCase
  include BaseTest
  
  def setup
    super
    @generator = create_generator
  end
  
  def test_insert_html_with_string
    assert_equal 'new Insertion.Top("element", "<p>This is a test</p>");',
      @generator.insert_html(:top, 'element', '<p>This is a test</p>')
    assert_equal 'new Insertion.Bottom("element", "<p>This is a test</p>");',
      @generator.insert_html(:bottom, 'element', '<p>This is a test</p>')
    assert_equal 'new Insertion.Before("element", "<p>This is a test</p>");',
      @generator.insert_html(:before, 'element', '<p>This is a test</p>')
    assert_equal 'new Insertion.After("element", "<p>This is a test</p>");',
      @generator.insert_html(:after, 'element', '<p>This is a test</p>')
  end
  
  def test_replace_html_with_string
173
    assert_equal 'Element.update("element", "<p>This is a test</p>");',
174 175 176
      @generator.replace_html('element', '<p>This is a test</p>')
  end
  
177 178
  def test_replace_element_with_string
    assert_equal 'Element.replace("element", "<div id=\"element\"><p>This is a test</p></div>");',
179
      @generator.replace('element', '<div id="element"><p>This is a test</p></div>')
180 181
  end
  
182 183 184 185 186 187 188 189
  def test_remove
    assert_equal '["foo"].each(Element.remove);',
      @generator.remove('foo')
    assert_equal '["foo", "bar", "baz"].each(Element.remove);',
      @generator.remove('foo', 'bar', 'baz')
  end
  
  def test_show
190
    assert_equal 'Element.show("foo");',
191
      @generator.show('foo')
192
    assert_equal 'Element.show("foo", "bar", "baz");',
193 194 195 196
      @generator.show('foo', 'bar', 'baz')
  end
  
  def test_hide
197
    assert_equal 'Element.hide("foo");',
198
      @generator.hide('foo')
199
    assert_equal 'Element.hide("foo", "bar", "baz");',
200 201 202
      @generator.hide('foo', 'bar', 'baz')
  end
  
203 204 205 206 207 208 209 210 211
  def test_alert
    assert_equal 'alert("hello");', @generator.alert('hello')
  end
  
  def test_redirect_to
    assert_equal 'window.location.href = "http://www.example.com/welcome";',
      @generator.redirect_to(:action => 'welcome')
  end
  
212 213 214 215 216 217 218 219
  def test_delay
    @generator.delay(20) do
      @generator.hide('foo')
    end
    
    assert_equal "setTimeout(function() {\n;\nElement.hide(\"foo\");\n}, 20000);", @generator.to_s
  end
  
220 221 222 223 224 225 226 227 228 229
  def test_to_s
    @generator.insert_html(:top, 'element', '<p>This is a test</p>')
    @generator.insert_html(:bottom, 'element', '<p>This is a test</p>')
    @generator.remove('foo', 'bar')
    @generator.replace_html('baz', '<p>This is a test</p>')
    
    assert_equal <<-EOS.chomp, @generator.to_s
new Insertion.Top("element", "<p>This is a test</p>");
new Insertion.Bottom("element", "<p>This is a test</p>");
["foo", "bar"].each(Element.remove);
230
Element.update("baz", "<p>This is a test</p>");
231 232
    EOS
  end
233 234 235 236 237 238 239 240 241 242

  def test_element_access
    assert_equal %($('hello');), @generator['hello']
  end

  def test_element_proxy_one_deep
    @generator['hello'].hide
    assert_equal %($('hello').hide();), @generator.to_s
  end

243
  def test_element_proxy_assignment
244
    @generator['hello'].width = 400
245 246 247
    assert_equal %($('hello').width = 400;), @generator.to_s
  end

248
  def test_element_proxy_two_deep
249 250
    @generator['hello'].hide("first").clean_whitespace
    assert_equal %($('hello').hide("first").cleanWhitespace();), @generator.to_s
251 252 253 254 255 256 257 258 259 260
  end
  
  def test_select_access
    assert_equal %($$('div.hello');), @generator.select('div.hello')
  end

  def test_select_proxy_one_deep
    @generator.select('p.welcome b').first.hide
    assert_equal %($$('p.welcome b').first().hide();), @generator.to_s
  end
261 262
  
  def test_visual_effect
263
    assert_equal %(new Effect.Puff("blah",{});), 
264 265 266 267
      @generator.visual_effect(:puff,'blah')
  end 
  
  def test_visual_effect_toggle
268
    assert_equal %(Effect.toggle("blah",'appear',{});), 
269 270 271 272
      @generator.visual_effect(:toggle_appear,'blah')
  end
  
  def test_sortable
273
    assert_equal %(Sortable.create("blah", {onUpdate:function(){new Ajax.Request('http://www.example.com/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize("blah")})}});), 
274 275 276 277
      @generator.sortable('blah', :url => { :action => "order" })
  end
  
  def test_draggable
278
    assert_equal %(new Draggable("blah", {});), 
279 280 281 282
      @generator.draggable('blah')
  end
  
  def test_drop_receiving
283
    assert_equal %(Droppables.add("blah", {onDrop:function(element){new Ajax.Request('http://www.example.com/order', {asynchronous:true, evalScripts:true, parameters:'id=' + encodeURIComponent(element.id)})}});), 
284 285
      @generator.drop_receiving('blah', :url => { :action => "order" })
  end
286 287

  def test_collection_proxy_with_each
288
    @generator.select('p.welcome b').each do |value|
289 290
      value.remove_class_name 'selected'
    end
291 292
    @generator.select('p.welcome b').each do |value, index|
      @generator.visual_effect :highlight, value
293
    end
294
    assert_equal <<-EOS.strip, @generator.to_s
295 296 297 298
$$('p.welcome b').each(function(value, index) {
value.removeClassName("selected");
});
$$('p.welcome b').each(function(value, index) {
299
new Effect.Highlight(value,{});
300 301 302 303 304
});
      EOS
  end

  def test_collection_proxy_on_enumerables_with_return_and_index
305 306
    iterator            = Proc.new { |value|        @generator << '(value.className == "welcome")' }
    iterator_with_index = Proc.new { |value, index| @generator.call 'alert', index ; @generator << '(value.className == "welcome")' }
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
    ActionView::Helpers::JavaScriptCollectionProxy::ENUMERABLE_METHODS_WITH_RETURN.each do |enum|
      @generator.select('p').enumerate(enum, 'a', &iterator)
      @generator.select('p').enumerate(enum, 'b', &iterator_with_index)
      
      assert_equal <<-EOS.strip, @generator.to_s
a = $$('p').#{enum}(function(value, index) {
return (value.className == "welcome");
});
b = $$('p').#{enum}(function(value, index) {
alert(index);
return (value.className == "welcome");
});
      EOS
      @generator = create_generator
    end
  end

  def test_collection_proxy_with_grep
325 326
    @generator.select('p').grep 'a', /^a/ do |value|
      @generator << '(value.className == "welcome")'
327
    end
328 329 330
    @generator.select('p').grep 'b', /b$/ do |value, index|
      @generator.call 'alert', value
      @generator << '(value.className == "welcome")'
331 332 333 334 335 336 337 338 339 340 341 342 343 344
    end

    assert_equal <<-EOS.strip, @generator.to_s
a = $$('p').grep(/^a/, function(value, index) {
return (value.className == "welcome");
});
b = $$('p').grep(/b$/, function(value, index) {
alert(value);
return (value.className == "welcome");
});
    EOS
  end

  def test_collection_proxy_with_inject
345 346
    @generator.select('p').inject 'a', [] do |memo, value|
      @generator << '(value.className == "welcome")'
347
    end
348 349 350
    @generator.select('p').inject 'b', nil do |memo, value, index|
      @generator.call 'alert', memo
      @generator << '(value.className == "welcome")'
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370
    end

    assert_equal <<-EOS.strip, @generator.to_s
a = $$('p').inject([], function(memo, value, index) {
return (value.className == "welcome");
});
b = $$('p').inject(null, function(memo, value, index) {
alert(memo);
return (value.className == "welcome");
});
    EOS
  end

  def test_collection_proxy_with_pluck
    @generator.select('p').pluck('a', 'className')
    assert_equal %(a = $$('p').pluck("className");), @generator.to_s
  end

  def test_collection_proxy_with_zip
    ActionView::Helpers::JavaScriptCollectionProxy.new(@generator, '[1, 2, 3]').zip('a', [4, 5, 6], [7, 8, 9])
371 372
    ActionView::Helpers::JavaScriptCollectionProxy.new(@generator, '[1, 2, 3]').zip('b', [4, 5, 6], [7, 8, 9]) do |array|
      @generator.call 'array.reverse'
373 374 375 376 377 378 379 380 381
    end

    assert_equal <<-EOS.strip, @generator.to_s
a = [1, 2, 3].zip([4, 5, 6], [7, 8, 9]);
b = [1, 2, 3].zip([4, 5, 6], [7, 8, 9], function(array) {
return array.reverse();
});
    EOS
  end
382
end