#!/usr/bin/env ruby -wW1 # encoding: UTF-8 $: << File.join(File.dirname(__FILE__), "../lib") $: << File.join(File.dirname(__FILE__), "../ext") require 'test/unit' require 'optparse' require 'ox' $indent = 2 opts = OptionParser.new # TBD add indent opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) } files = opts.parse(ARGV) class Func < ::Test::Unit::TestCase def test_get_options opts = Ox.default_options() assert_equal(opts, { :encoding=>nil, :indent=>2, :trace=>0, :with_dtd=>false, :with_xml=>false, :with_instructions=>false, :circular=>false, :xsd_date=>false, :mode=>nil, :effort=>:strict}) end def test_set_options orig = { :encoding=>nil, :indent=>2, :trace=>0, :with_dtd=>false, :with_xml=>true, :with_instructions=>false, :circular=>false, :xsd_date=>false, :mode=>nil, :effort=>:strict} o2 = { :encoding=>"UTF-8", :indent=>4, :trace=>1, :with_dtd=>true, :with_xml=>false, :with_instructions=>true, :circular=>true, :xsd_date=>true, :mode=>:object, :effort=>:tolerant } o3 = { :xsd_date=>false } Ox.default_options = o2 opts = Ox.default_options() assert_equal(opts, o2); Ox.default_options = o3 # see if it throws an exception Ox.default_options = orig # return to original end def test_nil dump_and_load(nil, false) end def test_true dump_and_load(true, false) end def test_false dump_and_load(false, false) end def test_fixnum dump_and_load(7, false) dump_and_load(-19, false) dump_and_load(0, false) end def test_float dump_and_load(7.7, false) dump_and_load(-1.9, false) dump_and_load(0.0, false) dump_and_load(-10.000005, false) dump_and_load(1.000000000005, false) end def test_string dump_and_load('a string', false) dump_and_load('', false) end def test_symbol dump_and_load(:a_symbol, false) dump_and_load(:<=, false) end def test_base64 dump_and_load('a & x', false) end def test_time dump_and_load(Time.now, false) end def test_array dump_and_load([], false) dump_and_load([1, 'a'], false) end def test_hash dump_and_load({ }, false) dump_and_load({ 'a' => 1, 2 => 'b' }, false) end def test_range if RUBY_VERSION.start_with?('1.8') assert(true) else dump_and_load((0..3), false) dump_and_load((-2..3.7), false) dump_and_load(('a'...'f'), false) t = Time.now t2 = t + 20 dump_and_load((t..t2), false) end end def test_regex if RUBY_VERSION.start_with?('1.8') assert(true) else dump_and_load(/^[0-9]/ix, false) dump_and_load(/^[&0-9]/ix, false) # with xml-unfriendly character end end def test_bignum dump_and_load(7 ** 55, false) dump_and_load(-7 ** 55, false) end def test_complex_number if RUBY_VERSION.start_with?('1.8') assert(true) else dump_and_load(Complex(1), false) dump_and_load(Complex(3, 2), false) end end def test_rational if RUBY_VERSION.start_with?('1.8') assert(true) else dump_and_load(Rational(1, 3), false) dump_and_load(Rational(0, 3), false) end end def test_object dump_and_load(Bag.new({ }), false) dump_and_load(Bag.new(:@x => 3), false) end def test_bad_object xml = %{ 3 } xml2 = %{ 7 } assert_raise(NameError) { Ox.load(xml, :mode => :object, :trace => 0) } loaded = Ox.load(xml, :mode => :object, :trace => 0, :effort => :tolerant) assert_equal(loaded, nil) loaded = Ox.load(xml, :mode => :object, :trace => 0, :effort => :auto_define) assert_equal(loaded.class.to_s, 'Bad::Boy') assert_equal(loaded.class.superclass.to_s, 'Ox::Bag') loaded = Ox.load(xml2, :mode => :object, :trace => 0, :effort => :auto_define) assert_equal(loaded.class.to_s, 'Bad') assert_equal(loaded.class.superclass.to_s, 'Ox::Bag') end def test_xml_instruction xml = Ox.dump("test", :mode => :object, :with_xml => false) assert_equal("test\n", xml) xml = Ox.dump("test", :mode => :object, :with_xml => true) assert_equal("\ntest\n", xml) xml = Ox.dump("test", :mode => :object, :with_xml => true, :encoding => 'UTF-8') assert_equal("\ntest\n", xml) end def test_ox_instruction xml = Ox.dump("test", :mode => :object, :with_xml => true, :with_instructions => true) assert_equal("\n\ntest\n", xml) xml = Ox.dump("test", :mode => :object, :with_instructions => true) assert_equal("\ntest\n", xml) xml = Ox.dump("test", :mode => :object, :with_instructions => true, :circular => true, :xsd_date => true) assert_equal("\ntest\n", xml) xml = Ox.dump("test", :mode => :object, :with_instructions => true, :circular => false, :xsd_date => false) assert_equal("\ntest\n", xml) end def test_dtd xml = Ox.dump("test", :mode => :object, :with_dtd => true) assert_equal("\ntest\n", xml) end def test_lone_dtd xml = "" # not really a valid xml but should pass anyway doc = Ox.parse(xml) assert_equal('html', doc.nodes[0].value) end def test_class dump_and_load(Bag, false) end def test_exception if RUBY_VERSION.start_with?('1.8') assert(true) else e = StandardError.new("Some Error") e.set_backtrace(["./func.rb:119: in test_exception", "./fake.rb:57: in fake_func"]) end dump_and_load(e, false) end def test_struct s = Struct.new('Box', :x, :y, :w, :h) dump_and_load(s.new(2, 4, 10, 20), false) end def test_bad_format xml = "\ntest\n" assert_raise(SyntaxError) { Ox.load(xml, :mode => :generic, :trace => 0) } end def test_array_multi if RUBY_VERSION.start_with?('1.8') dump_and_load([nil, true, false, 3, 'z', 7.9, 'a&b', :xyz, Time.now], false) else dump_and_load([nil, true, false, 3, 'z', 7.9, 'a&b', :xyz, Time.now, (-1..7)], false) end end def test_hash_multi if RUBY_VERSION.start_with?('1.8') dump_and_load({ nil => nil, true => true, false => false, 3 => 3, 'z' => 'z', 7.9 => 7.9, 'a&b' => 'a&b', :xyz => :xyz, Time.now => Time.now }, false) else dump_and_load({ nil => nil, true => true, false => false, 3 => 3, 'z' => 'z', 7.9 => 7.9, 'a&b' => 'a&b', :xyz => :xyz, Time.now => Time.now, (-1..7) => (-1..7) }, false) end end def test_object_multi if RUBY_VERSION.start_with?('1.8') dump_and_load(Bag.new(:@a => nil, :@b => true, :@c => false, :@d => 3, :@e => 'z', :@f => 7.9, :@g => 'a&b', :@h => :xyz, :@i => Time.now), false) else dump_and_load(Bag.new(:@a => nil, :@b => true, :@c => false, :@d => 3, :@e => 'z', :@f => 7.9, :@g => 'a&b', :@h => :xyz, :@i => Time.now, :@j => (-1..7)), false) end end def test_complex dump_and_load(Bag.new(:@o => Bag.new(:@a => [2]), :@a => [1, {:b => 3, :a => [5], :c => Bag.new(:@x => 7)}]), false) end # Create an Object and an Array with the same Objects in them. Dump and load # and then change the ones in the loaded Object to verify that the ones in # the array change in the same way. They are the same objects so they should # change. Perform the operation on both the object before and the loaded so # the equal() method can be used. def test_circular if RUBY_VERSION.start_with?('1.8') # In 1.8.7 the eql? method behaves differently but the results are # correct when viewed by eye. assert(true) else a = [1] s = "a,b,c" h = { 1 => 2 } e = Ox::Element.new('Zoo') e[:cage] = 'bear' b = Bag.new(:@a => a, :@s => s, :@h => h, :@e => e) a << s a << h a << e a << b loaded = dump_and_load(b, false, true) # modify the string loaded.instance_variable_get(:@s).gsub!(',', '_') b.instance_variable_get(:@s).gsub!(',', '_') # modify hash loaded.instance_variable_get(:@h)[1] = 3 b.instance_variable_get(:@h)[1] = 3 # modify Element loaded.instance_variable_get(:@e)['pen'] = 'zebra' b.instance_variable_get(:@e)['pen'] = 'zebra' # pp loaded assert_equal(b, loaded) end end def test_raw raw = Ox::Element.new('raw') su = Ox::Element.new('sushi') su[:kind] = 'fish' raw << su ba = Ox::Element.new('basashi') ba[:kind] = 'animal' raw << ba dump_and_load(Bag.new(:@raw => raw), false) end def dump_and_load(obj, trace=false, circular=false) xml = Ox.dump(obj, :indent => $indent, :circular => circular) puts xml if trace loaded = Ox.load(xml, :mode => :object, :trace => (trace ? 2 : 0)) assert_equal(obj, loaded) loaded end def test_nameerror begin "x".foo rescue Exception => e xml = Ox.dump(e, :effort => :tolerant) o = Ox.load(xml, :mode => :object) xml2 = Ox.dump(o, :effort => :tolerant) assert_equal(xml, xml2) end end def test_mutex if defined?(Mutex) # Mutex can not be serialize but it should not raise an exception. xml = Ox.dump(Mutex.new, :indent => 2, :effort => :tolerant) assert_equal(%{ }, xml) xml = Ox.dump(Bag.new(:@x => Mutex.new), :indent => 2, :effort => :tolerant) assert_equal(%{ }, xml) else assert(true) end end def test_encoding if RUBY_VERSION.start_with?('1.8') assert(true) else s = 'ピーター' xml = Ox.dump(s, :with_xml => true, :encoding => 'UTF-8') #puts xml #puts xml.encoding.to_s assert_equal('UTF-8', xml.encoding.to_s) obj = Ox.load(xml, :mode => :object) assert_equal(s, obj) end end def test_instructions xml = Ox.dump("test", :with_instructions => true) #puts xml obj = Ox.load(xml) # should convert it to an object assert_equal("test", obj) end def test_IO f = File.open(__FILE__, "r") assert_raise(NotImplementedError) { xml = Ox.dump(f, :effort => :strict) } xml = Ox.dump(f, :effort => :tolerant) obj = Ox.load(xml, :mode => :object) # should convert it to an object assert_equal(nil, obj) end def locate_xml() %{ } end def test_locate_self doc = Ox.parse(locate_xml) nodes = doc.locate(nil) assert_equal(doc, nodes[0]) end def test_locate_top doc = Ox.parse(locate_xml) nodes = doc.locate('Family') assert_equal([doc.nodes[0]], nodes) end def test_locate_top_wild doc = Ox.parse(locate_xml) nodes = doc.locate('?') assert_equal([doc.nodes[0]], nodes) end def test_locate_child doc = Ox.parse(locate_xml) nodes = doc.locate('Family/?') assert_equal(['Pete'], nodes.map { |n| n.name }) nodes = doc.locate('Family/?/?') assert_equal(['Kid1', 'Kid2'], nodes.map { |n| n.name }) nodes = doc.locate('Family/Pete/?') assert_equal(['Kid1', 'Kid2'], nodes.map { |n| n.name }) nodes = doc.locate('Family/Makie/?') assert_equal([], nodes.map { |n| n.name }) end def test_locate_child_wild_wild doc = Ox.parse(locate_xml) nodes = doc.locate('Family/?/?') assert_equal(['Kid1', 'Kid2'], nodes.map { |n| n.name }) end def test_locate_child_wild doc = Ox.parse(locate_xml) nodes = doc.locate('Family/Pete/?') assert_equal(['Kid1', 'Kid2'], nodes.map { |n| n.name }) end def test_locate_child_wild_missing doc = Ox.parse(locate_xml) nodes = doc.locate('Family/Makie/?') assert_equal([], nodes.map { |n| n.name }) end def test_locate_attribute doc = Ox.parse(locate_xml) nodes = doc.locate('Family/@?') assert_equal(['false'], nodes) nodes = doc.locate('Family/@real') assert_equal(['false'], nodes) nodes = doc.locate('Family/Pete/@?') assert_equal(['57', 'male'], nodes.sort) nodes = doc.locate('Family/Pete/@age') assert_equal(['57'], nodes) nodes = doc.locate('Family/Makie/@?') assert_equal([], nodes) nodes = doc.locate('Family/Pete/?/@age') assert_equal(['31', '32'], nodes.sort) nodes = doc.locate('Family/*/@age') assert_equal(['31', '32', '57'], nodes.sort) nodes = doc.locate('*/@?') assert_equal(['31', '32', '57', 'false', 'male'], nodes.sort) assert_raise(::Ox::InvalidPath) { nodes = doc.locate('Family/@age/?') } assert_raise(::Ox::InvalidPath) { nodes = doc.locate('Family/?[/?') } end def test_locate_qual_index doc = Ox.parse(locate_xml) nodes = doc.locate('Family/Pete/?[0]') assert_equal(['Kid1'], nodes.map { |e| e.name } ) nodes = doc.locate('Family/Pete/?[1]') assert_equal(['Kid2'], nodes.map { |e| e.name } ) end def test_locate_qual_less doc = Ox.parse(locate_xml) nodes = doc.locate('Family/Pete/?[<1]') assert_equal(['Kid1'], nodes.map { |e| e.name } ) end def test_locate_qual_great doc = Ox.parse(locate_xml) nodes = doc.locate('Family/Pete/?[>0]') assert_equal(['Kid2'], nodes.map { |e| e.name } ) end def test_locate_qual_last doc = Ox.parse(locate_xml) nodes = doc.locate('Family/Pete/?[-1]') assert_equal(['Kid2'], nodes.map { |e| e.name } ) end def test_locate_qual_last_attr doc = Ox.parse(locate_xml) nodes = doc.locate('Family/Pete/?[-1]/@age') assert_equal(['31'], nodes ) end end class Bag def initialize(args) args.each do |k,v| self.instance_variable_set(k, v) end end def eql?(other) return false if (other.nil? or self.class != other.class) ova = other.instance_variables return false if ova.size != instance_variables.size instance_variables.each do |vid| return false if instance_variable_get(vid) != other.instance_variable_get(vid) end true end alias == eql? end