From 3e88efe3df5daf41ed98b4630ece94be009e54ec Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> Date: Tue, 17 Feb 2004 14:51:40 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create branch 'ruby_1_8'. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@5754 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/rss/content.rb | 50 +++ lib/rss/rexmlparser.rb | 47 ++ lib/rss/trackback.rb | 301 +++++++++++++ sample/soap/calc/samplehttpd.conf | 2 + sample/soap/exchange/samplehttpd.conf | 2 + sample/soap/sampleStruct/samplehttpd.conf | 2 + sample/wsdl/googleSearch/samplehttpd.conf | 2 + test/ruby/marshaltestlib.rb | 494 ++++++++++++++++++++++ 8 files changed, 900 insertions(+) create mode 100644 lib/rss/content.rb create mode 100644 lib/rss/rexmlparser.rb create mode 100644 lib/rss/trackback.rb create mode 100644 sample/soap/calc/samplehttpd.conf create mode 100644 sample/soap/exchange/samplehttpd.conf create mode 100644 sample/soap/sampleStruct/samplehttpd.conf create mode 100644 sample/wsdl/googleSearch/samplehttpd.conf create mode 100644 test/ruby/marshaltestlib.rb diff --git a/lib/rss/content.rb b/lib/rss/content.rb new file mode 100644 index 0000000000..fae0b687be --- /dev/null +++ b/lib/rss/content.rb @@ -0,0 +1,50 @@ +require "rss/1.0" + +module RSS + + CONTENT_PREFIX = 'content' + CONTENT_URI = "http://purl.org/rss/1.0/modules/content/" + + RDF.install_ns(CONTENT_PREFIX, CONTENT_URI) + + module ContentModel + + extend BaseModel + + ELEMENTS = [] + + def self.included(mod) + mod.module_eval(<<-EOC) + %w(encoded).each do |x| + install_text_element("\#{CONTENT_PREFIX}_\#{x}") + end + EOC + end + + def content_validate(tags) + counter = {} + ELEMENTS.each do |x| + counter[x] = 0 + end + + tags.each do |tag| + key = "#{CONTENT_PREFIX}_#{tag}" + raise UnknownTagError.new(tag, CONTENT_URI) unless counter.has_key?(key) + counter[key] += 1 + raise TooMuchTagError.new(tag, tag_name) if counter[key] > 1 + end + end + + end + + class RDF + class Item; include ContentModel; end + end + + prefix_size = CONTENT_PREFIX.size + 1 + ContentModel::ELEMENTS.uniq! + ContentModel::ELEMENTS.each do |x| + BaseListener.install_get_text_element(x[prefix_size..-1], CONTENT_URI, "#{x}=") + end + +end diff --git a/lib/rss/rexmlparser.rb b/lib/rss/rexmlparser.rb new file mode 100644 index 0000000000..13ab0e277b --- /dev/null +++ b/lib/rss/rexmlparser.rb @@ -0,0 +1,47 @@ +require "rexml/document" +require "rexml/streamlistener" + +/\A(\d+)\.(\d+)(?:\.\d+)+\z/ =~ REXML::Version +if ([$1.to_i, $2.to_i] <=> [2, 5]) < 0 + raise LoadError, "needs REXML 2.5 or later (#{REXML::Version})" +end + +module RSS + + class REXMLParser < BaseParser + + private + + def listener + REXMLListener + end + + def _parse + begin + REXML::Document.parse_stream(@rss, @listener) + rescue RuntimeError => e + raise NotWellFormedError.new{e.message} + rescue REXML::ParseException => e + context = e.context + line = context[0] if context + raise NotWellFormedError.new(line){e.message} + end + end + + end + + class REXMLListener < BaseListener + + include REXML::StreamListener + include ListenerMixin + + def xmldecl(version, encoding, standalone) + super + # Encoding is converted to UTF-8 when REXML parse XML. + @encoding = 'UTF-8' + end + + alias_method(:cdata, :text) + end + +end diff --git a/lib/rss/trackback.rb b/lib/rss/trackback.rb new file mode 100644 index 0000000000..493e742453 --- /dev/null +++ b/lib/rss/trackback.rb @@ -0,0 +1,301 @@ +require 'rss/1.0' +require 'rss/2.0' + +module RSS + + TRACKBACK_PREFIX = 'trackback' + TRACKBACK_URI = 'http://madskills.com/public/xml/rss/module/trackback/' + + RDF.install_ns(TRACKBACK_PREFIX, TRACKBACK_URI) + Rss.install_ns(TRACKBACK_PREFIX, TRACKBACK_URI) + + module BaseTrackBackModel + def trackback_validate(tags) + raise unless @do_validate + counter = {} + %w(ping about).each do |x| + counter["#{TRACKBACK_PREFIX}_#{x}"] = 0 + end + + tags.each do |tag| + key = "#{TRACKBACK_PREFIX}_#{tag}" + raise UnknownTagError.new(tag, TRACKBACK_URI) unless counter.has_key?(key) + counter[key] += 1 + if tag != "about" and counter[key] > 1 + raise TooMuchTagError.new(tag, tag_name) + end + end + + if counter["#{TRACKBACK_PREFIX}_ping"].zero? and + counter["#{TRACKBACK_PREFIX}_about"].nonzero? + raise MissingTagError.new("#{TRACKBACK_PREFIX}:ping", tag_name) + end + end + end + + module TrackBackModel10 + extend BaseModel + include BaseTrackBackModel + + def self.append_features(klass) + super + + unless klass.class == Module + %w(ping).each do |x| + klass.install_have_child_element("#{TRACKBACK_PREFIX}_#{x}") + end + + %w(about).each do |x| + klass.install_have_children_element("#{TRACKBACK_PREFIX}_#{x}") + end + end + end + + class Ping < Element + include RSS10 + + class << self + + def required_prefix + TRACKBACK_PREFIX + end + + def required_uri + TRACKBACK_URI + end + + end + + [ + ["resource", ::RSS::RDF::URI, true] + ].each do |name, uri, required| + install_get_attribute(name, uri, required) + end + + def initialize(resource=nil) + super() + @resource = resource + end + + def to_s(convert=true) + if @resource + rv = %Q!<#{TRACKBACK_PREFIX}:ping #{::RSS::RDF::PREFIX}:resource="#{h @resource}"/>! + rv = @converter.convert(rv) if convert and @converter + rv + else + '' + end + end + + private + def _attrs + [ + ["resource", true], + ] + end + + end + + class About < Element + include RSS10 + + class << self + + def required_prefix + TRACKBACK_PREFIX + end + + def required_uri + TRACKBACK_URI + end + + end + + [ + ["resource", ::RSS::RDF::URI, true] + ].each do |name, uri, required| + install_get_attribute(name, uri, required) + end + + def initialize(resource=nil) + super() + @resource = resource + end + + def to_s(convert=true) + if @resource + rv = %Q!<#{TRACKBACK_PREFIX}:about #{::RSS::RDF::PREFIX}:resource="#{h @resource}"/>! + rv = @converter.convert(rv) if convert and @converter + rv + else + '' + end + end + + private + def _attrs + [ + ["resource", true], + ] + end + + end + end + + module TrackBackModel20 + include BaseTrackBackModel + extend BaseModel + + def self.append_features(klass) + super + + unless klass.class == Module + %w(ping).each do |x| + var_name = "#{TRACKBACK_PREFIX}_#{x}" + klass.install_have_child_element(var_name) + klass.module_eval(<<-EOC) + alias _#{var_name} #{var_name} + def #{var_name} + @#{var_name} and @#{var_name}.content + end + + alias _#{var_name}= #{var_name}= + def #{var_name}=(content) + @#{var_name} = new_with_content_if_need(#{x.capitalize}, content) + end + EOC + end + + [%w(about s)].each do |x, postfix| + var_name = "#{TRACKBACK_PREFIX}_#{x}" + klass.install_have_children_element(var_name) + klass.module_eval(<<-EOC) + alias _#{var_name}#{postfix} #{var_name}#{postfix} + def #{var_name}#{postfix} + @#{var_name}.collect {|x| x.content} + end + + alias _#{var_name} #{var_name} + def #{var_name}(*args) + if args.empty? + @#{var_name}.first and @#{var_name}.first.content + else + ret = @#{var_name}.send("[]", *args) + if ret.is_a?(Array) + ret.collect {|x| x.content} + else + ret.content + end + end + end + + alias _#{var_name}= #{var_name}= + alias _set_#{var_name} set_#{var_name} + def #{var_name}=(*args) + if args.size == 1 + item = new_with_content_if_need(#{x.capitalize}, args[0]) + @#{var_name}.push(item) + else + new_val = args.last + if new_val.is_a?(Array) + new_val = new_value.collect do |val| + new_with_content_if_need(#{x.capitalize}, val) + end + else + new_val = new_with_content_if_need(#{x.capitalize}, new_val) + end + @#{var_name}.send("[]=", *(args[0..-2] + [new_val])) + end + end + alias set_#{var_name} #{var_name}= + EOC + end + end + + private + def new_with_content(klass, content) + obj = klass.new + obj.content = content + obj + end + + def new_with_content_if_need(klass, content) + if content.is_a?(klass) + content + else + new_with_content(klass, content) + end + end + + end + + class Ping < Element + include RSS09 + + content_setup + + class << self + + def required_prefix + TRACKBACK_PREFIX + end + + def required_uri + TRACKBACK_URI + end + + end + + def to_s(convert=true) + if @content + rv = %Q!<#{TRACKBACK_PREFIX}:ping>#{h @content}! + rv = @converter.convert(rv) if convert and @converter + rv + else + '' + end + end + + end + + class About < Element + include RSS09 + + content_setup + + class << self + + def required_prefix + TRACKBACK_PREFIX + end + + def required_uri + TRACKBACK_URI + end + + end + + def to_s(convert=true) + if @content + rv = %Q!<#{TRACKBACK_PREFIX}:about>#{h @content}! + rv = @converter.convert(rv) if convert and @converter + rv + else + '' + end + end + + end + end + + class RDF + class Item; include TrackBackModel10; end + end + + class Rss + class Channel + class Item; include TrackBackModel20; end + end + end + +end diff --git a/sample/soap/calc/samplehttpd.conf b/sample/soap/calc/samplehttpd.conf new file mode 100644 index 0000000000..85e9995021 --- /dev/null +++ b/sample/soap/calc/samplehttpd.conf @@ -0,0 +1,2 @@ +docroot = . +port = 8808 diff --git a/sample/soap/exchange/samplehttpd.conf b/sample/soap/exchange/samplehttpd.conf new file mode 100644 index 0000000000..85e9995021 --- /dev/null +++ b/sample/soap/exchange/samplehttpd.conf @@ -0,0 +1,2 @@ +docroot = . +port = 8808 diff --git a/sample/soap/sampleStruct/samplehttpd.conf b/sample/soap/sampleStruct/samplehttpd.conf new file mode 100644 index 0000000000..85e9995021 --- /dev/null +++ b/sample/soap/sampleStruct/samplehttpd.conf @@ -0,0 +1,2 @@ +docroot = . +port = 8808 diff --git a/sample/wsdl/googleSearch/samplehttpd.conf b/sample/wsdl/googleSearch/samplehttpd.conf new file mode 100644 index 0000000000..85e9995021 --- /dev/null +++ b/sample/wsdl/googleSearch/samplehttpd.conf @@ -0,0 +1,2 @@ +docroot = . +port = 8808 diff --git a/test/ruby/marshaltestlib.rb b/test/ruby/marshaltestlib.rb new file mode 100644 index 0000000000..891f43b1f7 --- /dev/null +++ b/test/ruby/marshaltestlib.rb @@ -0,0 +1,494 @@ +module MarshalTestLib + # include this module to a Test::Unit::TestCase and definde encode(o) and + # decode(s) methods. e.g. + # + # def encode(o) + # SOAPMarshal.dump(o) + # end + # + # def decode(s) + # SOAPMarshal.load(s) + # end + + NegativeZero = (-1.0 / (1.0 / 0.0)) + + module Mod1; end + module Mod2; end + + def marshaltest(o1) + str = encode(o1) + print str, "\n" if $DEBUG + o2 = decode(str) + o2 + end + + def marshal_equal(o1, msg = nil) + msg = msg ? msg + "(#{ caller[0] })" : caller[0] + o2 = marshaltest(o1) + assert_equal(o1.class, o2.class, msg) + iv1 = o1.instance_variables.sort + iv2 = o2.instance_variables.sort + assert_equal(iv1, iv2) + val1 = iv1.map {|var| o1.instance_eval {eval var}} + val2 = iv1.map {|var| o2.instance_eval {eval var}} + assert_equal(val1, val2, msg) + if block_given? + assert_equal(yield(o1), yield(o2), msg) + else + assert_equal(o1, o2, msg) + end + end + + class MyObject; def initialize(v) @v = v end; attr_reader :v; end + def test_object + o1 = Object.new + o1.instance_eval { @iv = 1 } + marshal_equal(o1) {|o| o.instance_eval { @iv }} + end + + def test_object_subclass + marshal_equal(MyObject.new(2)) {|o| o.v} + end + + def test_object_extend + o1 = Object.new + o1.extend(Mod1) + marshal_equal(o1) { |o| + (class << self; self; end).ancestors + } + o1.extend(Mod2) + marshal_equal(o1) { |o| + (class << self; self; end).ancestors + } + end + + def test_object_subclass_extend + o1 = MyObject.new(2) + o1.extend(Mod1) + marshal_equal(o1) { |o| + (class << self; self; end).ancestors + } + o1.extend(Mod2) + marshal_equal(o1) { |o| + (class << self; self; end).ancestors + } + end + + class MyArray < Array + def initialize(v, *args) + super(args) + @v = v + end + end + def test_array + marshal_equal(5) + marshal_equal([1,2,3]) + end + + def test_array_subclass + marshal_equal(MyArray.new(0, 1, 2, 3)) + end + + def test_array_ivar + o1 = Array.new + o1.instance_eval { @iv = 1 } + marshal_equal(o1) {|o| o.instance_eval { @iv }} + end + + class MyException < Exception; def initialize(v, *args) super(*args); @v = v; end; attr_reader :v; end + def test_exception + marshal_equal(Exception.new('foo')) {|o| o.message} + marshal_equal(assert_raise(NoMethodError) {no_such_method()}) {|o| o.message} + end + + def test_exception_subclass + marshal_equal(MyException.new(20, "bar")) {|o| [o.message, o.v]} + end + + def test_false + marshal_equal(false) + end + + class MyHash < Hash; def initialize(v, *args) super(*args); @v = v; end end + def test_hash + marshal_equal({1=>2, 3=>4}) + end + + def test_hash_default + h = Hash.new(:default) + h[5] = 6 + marshal_equal(h) + end + + def test_hash_subclass + h = MyHash.new(7, 8) + h[4] = 5 + marshal_equal(h) + end + + def test_hash_default_proc + h = Hash.new {} + assert_raises(TypeError) { marshaltest(h) } + end + + def test_hash_ivar + o1 = Hash.new + o1.instance_eval { @iv = 1 } + marshal_equal(o1) {|o| o.instance_eval { @iv }} + end + + def test_hash_extend + o1 = Hash.new + o1.extend(Mod1) + marshal_equal(o1) { |o| + (class << self; self; end).ancestors + } + o1.extend(Mod2) + marshal_equal(o1) { |o| + (class << self; self; end).ancestors + } + end + + def test_hash_subclass_extend + o1 = MyHash.new(2) + o1.extend(Mod1) + marshal_equal(o1) { |o| + (class << self; self; end).ancestors + } + o1.extend(Mod2) + marshal_equal(o1) { |o| + (class << self; self; end).ancestors + } + end + + def test_bignum + marshal_equal(-0x4000_0000_0000_0001) + marshal_equal(-0x4000_0001) + marshal_equal(0x4000_0000) + marshal_equal(0x4000_0000_0000_0000) + end + + def test_fixnum + marshal_equal(-0x4000_0000) + marshal_equal(-0x3fff_ffff) + marshal_equal(-1) + marshal_equal(0) + marshal_equal(1) + marshal_equal(0x3fff_ffff) + end + + def test_fixnum_ivar + o1 = 1 + o1.instance_eval { @iv = 2 } + marshal_equal(o1) {|o| o.instance_eval { @iv }} + ensure + 1.instance_eval { remove_instance_variable("@iv") } + end + + def test_fixnum_ivar_self + o1 = 1 + o1.instance_eval { @iv = 1 } + marshal_equal(o1) {|o| o.instance_eval { @iv }} + ensure + 1.instance_eval { remove_instance_variable("@iv") } + end + + def test_float + marshal_equal(-1.0) + marshal_equal(0.0) + marshal_equal(1.0) + end + + def test_float_inf_nan + marshal_equal(1.0/0.0) + marshal_equal(-1.0/0.0) + marshal_equal(0.0/0.0) {|o| o.nan?} + marshal_equal(NegativeZero) {|o| 1.0/o} + end + + def test_float_ivar + o1 = 1.23 + o1.instance_eval { @iv = 1 } + marshal_equal(o1) {|o| o.instance_eval { @iv }} + end + + def test_float_ivar_self + o1 = 5.5 + o1.instance_eval { @iv = o1 } + marshal_equal(o1) {|o| o.instance_eval { @iv }} + end + + def test_float_extend + o1 = 0.0/0.0 + o1.extend(Mod1) + marshal_equal(o1) { |o| + (class << self; self; end).ancestors + } + o1.extend(Mod2) + marshal_equal(o1) { |o| + (class << self; self; end).ancestors + } + end + + class MyRange < Range; def initialize(v, *args) super(*args); @v = v; end end + def test_range + marshal_equal(1..2) + marshal_equal(1...3) + end + + def test_range_subclass + marshal_equal(MyRange.new(4,5,8, false)) + end + + class MyRegexp < Regexp; def initialize(v, *args) super(*args); @v = v; end end + def test_regexp + marshal_equal(/a/) + marshal_equal(/A/i) + marshal_equal(/A/mx) + end + + def test_regexp_subclass + marshal_equal(MyRegexp.new(10, "a")) + end + + class MyString < String; def initialize(v, *args) super(*args); @v = v; end end + def test_string + marshal_equal("abc") + end + + def test_string_ivar + o1 = "" + o1.instance_eval { @iv = 1 } + marshal_equal(o1) {|o| o.instance_eval { @iv }} + end + + def test_string_subclass + marshal_equal(MyString.new(10, "a")) + end + + def test_string_subclass_cycle + str = MyString.new(10, "b") + str.instance_eval { @v = str } + marshal_equal(str) { |o| + assert_equal(o.__id__, o.instance_eval { @v }.__id__) + o.instance_eval { @v } + } + end + + def test_string_subclass_extend + o = "abc" + o.extend(Mod1) + str = MyString.new(o, "c") + marshal_equal(str) { |o| + assert(o.instance_eval { @v }).kind_of?(Mod1) + } + end + + MyStruct = Struct.new("MyStruct", :a, :b) + if RUBY_VERSION < "1.8.0" + # Struct#== is not defined in ruby/1.6 + class MyStruct + def ==(rhs) + return true if __id__ == rhs.__id__ + return false unless rhs.is_a?(::Struct) + return false if self.class != rhs.class + members.each do |member| + return false if self.__send__(member) != rhs.__send__(member) + end + return true + end + end + end + class MySubStruct < MyStruct; def initialize(v, *args) super(*args); @v = v; end end + def test_struct + marshal_equal(MyStruct.new(1,2)) + end + + def test_struct_subclass + if RUBY_VERSION < "1.8.0" + # Substruct instance cannot be dumped in ruby/1.6 + # ::Marshal.dump(MySubStruct.new(10, 1, 2)) #=> uninitialized struct + return false + end + marshal_equal(MySubStruct.new(10,1,2)) + end + + def test_struct_ivar + o1 = MyStruct.new + o1.instance_eval { @iv = 1 } + marshal_equal(o1) {|o| o.instance_eval { @iv }} + end + + def test_struct_subclass_extend + o1 = MyStruct.new + o1.extend(Mod1) + marshal_equal(o1) { |o| + (class << self; self; end).ancestors + } + o1.extend(Mod2) + marshal_equal(o1) { |o| + (class << self; self; end).ancestors + } + end + + def test_symbol + marshal_equal(:a) + marshal_equal(:a?) + marshal_equal(:a!) + marshal_equal(:a=) + marshal_equal(:|) + marshal_equal(:^) + marshal_equal(:&) + marshal_equal(:<=>) + marshal_equal(:==) + marshal_equal(:===) + marshal_equal(:=~) + marshal_equal(:>) + marshal_equal(:>=) + marshal_equal(:<) + marshal_equal(:<=) + marshal_equal(:<<) + marshal_equal(:>>) + marshal_equal(:+) + marshal_equal(:-) + marshal_equal(:*) + marshal_equal(:/) + marshal_equal(:%) + marshal_equal(:**) + marshal_equal(:~) + marshal_equal(:+@) + marshal_equal(:-@) + marshal_equal(:[]) + marshal_equal(:[]=) + marshal_equal(:`) #` + marshal_equal("a b".intern) + end + + class MyTime < Time; def initialize(v, *args) super(*args); @v = v; end end + def test_time + # once there was a bug caused by usec overflow. try a little harder. + 10.times do + t = Time.now + marshal_equal(t, t.usec.to_s) + end + end + + def test_time_subclass + marshal_equal(MyTime.new(10)) + end + + def test_time_ivar + o1 = Time.now + o1.instance_eval { @iv = 1 } + marshal_equal(o1) {|o| o.instance_eval { @iv }} + end + + def test_true + marshal_equal(true) + end + + def test_nil + marshal_equal(nil) + end + + def test_share + o = [:share] + o1 = [o, o] + o2 = marshaltest(o1) + assert_same(o2.first, o2.last) + end + + class CyclicRange < Range + def <=>(other); true; end + end + def test_range_cyclic + return unless CyclicRange.respond_to?(:allocate) # test for 1.8 + o1 = CyclicRange.allocate + o1.instance_eval { initialize(o1, o1) } + o2 = marshaltest(o1) + assert_same(o2, o2.begin) + assert_same(o2, o2.end) + end + + def test_singleton + o = Object.new + def o.m() end + assert_raises(TypeError) { marshaltest(o) } + o = Object.new + c = class << o + @v = 1 + class C; self; end + end + assert_raises(TypeError) { marshaltest(o) } + assert_raises(TypeError) { marshaltest(c) } + assert_raises(TypeError) { marshaltest(ARGF) } + assert_raises(TypeError) { marshaltest(ENV) } + end + + def test_extend + o = Object.new + o.extend Mod1 + marshal_equal(o) { |obj| obj.kind_of? Mod1 } + o = Object.new + o.extend Mod1 + o.extend Mod2 + marshal_equal(o) {|obj| class << obj; ancestors end} + o = Object.new + o.extend Module.new + assert_raises(TypeError) { marshaltest(o) } + end + + def test_extend_string + o = "" + o.extend Mod1 + marshal_equal(o) { |obj| obj.kind_of? Mod1 } + o = "" + o.extend Mod1 + o.extend Mod2 + marshal_equal(o) {|obj| class << obj; ancestors end} + o = "" + o.extend Module.new + assert_raises(TypeError) { marshaltest(o) } + end + + def test_anonymous + c = Class.new + assert_raises(TypeError) { marshaltest(c) } + o = c.new + assert_raises(TypeError) { marshaltest(o) } + m = Module.new + assert_raises(TypeError) { marshaltest(m) } + end + + def test_string_empty + marshal_equal("") + end + + def test_string_crlf + marshal_equal("\r\n") + end + + def test_string_escape + marshal_equal("\0<;;>\1;;") + end + + MyStruct2 = Struct.new(:a, :b) + if RUBY_VERSION < "1.8.0" + # Struct#== is not defined in ruby/1.6 + class MyStruct2 + def ==(rhs) + return true if __id__ == rhs.__id__ + return false unless rhs.is_a?(::Struct) + return false if self.class != rhs.class + members.each do |member| + return false if self.__send__(member) != rhs.__send__(member) + end + return true + end + end + end + def test_struct_toplevel + o = MyStruct2.new(1,2) + marshal_equal(o) + end +end