Bladeren bron

[Ruby] Fix for truncating behavior when converting Float to Duration.

Joshua Haberman 4 jaren geleden
bovenliggende
commit
3b3aac95a6
2 gewijzigde bestanden met toevoegingen van 7 en 1 verwijderingen
  1. 1 1
      ruby/ext/google/protobuf_c/message.c
  2. 6 0
      ruby/tests/common_tests.rb

+ 1 - 1
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;
         if (!rb_obj_is_kind_of(value, rb_cNumeric)) goto badtype;
 
 
         sec.int64_val = NUM2LL(value);
         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, sec_f, sec, arena);
         upb_msg_set(msg, nsec_f, nsec, arena);
         upb_msg_set(msg, nsec_f, nsec, arena);
         return msg;
         return msg;

+ 6 - 0
ruby/tests/common_tests.rb

@@ -1701,6 +1701,12 @@ module CommonTests
     m = proto_module::TimeMessage.new(duration: 1.1)
     m = proto_module::TimeMessage.new(duration: 1.1)
     assert_equal Google::Protobuf::Duration.new(seconds: 1, nanos: 100_000_000), m.duration
     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 = '2' }
     assert_raise(Google::Protobuf::TypeError) { m.duration = proto_module::TimeMessage.new }
     assert_raise(Google::Protobuf::TypeError) { m.duration = proto_module::TimeMessage.new }
   end
   end