From 3b3aac95a6e39c94530e601df832b0de267445be Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Fri, 19 Feb 2021 13:36:05 -0800 Subject: [PATCH] [Ruby] Fix for truncating behavior when converting Float to Duration. --- ruby/ext/google/protobuf_c/message.c | 2 +- ruby/tests/common_tests.rb | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ruby/ext/google/protobuf_c/message.c b/ruby/ext/google/protobuf_c/message.c index f8661dfb2b4..259f5e666d6 100644 --- a/ruby/ext/google/protobuf_c/message.c +++ b/ruby/ext/google/protobuf_c/message.c @@ -1287,7 +1287,7 @@ const upb_msg* Message_GetUpbMessage(VALUE value, const upb_msgdef* m, if (!rb_obj_is_kind_of(value, rb_cNumeric)) goto badtype; sec.int64_val = NUM2LL(value); - nsec.int32_val = (NUM2DBL(value) - NUM2LL(value)) * 1000000000; + nsec.int32_val = round((NUM2DBL(value) - NUM2LL(value)) * 1000000000); upb_msg_set(msg, sec_f, sec, arena); upb_msg_set(msg, nsec_f, nsec, arena); return msg; diff --git a/ruby/tests/common_tests.rb b/ruby/tests/common_tests.rb index 589934b0e92..1957422fa93 100644 --- a/ruby/tests/common_tests.rb +++ b/ruby/tests/common_tests.rb @@ -1701,6 +1701,12 @@ def test_converts_duration m = proto_module::TimeMessage.new(duration: 1.1) assert_equal Google::Protobuf::Duration.new(seconds: 1, nanos: 100_000_000), m.duration + m = proto_module::TimeMessage.new(duration: 123.321) + assert_equal Google::Protobuf::Duration.new(seconds: 123, nanos: 321_000_000), m.duration + + m = proto_module::TimeMessage.new(duration: -123.321) + assert_equal Google::Protobuf::Duration.new(seconds: -123, nanos: -321_000_000), m.duration + assert_raise(Google::Protobuf::TypeError) { m.duration = '2' } assert_raise(Google::Protobuf::TypeError) { m.duration = proto_module::TimeMessage.new } end