summaryrefslogtreecommitdiff
path: root/test/psych
diff options
context:
space:
mode:
Diffstat (limited to 'test/psych')
-rw-r--r--test/psych/test_data.rb69
-rw-r--r--test/psych/test_object_references.rb5
-rw-r--r--test/psych/test_safe_load.rb32
-rw-r--r--test/psych/test_serialize_subclasses.rb18
-rw-r--r--test/psych/test_yaml.rb47
-rw-r--r--test/psych/visitors/test_yaml_tree.rb21
6 files changed, 191 insertions, 1 deletions
diff --git a/test/psych/test_data.rb b/test/psych/test_data.rb
new file mode 100644
index 0000000000..a67a037b9e
--- /dev/null
+++ b/test/psych/test_data.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+require_relative 'helper'
+
+class PsychDataWithIvar < Data.define(:foo)
+ attr_reader :bar
+ def initialize(**)
+ @bar = 'hello'
+ super
+ end
+end unless RUBY_VERSION < "3.2"
+
+module Psych
+ class TestData < TestCase
+ class SelfReferentialData < Data.define(:foo)
+ attr_accessor :ref
+ def initialize(foo:)
+ @ref = self
+ super
+ end
+ end unless RUBY_VERSION < "3.2"
+
+ def setup
+ omit "Data requires ruby >= 3.2" if RUBY_VERSION < "3.2"
+ end
+
+ # TODO: move to another test?
+ def test_dump_data
+ assert_equal <<~eoyml, Psych.dump(PsychDataWithIvar["bar"])
+ --- !ruby/data-with-ivars:PsychDataWithIvar
+ members:
+ foo: bar
+ ivars:
+ "@bar": hello
+ eoyml
+ end
+
+ def test_self_referential_data
+ circular = SelfReferentialData.new("foo")
+
+ loaded = Psych.unsafe_load(Psych.dump(circular))
+ assert_instance_of(SelfReferentialData, loaded.ref)
+
+ assert_equal(circular, loaded)
+ assert_same(loaded, loaded.ref)
+ end
+
+ def test_roundtrip
+ thing = PsychDataWithIvar.new("bar")
+ data = Psych.unsafe_load(Psych.dump(thing))
+
+ assert_equal "hello", data.bar
+ assert_equal "bar", data.foo
+ end
+
+ def test_load
+ obj = Psych.unsafe_load(<<~eoyml)
+ --- !ruby/data-with-ivars:PsychDataWithIvar
+ members:
+ foo: bar
+ ivars:
+ "@bar": hello
+ eoyml
+
+ assert_equal "hello", obj.bar
+ assert_equal "bar", obj.foo
+ end
+ end
+end
+
diff --git a/test/psych/test_object_references.rb b/test/psych/test_object_references.rb
index 86bb9034b9..0498d54eec 100644
--- a/test/psych/test_object_references.rb
+++ b/test/psych/test_object_references.rb
@@ -31,6 +31,11 @@ module Psych
assert_reference_trip Struct.new(:foo).new(1)
end
+ def test_data_has_references
+ omit "Data requires ruby >= 3.2" if RUBY_VERSION < "3.2"
+ assert_reference_trip Data.define(:foo).new(1)
+ end
+
def assert_reference_trip obj
yml = Psych.dump([obj, obj])
assert_match(/\*-?\d+/, yml)
diff --git a/test/psych/test_safe_load.rb b/test/psych/test_safe_load.rb
index a9ed737528..e6ca1e142b 100644
--- a/test/psych/test_safe_load.rb
+++ b/test/psych/test_safe_load.rb
@@ -114,6 +114,38 @@ module Psych
end
end
+ D = Data.define(:d) unless RUBY_VERSION < "3.2"
+
+ def test_data_depends_on_sym
+ omit "Data requires ruby >= 3.2" if RUBY_VERSION < "3.2"
+ assert_safe_cycle(D.new(nil), permitted_classes: [D, Symbol])
+ assert_raise(Psych::DisallowedClass) do
+ cycle D.new(nil), permitted_classes: [D]
+ end
+ end
+
+ def test_anon_data
+ omit "Data requires ruby >= 3.2" if RUBY_VERSION < "3.2"
+ assert Psych.safe_load(<<-eoyml, permitted_classes: [Data, Symbol])
+--- !ruby/data
+ foo: bar
+ eoyml
+
+ assert_raise(Psych::DisallowedClass) do
+ Psych.safe_load(<<-eoyml, permitted_classes: [Data])
+--- !ruby/data
+ foo: bar
+ eoyml
+ end
+
+ assert_raise(Psych::DisallowedClass) do
+ Psych.safe_load(<<-eoyml, permitted_classes: [Symbol])
+--- !ruby/data
+ foo: bar
+ eoyml
+ end
+ end
+
def test_safe_load_default_fallback
assert_nil Psych.safe_load("")
end
diff --git a/test/psych/test_serialize_subclasses.rb b/test/psych/test_serialize_subclasses.rb
index 344c79b3ef..640c331337 100644
--- a/test/psych/test_serialize_subclasses.rb
+++ b/test/psych/test_serialize_subclasses.rb
@@ -35,5 +35,23 @@ module Psych
so = StructSubclass.new('foo', [1,2,3])
assert_equal so, Psych.unsafe_load(Psych.dump(so))
end
+
+ class DataSubclass < Data.define(:foo)
+ def initialize(foo:)
+ @bar = "hello #{foo}"
+ super(foo: foo)
+ end
+
+ def == other
+ super(other) && @bar == other.instance_eval{ @bar }
+ end
+ end unless RUBY_VERSION < "3.2"
+
+ def test_data_subclass
+ omit "Data requires ruby >= 3.2" if RUBY_VERSION < "3.2"
+ so = DataSubclass.new('foo')
+ assert_equal so, Psych.unsafe_load(Psych.dump(so))
+ end
+
end
end
diff --git a/test/psych/test_yaml.rb b/test/psych/test_yaml.rb
index 897a7c8935..134c346c90 100644
--- a/test/psych/test_yaml.rb
+++ b/test/psych/test_yaml.rb
@@ -6,6 +6,7 @@ require_relative 'helper'
# [ruby-core:01946]
module Psych_Tests
StructTest = Struct::new( :c )
+ DataTest = Data.define( :c ) unless RUBY_VERSION < "3.2"
end
class Psych_Unit_Tests < Psych::TestCase
@@ -35,6 +36,10 @@ class Psych_Unit_Tests < Psych::TestCase
assert_cycle(Regexp.new("foo\nbar"))
end
+ def test_regexp_with_slash
+ assert_cycle(Regexp.new('/'))
+ end
+
# [ruby-core:34969]
def test_regexp_with_n
assert_cycle(Regexp.new('',Regexp::NOENCODING))
@@ -1037,7 +1042,6 @@ EOY
end
def test_ruby_struct
- Struct.send(:remove_const, :MyBookStruct) if Struct.const_defined?(:MyBookStruct)
# Ruby structures
book_struct = Struct::new( "MyBookStruct", :author, :title, :year, :isbn )
assert_to_yaml(
@@ -1069,6 +1073,47 @@ EOY
c: 123
EOY
+ ensure
+ Struct.__send__(:remove_const, :MyBookStruct) if book_struct
+ end
+
+ def test_ruby_data
+ omit "Data requires ruby >= 3.2" if RUBY_VERSION < "3.2"
+ # Ruby Data value objects
+ book_class = Data.define(:author, :title, :year, :isbn)
+ Object.const_set(:MyBookData, book_class)
+ assert_to_yaml(
+ [ book_class.new( "Yukihiro Matsumoto", "Ruby in a Nutshell", 2002, "0-596-00214-9" ),
+ book_class.new( [ 'Dave Thomas', 'Andy Hunt' ], "The Pickaxe", 2002,
+ book_class.new( "This should be the ISBN", "but I have more data here", 2002, "None" )
+ )
+ ], <<EOY
+- !ruby/data:MyBookData
+ author: Yukihiro Matsumoto
+ title: Ruby in a Nutshell
+ year: 2002
+ isbn: 0-596-00214-9
+- !ruby/data:MyBookData
+ author:
+ - Dave Thomas
+ - Andy Hunt
+ title: The Pickaxe
+ year: 2002
+ isbn: !ruby/data:MyBookData
+ author: This should be the ISBN
+ title: but I have more data here
+ year: 2002
+ isbn: None
+EOY
+ )
+
+ assert_to_yaml( Psych_Tests::DataTest.new( 123 ), <<EOY )
+--- !ruby/data:Psych_Tests::DataTest
+c: 123
+EOY
+
+ ensure
+ Object.__send__(:remove_const, :MyBookData) if book_class
end
def test_ruby_rational
diff --git a/test/psych/visitors/test_yaml_tree.rb b/test/psych/visitors/test_yaml_tree.rb
index 01e685134a..bd3919f83d 100644
--- a/test/psych/visitors/test_yaml_tree.rb
+++ b/test/psych/visitors/test_yaml_tree.rb
@@ -73,6 +73,27 @@ module Psych
assert_equal s.method, obj.method
end
+ D = Data.define(:foo) unless RUBY_VERSION < "3.2"
+
+ def test_data
+ omit "Data requires ruby >= 3.2" if RUBY_VERSION < "3.2"
+ assert_cycle D.new('bar')
+ end
+
+ def test_data_anon
+ omit "Data requires ruby >= 3.2" if RUBY_VERSION < "3.2"
+ d = Data.define(:foo).new('bar')
+ obj = Psych.unsafe_load(Psych.dump(d))
+ assert_equal d.foo, obj.foo
+ end
+
+ def test_data_override_method
+ omit "Data requires ruby >= 3.2" if RUBY_VERSION < "3.2"
+ d = Data.define(:method).new('override')
+ obj = Psych.unsafe_load(Psych.dump(d))
+ assert_equal d.method, obj.method
+ end
+
def test_exception
ex = Exception.new 'foo'
loaded = Psych.unsafe_load(Psych.dump(ex))