diff options
Diffstat (limited to 'test/ruby/test_data.rb')
-rw-r--r-- | test/ruby/test_data.rb | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/test/ruby/test_data.rb b/test/ruby/test_data.rb index f63b0236fb..bb38f8ec91 100644 --- a/test/ruby/test_data.rb +++ b/test/ruby/test_data.rb @@ -62,6 +62,7 @@ class TestData < Test::Unit::TestCase assert_equal(1, test.foo) assert_equal(2, test.bar) assert_equal(test, klass.new(1, 2)) + assert_predicate(test, :frozen?) # Keywords test_kw = klass.new(foo: 1, bar: 2) @@ -96,6 +97,7 @@ class TestData < Test::Unit::TestCase # Missing arguments can be fixed in initialize assert_equal([[], {foo: 1}], klass.new(foo: 1).passed) + assert_equal([[], {foo: 42}], klass.new(42).passed) # Extra keyword arguments can be dropped in initialize assert_equal([[], {foo: 1, bar: 2, baz: 3}], klass.new(foo: 1, bar: 2, baz: 3).passed) @@ -115,14 +117,31 @@ class TestData < Test::Unit::TestCase assert_equal({foo: 1, bar: 2}, test.to_h) assert_equal({"foo"=>"1", "bar"=>"2"}, test.to_h { [_1.to_s, _2.to_s] }) + assert_equal([1, 2], test.deconstruct) assert_equal({foo: 1, bar: 2}, test.deconstruct_keys(nil)) assert_equal({foo: 1}, test.deconstruct_keys(%i[foo])) assert_equal({foo: 1}, test.deconstruct_keys(%i[foo baz])) + assert_equal({}, test.deconstruct_keys(%i[foo bar baz])) assert_raise(TypeError) { test.deconstruct_keys(0) } assert_kind_of(Integer, test.hash) end + def test_hash + measure = Data.define(:amount, :unit) + + assert_equal(measure[1, 'km'].hash, measure[1, 'km'].hash) + assert_not_equal(measure[1, 'km'].hash, measure[10, 'km'].hash) + assert_not_equal(measure[1, 'km'].hash, measure[1, 'm'].hash) + assert_not_equal(measure[1, 'km'].hash, measure[1.0, 'km'].hash) + + # Structurally similar data class, but shouldn't be considered + # the same hash key + measurement = Data.define(:amount, :unit) + + assert_not_equal(measure[1, 'km'].hash, measurement[1, 'km'].hash) + end + def test_inspect klass = Data.define(:a) o = klass.new(1) @@ -157,6 +176,81 @@ class TestData < Test::Unit::TestCase assert_not_operator(o1, :eql?, o3) end + def test_with + klass = Data.define(:foo, :bar) + source = klass.new(foo: 1, bar: 2) + + # Simple + test = source.with + assert_equal(source.object_id, test.object_id) + + # Changes + test = source.with(foo: 10) + + assert_equal(1, source.foo) + assert_equal(2, source.bar) + assert_equal(source, klass.new(foo: 1, bar: 2)) + + assert_equal(10, test.foo) + assert_equal(2, test.bar) + assert_equal(test, klass.new(foo: 10, bar: 2)) + + test = source.with(foo: 10, bar: 20) + + assert_equal(1, source.foo) + assert_equal(2, source.bar) + assert_equal(source, klass.new(foo: 1, bar: 2)) + + assert_equal(10, test.foo) + assert_equal(20, test.bar) + assert_equal(test, klass.new(foo: 10, bar: 20)) + + # Keyword splat + changes = { foo: 10, bar: 20 } + test = source.with(**changes) + + assert_equal(1, source.foo) + assert_equal(2, source.bar) + assert_equal(source, klass.new(foo: 1, bar: 2)) + + assert_equal(10, test.foo) + assert_equal(20, test.bar) + assert_equal(test, klass.new(foo: 10, bar: 20)) + + # Wrong protocol + assert_raise_with_message(ArgumentError, "wrong number of arguments (given 1, expected 0)") do + source.with(10) + end + assert_raise_with_message(ArgumentError, "unknown keywords: :baz, :quux") do + source.with(foo: 1, bar: 2, baz: 3, quux: 4) + end + assert_raise_with_message(ArgumentError, "wrong number of arguments (given 1, expected 0)") do + source.with(1, bar: 2) + end + assert_raise_with_message(ArgumentError, "wrong number of arguments (given 2, expected 0)") do + source.with(1, 2) + end + assert_raise_with_message(ArgumentError, "wrong number of arguments (given 1, expected 0)") do + source.with({ bar: 2 }) + end + end + + def test_with_initialize + oddclass = Data.define(:odd) do + def initialize(odd:) + raise ArgumentError, "Not odd" unless odd.odd? + super(odd: odd) + end + end + assert_raise_with_message(ArgumentError, "Not odd") { + oddclass.new(odd: 0) + } + odd = oddclass.new(odd: 1) + assert_raise_with_message(ArgumentError, "Not odd") { + odd.with(odd: 2) + } + end + def test_memberless klass = Data.define @@ -169,4 +263,21 @@ class TestData < Test::Unit::TestCase assert_equal([], test.members) assert_equal({}, test.to_h) end + + def test_dup + klass = Data.define(:foo, :bar) + test = klass.new(foo: 1, bar: 2) + assert_equal(klass.new(foo: 1, bar: 2), test.dup) + assert_predicate(test.dup, :frozen?) + end + + Klass = Data.define(:foo, :bar) + + def test_marshal + test = Klass.new(foo: 1, bar: 2) + loaded = Marshal.load(Marshal.dump(test)) + assert_equal(test, loaded) + assert_not_same(test, loaded) + assert_predicate(loaded, :frozen?) + end end |