#!/usr/bin/env ruby require 'test/unit' currentPath = File.dirname(__FILE__) require File.join( currentPath, '../../lib/masterview' ) require File.join( currentPath, '../test_helper' ) class DirectiveExample < MasterView::DirectiveBase attr_arg :obj, :quote => true attr_arg(:method) { 'override' } attr_arg(:foo) { |x| x.downcase } attr_arg :collection, :quote => true attr_arg :value_method, :quote => true attr_arg :text_method, :quote => true attr_arg :options, :default => {} attr_arg :html_options, :append_element_attrs => [:common_html, :onclick] event :before_stag do render erb_content( 'text_area', :obj, :method, :foo ) end event :after_stag, :foo => :bar do render :nothing end event :content, :render => :nothing #rolls up all content between after_stag and before_etag event :stag do # unless render something or render :nothing is called, then dcs.render will still occur implicitely end event :etag do con = render_result() # get the dcs.render result so we can modify it con.gsub!( /foo/, 'bar' ) render con end event :element do # this will allow replacement of entire element and children render erb_eval( 'execute something' ) end end class DirectiveExampleNoStag < MasterView::DirectiveBase event :before_stag do render 'foo' end event :after_etag, :render => :nothing end class DirectiveExampleRenderNothingOption < MasterView::DirectiveBase event :before_stag do render 'foo' end event :stag, :render => :nothing event :etag, :render => :nothing do render 'this should not be rendered' end end class DirectiveExampleRenderNothingContent < MasterView::DirectiveBase event :stag do self.content = 'this is content, but will not be rendered' render 'foo' end event :content, :render => :nothing event :etag do render 'bar' end end class DirectiveExampleRenderNothingElement < MasterView::DirectiveBase event :stag do self.content = 'this is content, but will not be rendered' render 'foo' end event :etag do render 'bar' end event :element, :render => :nothing end class DirectiveExampleRenderNothingMethod < MasterView::DirectiveBase event :stag do render 'this will be cancelled out by :nothing call' render :nothing end end class DirectiveExampleParamsArray < MasterView::DirectiveBase attr_arg :obj attr_arg :params, :varargs => true event :stag do render erb_content( 'foo', :obj, :params ) end end class DirectiveExampleNonhashFirstString < MasterView::DirectiveBase attr_arg :name do |value, args| if value.respond_to?(:include?) and value.include?('=>') args.unshift value nil else value end end attr_arg :options end class DirectiveExampleInst < MasterView::DirectiveBase attr_arg :name do |value, args, inst| if value.respond_to?(:include?) and value.include?('=>') args.unshift value inst.quote(inst.element_attrs[:foo]) else value end end attr_arg :options event :etag do render erb_content( 'test', :name, :options ) end end class DirectiveWithChild < MasterView::DirectiveBase event :before_child_td_stag do end event :child_any_etag do end event :descendant_th_content do end event :after_descendant_th_etag do end event :descendant_th_etag do end end class TestDirectiveBaseNew < Test::Unit::TestCase # shortcut refs for internal DirectiveDSL implementation classes EventDef = MasterView::DirectiveProcessing::EventDef RenderAccumulator = MasterView::DirectiveProcessing::RenderAccumulator def setup @base = MasterView::DirectiveBase.new('') end def test_quote assert_equal '\'hello\'', @base.quote('hello') end def test_quote_double assert_equal '"hello"', @base.quote('hello', '"') end def test_quote_if assert_equal '\'helloWorld0123\'', @base.quote_if('helloWorld0123') assert_equal 'hello world', @base.quote_if('hello world') assert_equal 'hello,world', @base.quote_if('hello,world') assert_equal 'hello(world)', @base.quote_if('hello(world)') assert_equal ':hello', @base.quote_if(':hello') assert_equal '\"hello world\"', @base.quote_if('\"hello world\"') assert_equal '%q{helloworld}', @base.quote_if('%q{helloworld}') assert_equal 'hello.world', @base.quote_if('hello.world') assert_equal 'hel/lo.w_orld', @base.quote_if('hel/lo.w_orld') assert_equal '\'\'', @base.quote_if('') end def test_event_def_valid_mappings assert EventDef.valid_event_mapping?( :before_stag ) assert EventDef.valid_event_mapping?( :stag ) assert EventDef.valid_event_mapping?( :after_stag ) assert EventDef.valid_event_mapping?( :content ) assert EventDef.valid_event_mapping?( :before_etag ) assert EventDef.valid_event_mapping?( :etag ) assert EventDef.valid_event_mapping?( :after_etag ) assert EventDef.valid_event_mapping?( :element ) assert EventDef.valid_event_mapping?( :before_child_td_stag ) assert EventDef.valid_event_mapping?( :child_td_stag ) assert EventDef.valid_event_mapping?( :after_child_td_stag ) assert EventDef.valid_event_mapping?( :child_td_content ) assert EventDef.valid_event_mapping?( :child_td_element ) assert EventDef.valid_event_mapping?( :before_child_any_stag ) assert EventDef.valid_event_mapping?( :child_any_stag ) assert EventDef.valid_event_mapping?( :after_child_any_stag ) assert EventDef.valid_event_mapping?( :child_any_content ) assert EventDef.valid_event_mapping?( :child_any_element ) assert EventDef.valid_event_mapping?( :before_child_tbody_td_stag ) assert EventDef.valid_event_mapping?( :child_tbody_td_stag ) assert EventDef.valid_event_mapping?( :after_child_tbody_td_stag ) assert EventDef.valid_event_mapping?( :child_tbody_td_content ) assert EventDef.valid_event_mapping?( :child_tbody_td_element ) assert EventDef.valid_event_mapping?( :before_descendant_td_stag ) assert EventDef.valid_event_mapping?( :descendant_td_stag ) assert EventDef.valid_event_mapping?( :after_descendant_td_stag ) assert EventDef.valid_event_mapping?( :descendant_td_content ) assert EventDef.valid_event_mapping?( :descendant_td_element ) assert EventDef.valid_event_mapping?( :before_descendant_any_stag ) assert EventDef.valid_event_mapping?( :descendant_any_stag ) assert EventDef.valid_event_mapping?( :after_descendant_any_stag ) assert EventDef.valid_event_mapping?( :descendant_any_content ) assert EventDef.valid_event_mapping?( :descendant_any_element ) assert EventDef.valid_event_mapping?( :before_descendant_tbody_td_stag ) assert EventDef.valid_event_mapping?( :descendant_tbody_td_stag ) assert EventDef.valid_event_mapping?( :after_descendant_tbody_td_stag ) assert EventDef.valid_event_mapping?( :descendant_tbody_td_content ) assert EventDef.valid_event_mapping?( :descendant_tbody_td_element ) assert !EventDef.valid_event_mapping?( :foo ) assert !EventDef.valid_event_mapping?( :child_bar ) assert !EventDef.valid_event_mapping?( :before_child_hello ) end def test_event_def_base_method assert_equal [:stag], EventDef.base_methods_from_event( :before_stag ) assert_equal [:stag], EventDef.base_methods_from_event( :stag ) assert_equal [:stag], EventDef.base_methods_from_event( :after_stag ) assert_equal [:etag], EventDef.base_methods_from_event( :content ) assert_equal [:etag], EventDef.base_methods_from_event( :before_etag ) assert_equal [:etag], EventDef.base_methods_from_event( :etag ) assert_equal [:etag], EventDef.base_methods_from_event( :after_etag ) assert_equal [:stag, :etag], EventDef.base_methods_from_event( :element ) assert_equal [:child_td_stag], EventDef.base_methods_from_event( :before_child_td_stag ) assert_equal [:child_td_stag], EventDef.base_methods_from_event( :child_td_stag ) assert_equal [:child_td_stag], EventDef.base_methods_from_event( :after_child_td_stag ) assert_equal [:child_td_etag], EventDef.base_methods_from_event( :child_td_content ) assert_equal [:child_td_stag, :child_td_etag], EventDef.base_methods_from_event( :child_td_element ) assert_equal [:child_any_stag], EventDef.base_methods_from_event( :before_child_any_stag ) assert_equal [:child_any_stag], EventDef.base_methods_from_event( :child_any_stag ) assert_equal [:child_any_stag], EventDef.base_methods_from_event( :after_child_any_stag ) assert_equal [:child_any_etag], EventDef.base_methods_from_event( :child_any_content ) assert_equal [:child_any_stag, :child_any_etag], EventDef.base_methods_from_event( :child_any_element ) assert_equal [:child_tbody_td_stag], EventDef.base_methods_from_event( :before_child_tbody_td_stag ) assert_equal [:child_tbody_td_stag], EventDef.base_methods_from_event( :child_tbody_td_stag ) assert_equal [:child_tbody_td_stag], EventDef.base_methods_from_event( :after_child_tbody_td_stag ) assert_equal [:child_tbody_td_etag], EventDef.base_methods_from_event( :child_tbody_td_content ) assert_equal [:child_tbody_td_stag, :child_tbody_td_etag], EventDef.base_methods_from_event( :child_tbody_td_element ) assert_equal [:descendant_td_stag], EventDef.base_methods_from_event( :before_descendant_td_stag ) assert_equal [:descendant_td_stag], EventDef.base_methods_from_event( :descendant_td_stag ) assert_equal [:descendant_td_stag], EventDef.base_methods_from_event( :after_descendant_td_stag ) assert_equal [:descendant_td_etag], EventDef.base_methods_from_event( :descendant_td_content ) assert_equal [:descendant_td_stag, :descendant_td_etag], EventDef.base_methods_from_event( :descendant_td_element ) assert_equal [:descendant_any_stag], EventDef.base_methods_from_event( :before_descendant_any_stag ) assert_equal [:descendant_any_stag], EventDef.base_methods_from_event( :descendant_any_stag ) assert_equal [:descendant_any_stag], EventDef.base_methods_from_event( :after_descendant_any_stag ) assert_equal [:descendant_any_etag], EventDef.base_methods_from_event( :descendant_any_content ) assert_equal [:descendant_any_stag, :descendant_any_etag], EventDef.base_methods_from_event( :descendant_any_element ) assert_equal [:descendant_tbody_td_stag], EventDef.base_methods_from_event( :before_descendant_tbody_td_stag ) assert_equal [:descendant_tbody_td_stag], EventDef.base_methods_from_event( :descendant_tbody_td_stag ) assert_equal [:descendant_tbody_td_stag], EventDef.base_methods_from_event( :after_descendant_tbody_td_stag ) assert_equal [:descendant_tbody_td_etag], EventDef.base_methods_from_event( :descendant_tbody_td_content ) assert_equal [:descendant_tbody_td_stag, :descendant_tbody_td_etag], EventDef.base_methods_from_event( :descendant_tbody_td_element ) end def test_event_def_method_events_from_base assert_equal [:before_stag, :stag, :after_stag], EventDef.method_events_from_base( :stag ) assert_equal [:before_child_td_stag, :child_td_stag, :after_child_td_stag], EventDef.method_events_from_base( :child_td_stag ) assert_equal [:before_child_any_stag, :child_any_stag, :after_child_any_stag], EventDef.method_events_from_base( :child_any_stag ) assert_equal [:before_child_tbody_td_stag, :child_tbody_td_stag, :after_child_tbody_td_stag], EventDef.method_events_from_base( :child_tbody_td_stag ) assert_equal [:before_descendant_td_stag, :descendant_td_stag, :after_descendant_td_stag], EventDef.method_events_from_base( :descendant_td_stag ) assert_equal [:before_descendant_tbody_td_stag, :descendant_tbody_td_stag, :after_descendant_tbody_td_stag], EventDef.method_events_from_base( :descendant_tbody_td_stag ) assert_equal [:content, :before_etag, :etag, :after_etag, :element], EventDef.method_events_from_base( :etag ) assert_equal [:child_tbody_td_content, :before_child_tbody_td_etag, :child_tbody_td_etag, :after_child_tbody_td_etag, :child_tbody_td_element], EventDef.method_events_from_base( :child_tbody_td_etag ) assert_equal [:descendant_td_content, :before_descendant_td_etag, :descendant_td_etag, :after_descendant_td_etag, :descendant_td_element], EventDef.method_events_from_base( :descendant_td_etag ) assert_equal [:descendant_tbody_td_content, :before_descendant_tbody_td_etag, :descendant_tbody_td_etag, :after_descendant_tbody_td_etag, :descendant_tbody_td_element], EventDef.method_events_from_base( :descendant_tbody_td_etag ) end # return array of events to check for the base # :stag => [:before_stag, :stag, :after_stag], # :etag => [:content, :before_etag, :etag, :after_etag, :element] # def self.method_events_from_base(base_sym) # base_str = base_sym.to_s # case base_str # when /(.*)stag/ # [ # ('before_'+base_str).to_sym, # base_sym, # ('after_'+base_str).to_sym # ] # when /(.*)etag/ # [ # ('\1content').to_sym, # ('before_'+base_str).to_sym, # base_sym, # ('after_'+base_str).to_sym, # ('\1element').to_sym # ] # end # end def test_attr_arg_defs assert_equal 8, DirectiveExample.directive_class_def.attr_arg_defs.size assert_equal :obj, DirectiveExample.directive_class_def.attr_arg_defs[0].name assert_equal :method, DirectiveExample.directive_class_def.attr_arg_defs[1].name assert_equal :foo, DirectiveExample.directive_class_def.attr_arg_defs[2].name assert_equal :collection, DirectiveExample.directive_class_def.attr_arg_defs[3].name assert_equal :value_method, DirectiveExample.directive_class_def.attr_arg_defs[4].name assert_equal :text_method, DirectiveExample.directive_class_def.attr_arg_defs[5].name assert_equal :options, DirectiveExample.directive_class_def.attr_arg_defs[6].name assert_equal :html_options, DirectiveExample.directive_class_def.attr_arg_defs[7].name assert_equal :obj, DirectiveExample.directive_class_def.find_attr_arg_def_by_name(:obj).name assert_equal :method, DirectiveExample.directive_class_def.find_attr_arg_def_by_name(:method).name assert_equal :foo, DirectiveExample.directive_class_def.find_attr_arg_def_by_name(:foo).name assert_equal :collection, DirectiveExample.directive_class_def.find_attr_arg_def_by_name(:collection).name assert_equal :value_method, DirectiveExample.directive_class_def.find_attr_arg_def_by_name(:value_method).name assert_equal :text_method, DirectiveExample.directive_class_def.find_attr_arg_def_by_name(:text_method).name assert_equal :options, DirectiveExample.directive_class_def.find_attr_arg_def_by_name(:options).name assert_equal :html_options, DirectiveExample.directive_class_def.find_attr_arg_def_by_name(:html_options).name assert_equal( { :quote => true }, DirectiveExample.directive_class_def.attr_arg_defs[0].options ) assert_equal( { }, DirectiveExample.directive_class_def.attr_arg_defs[1].options ) assert_equal( { }, DirectiveExample.directive_class_def.attr_arg_defs[2].options ) assert_equal( { :quote => true }, DirectiveExample.directive_class_def.attr_arg_defs[3].options ) assert_equal( { :quote => true }, DirectiveExample.directive_class_def.attr_arg_defs[4].options ) assert_equal( { :quote => true }, DirectiveExample.directive_class_def.attr_arg_defs[5].options ) assert_equal( { :default => {} }, DirectiveExample.directive_class_def.attr_arg_defs[6].options ) assert_equal( {}, DirectiveExample.directive_class_def.attr_arg_defs[6].optional_default ) assert_equal( { :append_element_attrs => [:common_html, :onclick] }, DirectiveExample.directive_class_def.attr_arg_defs[7].options ) end def test_prepare_arg_instance_vars d = DirectiveExample.new('product, desc, "Foo", coll, val, text, {:foo => :bar}, :readonly => false') d.save_directive_call_stack(MasterView::ParserMock.createMockDCS()) d.element_attrs['class'] = 'red' d.element_attrs['id'] = 'id1' d.element_attrs['onclick'] = 'jsfunc' d.prepare_arg_instance_vars assert_equal "'product'", d.instance_variable_get(:@obj) assert_equal 'override', d.instance_variable_get(:@method) assert_equal '"foo"', d.instance_variable_get(:@foo) assert_equal "'coll'", d.instance_variable_get(:@collection) assert_equal "'val'", d.instance_variable_get(:@value_method) assert_equal "'text'", d.instance_variable_get(:@text_method) assert_equal '{:foo => :bar}', d.instance_variable_get(:@options) assert_equal ':readonly => false, :class => "red", :id => "id1", :onclick => "jsfunc"', d.instance_variable_get(:@html_options) end def test_params_array d = DirectiveExampleParamsArray.new('product, desc, "Foo", coll, val, text, {:foo => :bar}, :readonly => false') dcs = MasterView::ParserMock.createMockDCS() d.save_directive_call_stack(dcs) d.prepare_arg_instance_vars assert_equal "product", d.instance_variable_get(:@obj) assert_equal ['desc', '"Foo"', 'coll', 'val', 'text', '{:foo => :bar}', ':readonly => false'], d.instance_variable_get(:@params) d = DirectiveExampleParamsArray.new('product, desc, hello, world') dcs = MasterView::ParserMock.createMockDCS() d.save_directive_call_stack(dcs) assert_equal ['<%= foo( product, desc, hello, world ) %>'], d.stag(dcs) d = DirectiveExampleParamsArray.new('product') d.save_directive_call_stack(MasterView::ParserMock.createMockDCS()) d.prepare_arg_instance_vars assert_equal "product", d.instance_variable_get(:@obj) assert_equal [], d.instance_variable_get(:@params) d = DirectiveExampleParamsArray.new('product') dcs = MasterView::ParserMock.createMockDCS() d.save_directive_call_stack(dcs) assert_equal ['<%= foo( product ) %>'], d.stag(dcs) d = DirectiveExampleParamsArray.new(":action => 'create'") d.save_directive_call_stack(MasterView::ParserMock.createMockDCS()) d.prepare_arg_instance_vars assert_equal ":action => 'create'", d.instance_variable_get(:@obj) end def test_nonhash_first_string d = DirectiveExampleNonhashFirstString.new('foo, :bar => :baz') dcs = MasterView::ParserMock.createMockDCS() d.save_directive_call_stack(dcs) d.prepare_arg_instance_vars assert_equal "foo", d.instance_variable_get(:@name) assert_equal ":bar => :baz", d.instance_variable_get(:@options) d = DirectiveExampleNonhashFirstString.new(':bar => :baz') dcs = MasterView::ParserMock.createMockDCS() d.save_directive_call_stack(dcs) d.prepare_arg_instance_vars assert_nil d.instance_variable_get(:@name) assert_equal ":bar => :baz", d.instance_variable_get(:@options) end def test_inst d = DirectiveExampleInst.new(':bar => :baz') dcs = MasterView::ParserMock.createMockDCS() d.save_directive_call_stack(dcs) d.element_attrs[:foo] = 'hello' d.prepare_arg_instance_vars assert_equal "'hello'", d.instance_variable_get(:@name) assert_equal ":bar => :baz", d.instance_variable_get(:@options) end def test_event_defs assert_equal 6, DirectiveExample.directive_class_def.event_defs.size assert DirectiveExample.directive_class_def.event_defs[:before_stag] assert DirectiveExample.directive_class_def.event_defs[:after_stag] assert DirectiveExample.directive_class_def.event_defs[:stag] assert DirectiveExample.directive_class_def.event_defs[:content] assert DirectiveExample.directive_class_def.event_defs[:etag] assert DirectiveExample.directive_class_def.event_defs[:element] assert !DirectiveExample.directive_class_def.event_defs[:doesnt_exist] assert_equal( {}, DirectiveExample.directive_class_def.event_defs[:before_stag].options ) assert_equal( {:foo => :bar}, DirectiveExample.directive_class_def.event_defs[:after_stag].options ) assert_equal( {}, DirectiveExample.directive_class_def.event_defs[:stag].options ) assert_equal( { :render => :nothing }, DirectiveExample.directive_class_def.event_defs[:content].options ) assert_equal( {}, DirectiveExample.directive_class_def.event_defs[:etag].options ) assert_equal( {}, DirectiveExample.directive_class_def.event_defs[:element].options ) end def test_methods_defined assert DirectiveExample.public_method_defined?(:stag) assert DirectiveExample.public_method_defined?(:etag) assert !DirectiveExample.public_method_defined?(:before_stag) assert !DirectiveExample.public_method_defined?(:after_stag) end def test_render_accumulator ra = RenderAccumulator.new assert_equal [], ra.method_level_content_array assert_equal [], ra.event_level_content_array assert_equal false, ra.render_call_found assert_nil ra.instance_variable_get(:@render_result) assert_nil ra.instance_variable_get(:@render_result_block) ra.add_to_event_content 'foo' assert_equal [], ra.method_level_content_array assert_equal ['foo'], ra.event_level_content_array assert_equal true, ra.render_call_found ra.add_to_event_content 'bar' assert_equal [], ra.method_level_content_array assert_equal ['foo', 'bar'], ra.event_level_content_array assert_equal true, ra.render_call_found ra.add_event_content_to_method_content assert_equal ['foo', 'bar'], ra.method_level_content_array assert_equal [], ra.event_level_content_array assert_equal true, ra.render_call_found ra.add_to_event_content 'hello' ra.replace_all_method_content_with_event_content assert_equal ['hello'], ra.method_level_content_array ra.add_to_event_content 'hello' ra.reset_event_level_vars assert_equal [], ra.event_level_content_array assert_equal false, ra.render_call_found assert_nil ra.instance_variable_get(:@render_result) assert_nil ra.instance_variable_get(:@render_result_block) ra.render_result_block = lambda { ra.render_result = 'wow' } assert_equal 'wow', ra.call_render_result_block assert_equal 'wow', ra.instance_variable_get(:@render_result) ra.render_result = 'changed' assert_nil ra.instance_variable_get(:@render_result_block) assert_equal 'changed', ra.instance_variable_get(:@render_result) end def test_no_stag assert DirectiveExampleNoStag.public_method_defined?(:stag) assert DirectiveExampleNoStag.public_method_defined?(:etag) end def test_event_defs_no_stag assert_equal 4, DirectiveExampleNoStag.directive_class_def.event_defs.size assert DirectiveExampleNoStag.directive_class_def.event_defs[:before_stag] assert DirectiveExampleNoStag.directive_class_def.event_defs[:after_etag] assert DirectiveExampleNoStag.directive_class_def.event_defs[:stag] assert DirectiveExampleNoStag.directive_class_def.event_defs[:etag] end def test_nothing_option d = DirectiveExampleRenderNothingOption.new('') dcs = MasterView::ParserMock.createMockDCS() d.save_directive_call_stack(dcs) assert_equal ['foo'], d.stag(dcs) assert_equal [], d.etag(dcs) end def test_nothing_option_content d = DirectiveExampleRenderNothingContent.new('') dcs = MasterView::ParserMock.createMockDCS() d.save_directive_call_stack(dcs) d.etag(dcs) assert_equal nil, dcs.content end def test_nothing_option_element d = DirectiveExampleRenderNothingElement.new('') dcs = MasterView::ParserMock.createMockDCS() d.save_directive_call_stack(dcs) assert_equal ['foo'], d.stag(dcs) assert_equal [], d.etag(dcs) assert_equal nil, dcs.content assert_equal nil, dcs.stag end def test_nothing_method d = DirectiveExampleRenderNothingMethod.new('') dcs = MasterView::ParserMock.createMockDCS() d.save_directive_call_stack(dcs) assert_equal [], d.stag(dcs) end def test_event_defs_for_child assert_equal 6, DirectiveWithChild.directive_class_def.event_defs.size assert DirectiveWithChild.directive_class_def.event_defs[:before_child_td_stag] assert DirectiveWithChild.directive_class_def.event_defs[:child_td_stag] assert DirectiveWithChild.directive_class_def.event_defs[:child_any_etag] assert DirectiveWithChild.directive_class_def.event_defs[:descendant_th_content] assert DirectiveWithChild.directive_class_def.event_defs[:after_descendant_th_etag] assert DirectiveWithChild.directive_class_def.event_defs[:descendant_th_etag] assert DirectiveWithChild.public_method_defined?(:child_td_stag) assert DirectiveWithChild.public_method_defined?(:child_any_etag) assert DirectiveWithChild.public_method_defined?(:descendant_th_etag) end end