summaryrefslogtreecommitdiff
path: root/test/ruby/test_data.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/ruby/test_data.rb')
-rw-r--r--test/ruby/test_data.rb111
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