summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/rss/content.rb50
-rw-r--r--lib/rss/rexmlparser.rb47
-rw-r--r--lib/rss/trackback.rb301
-rw-r--r--sample/soap/calc/samplehttpd.conf2
-rw-r--r--sample/soap/exchange/samplehttpd.conf2
-rw-r--r--sample/soap/sampleStruct/samplehttpd.conf2
-rw-r--r--sample/wsdl/googleSearch/samplehttpd.conf2
-rw-r--r--test/ruby/marshaltestlib.rb494
8 files changed, 900 insertions, 0 deletions
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}</#{TRACKBACK_PREFIX}:ping>!
+ 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}</#{TRACKBACK_PREFIX}:about>!
+ 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