require File.expand_path(File.dirname(__FILE__) + '/test_helper') class RadiusParserTest < Test::Unit::TestCase include RadiusTestHelper def setup @context = new_context @parser = Radius::Parser.new(@context, :tag_prefix => 'r') end def test_initialize @parser = Radius::Parser.new assert_kind_of Radius::Context, @parser.context end def test_initialize_with_params @parser = Radius::Parser.new(TestContext.new) assert_kind_of TestContext, @parser.context @parser = Radius::Parser.new(:context => TestContext.new) assert_kind_of TestContext, @parser.context @parser = Radius::Parser.new('context' => TestContext.new) assert_kind_of TestContext, @parser.context @parser = Radius::Parser.new(:tag_prefix => 'r') assert_kind_of Radius::Context, @parser.context assert_equal 'r', @parser.tag_prefix @parser = Radius::Parser.new(TestContext.new, :tag_prefix => 'r') assert_kind_of TestContext, @parser.context assert_equal 'r', @parser.tag_prefix end def test_parse_tag_with_dashes define_tag 'some-tag' do |tag| 'ok' end assert_parse_output 'ok', 'nope' end def test_parse_individual_tags_and_parameters define_tag "add" do |tag| tag.attr["param1"].to_i + tag.attr["param2"].to_i end assert_parse_output "<3>", %{<>} end def test_parse_attributes attributes = %{{"a"=>"1", "b"=>"2", "c"=>"3", "d"=>"'"}} assert_parse_output attributes, %{} assert_parse_output attributes, %{} end def test_parse_attributes_with_slashes_or_angle_brackets slash = %{{"slash"=>"/"}} angle = %{{"angle"=>">"}} assert_parse_output slash, %{} assert_parse_output slash, %{} assert_parse_output angle, %{} end def test_parse_quotes assert_parse_output "test []", %{ } end def test_things_that_should_be_left_alone [ %{ test="2"="4" }, %{="2" } ].each do |middle| assert_parsed_is_unchanged "" assert_parsed_is_unchanged "" end end def test_tags_inside_html_tags assert_parse_output %{
tags in yo tags
}, %{
tags in yo tags
} end def test_parse_result_is_always_a_string define_tag("twelve") { 12 } assert_parse_output "12", "" end def test_parse_double_tags assert_parse_output "test".reverse, "test" assert_parse_output "tset TEST", "test test" end def test_parse_tag_nesting define_tag("parent", :for => '') define_tag("parent:child", :for => '') define_tag("extra", :for => '') define_tag("nesting") { |tag| tag.nesting } define_tag("extra:nesting") { |tag| tag.nesting.gsub(':', ' > ') } define_tag("parent:child:nesting") { |tag| tag.nesting.gsub(':', ' * ') } assert_parse_output "nesting", "" assert_parse_output "parent:nesting", "" assert_parse_output "extra > nesting", "" assert_parse_output "parent * child * nesting", "" assert_parse_output "parent > extra > nesting", "" assert_parse_output "parent > child > extra > nesting", "" assert_parse_output "parent * extra * child * nesting", "" assert_parse_output "parent > extra > child > extra > nesting", "" assert_parse_output "parent > extra > child > extra > nesting", "" assert_parse_output "extra * parent * child * nesting", "" assert_parse_output "extra > parent > nesting", "" assert_parse_output "extra * parent * child * nesting", "" assert_raises(Radius::UndefinedTagError) { @parser.parse("") } end def test_parse_tag_nesting_2 define_tag("parent", :for => '') define_tag("parent:child", :for => '') define_tag("content") { |tag| tag.nesting } assert_parse_output 'parent:child:content', '' end def test_parse_tag__binding_do_missing define_tag 'test' do |tag| tag.missing! end e = assert_raises(Radius::UndefinedTagError) { @parser.parse("") } assert_equal "undefined tag `test'", e.message end def test_parse_chirpy_bird # :> chirp chirp assert_parse_output "<:", "<:" end def test_parse_tag__binding_render_tag define_tag('test') { |tag| "Hello #{tag.attr['name']}!" } define_tag('hello') { |tag| tag.render('test', tag.attr) } assert_parse_output 'Hello John!', '' end def test_accessing_tag_attributes_through_tag_indexer define_tag('test') { |tag| "Hello #{tag['name']}!" } assert_parse_output 'Hello John!', '' end def test_parse_tag__binding_render_tag_with_block define_tag('test') { |tag| "Hello #{tag.expand}!" } define_tag('hello') { |tag| tag.render('test') { tag.expand } } assert_parse_output 'Hello John!', 'John' end def test_tag_locals define_tag "outer" do |tag| tag.locals.var = 'outer' tag.expand end define_tag "outer:inner" do |tag| tag.locals.var = 'inner' tag.expand end define_tag "outer:var" do |tag| tag.locals.var end assert_parse_output 'outer', "" assert_parse_output 'outer:inner:outer', "::" assert_parse_output 'outer:inner:outer:inner:outer', "::::" assert_parse_output 'outer', "" end def test_tag_globals define_tag "set" do |tag| tag.globals.var = tag.attr['value'] '' end define_tag "var" do |tag| tag.globals.var end assert_parse_output " true false", %{ } end def test_parse_loops @item = nil define_tag "each" do |tag| result = [] ["Larry", "Moe", "Curly"].each do |item| tag.locals.item = item result << tag.expand end result.join(tag.attr["between"] || "") end define_tag "each:item" do |tag| tag.locals.item end assert_parse_output %{Three Stooges: "Larry", "Moe", "Curly"}, %{Three Stooges: ""} end def test_parse_speed define_tag "set" do |tag| tag.globals.var = tag.attr['value'] '' end define_tag "var" do |tag| tag.globals.var end parts = %w{decima nobis augue at facer processus commodo legentis odio lectorum dolore nulla esse lius qui nonummy ullamcorper erat ii notare} multiplier = parts.map{|p| "#{p}=\"#{rand}\""}.join(' ') assert_nothing_raised do Timeout.timeout(10) do assert_parse_output " false", %{ } end end end def test_tag_option_for define_tag 'fun', :for => 'just for kicks' assert_parse_output 'just for kicks', '' end def test_tag_expose_option define_tag 'user', :for => users.first, :expose => ['name', :age] assert_parse_output 'John', '' assert_parse_output '25', '' e = assert_raises(Radius::UndefinedTagError) { @parser.parse "" } assert_equal "undefined tag `email'", e.message end def test_tag_expose_attributes_option_on_by_default define_tag 'user', :for => user_with_attributes assert_parse_output 'John', '' end def test_tag_expose_attributes_set_to_false define_tag 'user_without_attributes', :for => user_with_attributes, :attributes => false assert_raises(Radius::UndefinedTagError) { @parser.parse "" } end def test_tag_options_must_contain_a_for_option_if_methods_are_exposed e = assert_raises(ArgumentError) { define_tag('fun', :expose => :today) { 'test' } } assert_equal "tag definition must contain a :for option when used with the :expose option", e.message end def test_parse_fail_on_missing_end_tag assert_raises(Radius::MissingEndTagError) { @parser.parse("") } end def test_parse_fail_on_wrong_end_tag assert_raises(Radius::WrongEndTagError) { @parser.parse("") } end def test_parse_with_default_tag_prefix @parser = Radius::Parser.new(@context) define_tag("hello") { |tag| "Hello world!" } assert_equal "

Hello world!

", @parser.parse('

') end def test_parse_with_other_radius_like_tags @parser = Radius::Parser.new(@context, :tag_prefix => "ralph") define_tag('hello') { "hello" } assert_equal "", @parser.parse("") end def test_copyin_global_values @context.globals.foo = 'bar' assert_equal 'bar', Radius::Parser.new(@context).context.globals.foo end def test_does_not_pollute_copied_globals @context.globals.foo = 'bar' parser = Radius::Parser.new(@context) parser.context.globals.foo = '[baz]' assert_equal 'bar', @context.globals.foo end def test_parse_with_other_namespaces @parser = Radius::Parser.new(@context, :tag_prefix => 'r') assert_equal "hello world", @parser.parse("hello world") end protected def assert_parse_output(output, input, message = nil) r = @parser.parse(input) assert_equal(output, r, message) end def assert_parsed_is_unchanged(something) assert_parse_output something, something end class User attr_accessor :name, :age, :email, :friend def initialize(name, age, email) @name, @age, @email = name, age, email end def <=>(other) name <=> other.name end end class UserWithAttributes < User def attributes { :name => name, :age => age, :email => email } end end def users [ User.new('John', 25, 'test@johnwlong.com'), User.new('James', 27, 'test@jameslong.com') ] end def user_with_attributes UserWithAttributes.new('John', 25, 'test@johnwlong.com') end end