require File.dirname(__FILE__) + "/../../spec_helper.rb" # # Fake active-record and active resource classes to work with # module ActiveRecord class Base def initialize(hash={}) @hash = hash end def id @hash[:id] end def self.table_name name = 'records' name.stub!(:singularize).and_return('record') name end def new_record? true end end end module ActiveResource class Base end end describe RightRails::JavaScriptGenerator do before :each do RightRails::Config.reset! @template = mock() def @template.dom_id(record) "record_#{record.id}" end def @template.escape_javascript(str) str end @page = RightRails::JavaScriptGenerator.new(@template) end describe "top level calls" do it "should generate a simple ID search" do @page['element-id'] @page.to_s.should == '$("element-id");' end it "should respond to the top-level javascript objects" do @page.document @page.to_s.should == 'document;' end it "should generate an ID search from active-records and active-resources" do @record = ActiveRecord::Base.new({:id => '22'}) @page[@record] @page.to_s.should == '$("record_22");' end it "should generate a CSS select block" do @page.find('div, span, table') @page.to_s.should == '$$("div, span, table");' end it "should generate redirect" do @page.redirect_to('/boo/boo/boo') @page.to_s.should == 'document.location.href="/boo/boo/boo";' end it "should generate reload" do @page.reload @page.to_s.should == 'document.location.reload();' end it "should process assignments" do @page.something = nil; @page.to_s.should == 'something=null;' end it "should provide access to javascript context variables" do @page.get(:my_var).property = 'boo'; @page.to_s.should == 'my_var.property="boo";' end it "should let you set the variables" do @page.set(:my_var, nil) @page.to_s.should == 'var my_var=null;' end it "should process << pushes correctly" do @page << 'some_code();' << 'another_code();' @page.to_s.should == 'some_code();another_code();' end it "should convert several lines of code properly" do @page['el1'].update('text1').show(); @page['el2'].update('text2').highlight(); @page.to_s.should == '$("el1").update("text1").show();$("el2").update("text2").highlight();' end describe "in safe-mode" do before :each do RightRails::Config.safe_mode = true end it "should prefix $ with RightJS." do @page['element-id'] @page.to_s.should == 'RightJS.$("element-id");' end it "should prefix $$ with RightJS." do @page.find('div#css.rule') @page.to_s.should == 'RightJS.$$("div#css.rule");' end end end describe "second level calls" do it "should catch up an element method simple calls" do @page['element-id'].myMethod @page.to_s.should == '$("element-id").myMethod();' end it "should catch up an element method arguments as well" do @page['element-id'].myMethod(1,2,3) @page.to_s.should == '$("element-id").myMethod(1,2,3);' end it "should catch up with element property calls" do @page['element-id'][:innerHTML] @page.to_s.should == '$("element-id").innerHTML;' end it "should catch up with element properties call chains" do @page['element-id'].test(1).show.highlight() @page.to_s.should == '$("element-id").test(1).show().highlight();' end it "should catch up the assignments correctly" do @page['element-id'].innerHTML = nil; @page.to_s.should == '$("element-id").innerHTML=null;' end it "should catch the property assignment calls too" do @page['element-id'][:title] = 'something'; @page.to_s.should == '$("element-id").title="something";' end it "should process other methods calls as arguments" do @page['element-id'].update(@page.my_method(@page.another_method(1,2),3,nil)) @page.to_s.should == '$("element-id").update(my_method(another_method(1,2),3,null));' end it "should process operation calls" do @page.property = @page.first + @page.another(1,nil) * @page.more / 2 - @page.get(:thing) / @page.another(2) + nil - 'boo' + @page.last(@page.first) @page.to_s.should == 'property=first()+another(1,null)*more()/2-thing/another(2)+null-"boo"+last(first());' end it "should process the append operation" do @page['element'][:innerHTML] << 'boo' @page.to_s.should == '$("element").innerHTML+="boo";' end end describe "data types conversion" do it "should correctly process numeric arguments" do @page['element-id'].test(1, 2.3) @page.to_s.should == '$("element-id").test(1,2.3);' end it "should correctly process boolean and nil values" do @page["element-id"].test(true, false, nil) @page.to_s.should == '$("element-id").test(true,false,null);' end it "should escape string arguments properly" do @template.should_receive(:escape_javascript).with('"quoted"').and_return('_quoted_') @page["element-id"].test('"quoted"') @page.to_s.should == '$("element-id").test("_quoted_");' end it "should convert symbols into object reverences" do @page["element-id"].test(:name1, :name2, :name3) @page.to_s.should == '$("element-id").test(name1,name2,name3);' end it "should handle arrays properly" do @template.should_receive(:escape_javascript).with('"quoted"').and_return('_quoted_') @page["element-id"].test([1,2.3,[nil,[true,'"quoted"']]]) @page.to_s.should == '$("element-id").test([1,2.3,[null,[true,"_quoted_"]]]);' end it "should handle hashes properly" do @page["element-id"].test({ :one => 1, :two => 2.3, 'four' => { 'five' => true, 'six' => nil } }) @page.to_s.should == '$("element-id").test({"four":{"five":true,"six":null},one:1,two:2.3});' end it "should handle JSON exportable units too" do @value = ActiveRecord::Base.new({:id => '22'}); def @value.to_json {:id => id} end @page["element-id"].test(@value) @page.to_s.should == '$("element-id").test({id:"22"});' end it "should convert lambdas to functions" do @page.find("boo").each(lambda{ |item, i, array| item.boo(i.foo(2)) + array.hoo }) @page.to_s.should == '$$("boo").each(function(a,b,c){a.boo(b.foo(2))+c.hoo();});' end it "should process blocks nicely" do @page.find("boo").each do |item, i| item.boo(i.foo('hoo')) end @page.to_s.should == '$$("boo").each(function(a,b){a.boo(b.foo("hoo"));});' end it "should process blocks with scope variables and the page builder calls" do some_text = 'boo' @page.find("foo").each do |item, index| @page['element'][:innerHTML] << item[:innerHTML] + index + some_text end # checking that the context is getting back @page.alert(@page['element'][:innerHTML]) @page.to_s.should == '$$("foo").each(function(a,b){$("element").innerHTML+=a.innerHTML+b+"boo";});alert($("element").innerHTML);' end it "should throw an error for unknown data-types" do class Booooooooooo def respond_to?(name) name.to_sym == :to_json ? false : super(name) end end lambda { @page['element'].insert(Booooooooooo.new) }.should raise_error end end describe "RR object method calls generator" do before :each do @record = ActiveRecord::Base.new({:id => '22'}) end it "should generate script for the 'insert' request" do @template.should_receive(:render).with(@record).and_return('') @page.insert(@record) @page.to_s.should == 'RR.insert("records","");' end it "should generate script for the 'replace' request" do @template.should_receive(:render).with(@record).and_return('') @page.replace(@record) @page.to_s.should == 'RR.replace("record_22","");' end it "should generate script for the 'remove' request" do @page.remove(@record) @page.to_s.should == 'RR.remove("record_22");' end it "should generate script for the 'show_form_for' request" do @template.should_receive(:render).with('form').and_return('') @page.show_form_for(@record) @page.to_s.should == 'RR.show_form_for("record_22","");' end describe "replace_form_for generator" do before :each do @template.should_receive(:render).with('form').and_return('') end it "should generate a script for a new record" do @record.should_receive(:new_record?).and_return(true) @page.replace_form_for(@record) @page.to_s.should == 'RR.replace_form("new_record","");' end it "should generate a script for an existing record" do @record.should_receive(:new_record?).and_return(false) @page.replace_form_for(@record) @page.to_s.should == 'RR.replace_form("edit_record_22","");' end end describe "updates with care" do before :each do @template.should_receive(:flashes).and_return('') @template.should_receive(:flash).and_return(mock(:flash, {:clear => true})) end it "should generate response for #update_flash" do @page.update_flash @page.to_s.should == 'RR.update_flash("");' end it "should generate response for the #insert_and_care method" do @template.should_receive(:render).with('form').and_return('') @template.should_receive(:render).with(@record).and_return('') @page.insert_and_care(@record) @page.to_s.should == 'RR.insert("records","");' + 'RR.replace_form("new_record","");' + 'RR.update_flash("");' end it "should generate response for the #replace_and_care method" do @template.should_receive(:render).with(@record).and_return('') @page.replace_and_care(@record) @page.to_s.should == 'RR.replace("record_22","");' + 'RR.update_flash("");' end end end end