aboutsummaryrefslogtreecommitdiffhomepage
path: root/ruby/tests/well_known_types_test.rb
blob: f35f7b13def8cb404b0e35e5046775e61cd20ea5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/ruby

require 'test/unit'
require 'google/protobuf/well_known_types'

class TestWellKnownTypes < Test::Unit::TestCase
  def test_timestamp
    ts = Google::Protobuf::Timestamp.new

    assert_equal Time.at(0), ts.to_time

    ts.seconds = 12345
    assert_equal Time.at(12345), ts.to_time
    assert_equal 12345, ts.to_i

    # millisecond accuracy
    time = Time.at(123456, 654321)
    ts.from_time(time)
    assert_equal 123456, ts.seconds
    assert_equal 654321000, ts.nanos
    assert_equal time, ts.to_time

    # nanosecond accuracy
    time = Time.at(123456, Rational(654321321, 1000))
    ts.from_time(time)
    assert_equal 654321321, ts.nanos
    assert_equal time, ts.to_time
  end

  def test_duration
    duration = Google::Protobuf::Duration.new(seconds: 123, nanos: 456)
    assert_equal 123.000000456, duration.to_f
  end

  def test_struct
    struct = Google::Protobuf::Struct.new

    substruct = {
      "subkey" => 999,
      "subkey2" => false
    }

    sublist = ["abc", 123, {"deepkey" => "deepval"}]

    struct["number"] = 12345
    struct["boolean-true"] = true
    struct["boolean-false"] = false
    struct["null"] = nil
    struct["string"] = "abcdef"
    struct["substruct"] = substruct
    struct["sublist"] = sublist

    assert_equal 12345, struct["number"]
    assert_equal true, struct["boolean-true"]
    assert_equal false, struct["boolean-false"]
    assert_equal nil, struct["null"]
    assert_equal "abcdef", struct["string"]
    assert_equal(Google::Protobuf::Struct.from_hash(substruct),
                 struct["substruct"])
    assert_equal(Google::Protobuf::ListValue.from_a(sublist),
                 struct["sublist"])

    assert_equal true, struct.has_key?("null")
    assert_equal false, struct.has_key?("missing_key")

    should_equal = {
      "number" => 12345,
      "boolean-true" => true,
      "boolean-false" => false,
      "null" => nil,
      "string" => "abcdef",
      "substruct" => {
        "subkey" => 999,
        "subkey2" => false
      },
      "sublist" => ["abc", 123, {"deepkey" => "deepval"}]
    }

    list = struct["sublist"]
    list.is_a?(Google::Protobuf::ListValue)
    assert_equal "abc", list[0]
    assert_equal 123, list[1]
    assert_equal({"deepkey" => "deepval"}, list[2].to_h)

    # to_h returns a fully-flattened Ruby structure (Hash and Array).
    assert_equal(should_equal, struct.to_h)

    # Test that we can safely access a missing key
    assert_equal(nil, struct["missing_key"])

    # Test that we can assign Struct and ListValue directly.
    struct["substruct"] = Google::Protobuf::Struct.from_hash(substruct)
    struct["sublist"] = Google::Protobuf::ListValue.from_a(sublist)

    assert_equal(should_equal, struct.to_h)

    struct["sublist"] << nil
    should_equal["sublist"] << nil

    assert_equal(should_equal, struct.to_h)
    assert_equal(should_equal["sublist"].length, struct["sublist"].length)

    assert_raise Google::Protobuf::UnexpectedStructType do
      struct[123] = 5
    end

    assert_raise Google::Protobuf::UnexpectedStructType do
      struct[5] = Time.new
    end

    assert_raise Google::Protobuf::UnexpectedStructType do
      struct[5] = [Time.new]
    end

    assert_raise Google::Protobuf::UnexpectedStructType do
      struct[5] = {123 => 456}
    end

    assert_raise Google::Protobuf::UnexpectedStructType do
      struct = Google::Protobuf::Struct.new
      struct.fields["foo"] = Google::Protobuf::Value.new
      # Tries to return a Ruby value for a Value class whose type
      # hasn't been filled in.
      struct["foo"]
    end
  end

  def test_any
    ts = Google::Protobuf::Timestamp.new(seconds: 12345, nanos: 6789)

    any = Google::Protobuf::Any.new
    any.pack(ts)

    assert any.is(Google::Protobuf::Timestamp)
    assert_equal ts, any.unpack(Google::Protobuf::Timestamp)

    any = Google::Protobuf::Any.pack(ts)

    assert any.is(Google::Protobuf::Timestamp)
    assert_equal ts, any.unpack(Google::Protobuf::Timestamp)
  end
end