protip 0.20.7 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/protip.rb +10 -0
- data/lib/protip/{wrapper.rb → decorator.rb} +98 -82
- data/lib/protip/extensions.rb +0 -1
- data/lib/protip/resource.rb +56 -32
- data/lib/protip/resource/extra_methods.rb +5 -3
- data/lib/protip/tasks/compile.rake +2 -2
- data/lib/protip/transformer.rb +14 -0
- data/lib/protip/transformers/abstract_transformer.rb +11 -0
- data/lib/protip/transformers/active_support/time_with_zone_transformer.rb +35 -0
- data/lib/protip/transformers/decorating_transformer.rb +33 -0
- data/lib/protip/transformers/default_transformer.rb +22 -0
- data/lib/protip/transformers/delegating_transformer.rb +44 -0
- data/lib/protip/transformers/deprecated_transformer.rb +90 -0
- data/lib/protip/transformers/enum_transformer.rb +93 -0
- data/lib/protip/transformers/primitives_transformer.rb +78 -0
- data/lib/protip/transformers/timestamp_transformer.rb +31 -0
- data/test/functional/protip/decorator_test.rb +204 -0
- data/test/unit/protip/decorator_test.rb +665 -0
- data/test/unit/protip/resource_test.rb +76 -92
- data/test/unit/protip/transformers/decorating_transformer_test.rb +92 -0
- data/test/unit/protip/transformers/delegating_transformer_test.rb +83 -0
- data/test/unit/protip/transformers/deprecated_transformer_test.rb +139 -0
- data/test/unit/protip/transformers/enum_transformer_test.rb +157 -0
- data/test/unit/protip/transformers/primitives_transformer_test.rb +139 -0
- data/test/unit/protip/transformers/timestamp_transformer_test.rb +46 -0
- metadata +23 -12
- data/definitions/google/protobuf/wrappers.proto +0 -99
- data/lib/google/protobuf/descriptor.rb +0 -1
- data/lib/google/protobuf/wrappers.rb +0 -48
- data/lib/protip/converter.rb +0 -22
- data/lib/protip/standard_converter.rb +0 -185
- data/test/unit/protip/standard_converter_test.rb +0 -502
- data/test/unit/protip/wrapper_test.rb +0 -646
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'protip/transformers/deprecated_transformer'
|
4
|
+
|
5
|
+
require 'protip/messages'
|
6
|
+
|
7
|
+
describe Protip::Transformers::DeprecatedTransformer do
|
8
|
+
let(:transformer) { Protip::Transformers::DeprecatedTransformer.new }
|
9
|
+
let(:message_class) { raise NotImplementedError } # sub-sections must define
|
10
|
+
let(:field) do
|
11
|
+
field = mock.responds_like_instance_of ::Google::Protobuf::FieldDescriptor
|
12
|
+
field.stubs(:submsg_name).returns(message_class.descriptor.name)
|
13
|
+
field.stubs(:subtype).returns(message_class.descriptor)
|
14
|
+
field
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#to_object' do
|
18
|
+
describe 'Date' do
|
19
|
+
let(:message_class) { Protip::Messages::Date }
|
20
|
+
it 'converts dates' do
|
21
|
+
date = transformer.to_object(message_class.new(year: 2015, month: 2, day: 9), field)
|
22
|
+
assert_instance_of ::Date, date
|
23
|
+
assert_equal '2015-02-09', date.strftime
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'Range' do
|
28
|
+
let(:message_class) { Protip::Messages::Range }
|
29
|
+
it 'converts ranges' do
|
30
|
+
range = transformer.to_object(message_class.new(begin: 1, end: 4), field)
|
31
|
+
assert_instance_of ::Range, range
|
32
|
+
assert_equal 1..4, range
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'Currency' do
|
37
|
+
let(:message_class) { Protip::Messages::Currency }
|
38
|
+
it 'converts currency' do
|
39
|
+
currency = transformer.to_object(message_class.new(currency_code: :GBP), field)
|
40
|
+
assert_equal :GBP, currency
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe 'Money' do
|
45
|
+
let(:message_class) { Protip::Messages::Money }
|
46
|
+
it 'converts money' do
|
47
|
+
message = message_class.new amount_cents: 250,
|
48
|
+
currency: (Protip::Messages::Currency.new currency_code: :CAD)
|
49
|
+
money = transformer.to_object(message, field)
|
50
|
+
assert_instance_of ::Money, money
|
51
|
+
assert_equal ::Money::Currency.new(:CAD), money.currency
|
52
|
+
assert_equal 250, money.fractional
|
53
|
+
assert_equal ::Money.new(250, 'CAD'), money
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe 'ActiveSupport::TimeWithZone' do
|
58
|
+
let(:message_class) { Protip::Messages::ActiveSupport::TimeWithZone }
|
59
|
+
it 'converts times with zones' do
|
60
|
+
message = message_class.new utc_timestamp: 1451610000,
|
61
|
+
time_zone_name: 'America/Los_Angeles'
|
62
|
+
time = transformer.to_object(message, field)
|
63
|
+
assert_instance_of ::ActiveSupport::TimeWithZone, time
|
64
|
+
assert_equal 1451610000, time.to_i
|
65
|
+
assert_equal '2015-12-31T17:00:00-08:00', time.iso8601
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe '#to_message' do
|
71
|
+
describe 'Date' do
|
72
|
+
let(:message_class) { Protip::Messages::Date }
|
73
|
+
it 'converts dates' do
|
74
|
+
date = ::Date.new(2012, 5, 7)
|
75
|
+
assert_equal 7, date.day # Sanity check argument order
|
76
|
+
assert_equal message_class.new(year: 2012, month: 5, day: 7),
|
77
|
+
transformer.to_message(date, field)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe 'Range' do
|
82
|
+
let(:message_class) { Protip::Messages::Range }
|
83
|
+
it 'converts ranges' do
|
84
|
+
range = -1..34
|
85
|
+
assert_equal message_class.new(begin: -1, end: 34),
|
86
|
+
transformer.to_message(range, field)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe 'Currency' do
|
91
|
+
let(:message_class) { Protip::Messages::Currency }
|
92
|
+
it 'converts currency' do
|
93
|
+
currency = :HKD
|
94
|
+
message = transformer.to_message(currency, field)
|
95
|
+
assert_equal message_class.new(currency_code: currency), message
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe 'Money' do
|
100
|
+
let(:message_class) { Protip::Messages::Money }
|
101
|
+
it 'converts money' do
|
102
|
+
money = ::Money.new(250, 'CAD')
|
103
|
+
message = transformer.to_message(money, field)
|
104
|
+
assert_instance_of message_class, message
|
105
|
+
assert_equal message_class.new(
|
106
|
+
amount_cents: money.cents,
|
107
|
+
currency: Protip::Messages::Currency.new(
|
108
|
+
currency_code: money.currency.iso_code.to_sym
|
109
|
+
)),
|
110
|
+
message
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe 'ActiveSupport::TimeWithZone' do
|
115
|
+
let(:message_class) { Protip::Messages::ActiveSupport::TimeWithZone }
|
116
|
+
it 'converts times with zones' do
|
117
|
+
time_with_zone = ::ActiveSupport::TimeWithZone.new(Time.new(2016, 1, 1, 0, 0, 0, 0),
|
118
|
+
::ActiveSupport::TimeZone.new('America/New_York'))
|
119
|
+
message = transformer.to_message(time_with_zone, field)
|
120
|
+
assert_equal 1451606400, message.utc_timestamp
|
121
|
+
assert_equal 'America/New_York', message.time_zone_name
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'converts times without zones' do
|
125
|
+
time = ::Time.new(2016, 1, 1, 0, 0, 0, -3600)
|
126
|
+
message = transformer.to_message(time, field)
|
127
|
+
assert_equal 1451610000, message.utc_timestamp
|
128
|
+
assert_equal 'UTC', message.time_zone_name
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'converts datetimes without zones' do
|
132
|
+
datetime = ::DateTime.new(2016, 1, 1, 0, 0, 0, '-1')
|
133
|
+
message = transformer.to_message(datetime, field)
|
134
|
+
assert_equal 1451610000, message.utc_timestamp
|
135
|
+
assert_equal 'UTC', message.time_zone_name
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'protip/transformers/enum_transformer'
|
4
|
+
|
5
|
+
require 'protip/messages'
|
6
|
+
|
7
|
+
describe Protip::Transformers::EnumTransformer do
|
8
|
+
let(:transformer) { Protip::Transformers::EnumTransformer.new }
|
9
|
+
let(:pool) do
|
10
|
+
# See https://github.com/google/protobuf/blob/master/ruby/tests/generated_code.rb for
|
11
|
+
# examples of field types you can add here
|
12
|
+
pool = Google::Protobuf::DescriptorPool.new
|
13
|
+
pool.build do
|
14
|
+
add_enum 'number' do
|
15
|
+
value :ZERO, 0
|
16
|
+
value :ONE, 1
|
17
|
+
end
|
18
|
+
end
|
19
|
+
pool
|
20
|
+
end
|
21
|
+
let(:enum) { pool.lookup 'number' }
|
22
|
+
let(:message_class) { raise NotImplementedError } # sub-sections must define
|
23
|
+
let(:field) do
|
24
|
+
field = mock.responds_like_instance_of ::Google::Protobuf::FieldDescriptor
|
25
|
+
field.stubs(:submsg_name).returns(message_class.descriptor.name)
|
26
|
+
field.stubs(:subtype).returns(message_class.descriptor)
|
27
|
+
field
|
28
|
+
end
|
29
|
+
|
30
|
+
before do
|
31
|
+
Protip::Transformers::EnumTransformer.stubs(:enum_for_field).
|
32
|
+
returns(enum)
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#to_object' do
|
36
|
+
describe 'scalars' do
|
37
|
+
let(:message_class) { Protip::Messages::EnumValue }
|
38
|
+
it 'transforms enum values in range to symbols' do
|
39
|
+
message = message_class.new(value: 1)
|
40
|
+
assert_equal :ONE, transformer.to_object(message, field)
|
41
|
+
end
|
42
|
+
it 'transforms enum values out of range to integers' do
|
43
|
+
message = message_class.new(value: 5)
|
44
|
+
assert_equal 5, transformer.to_object(message, field)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
describe 'arrays' do
|
48
|
+
let(:message_class) { Protip::Messages::RepeatedEnum }
|
49
|
+
it 'transforms repeated enum values in range to symbols' do
|
50
|
+
message = message_class.new(values: [0, 1])
|
51
|
+
assert_equal [:ZERO, :ONE], transformer.to_object(message, field)
|
52
|
+
end
|
53
|
+
it 'transforms repeated enum values out of range to integers' do
|
54
|
+
message = message_class.new(values: [3, 1, 5])
|
55
|
+
assert_equal [3, :ONE, 5], transformer.to_object(message, field)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#to_message' do
|
61
|
+
%w(zero one two).each do |number| # values symbolizing as :ZERO, :ONE, :TWO
|
62
|
+
let number do
|
63
|
+
value = mock
|
64
|
+
value.stubs(:to_sym).returns(number.upcase.to_sym)
|
65
|
+
value
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe 'scalars' do
|
70
|
+
let(:message_class) { Protip::Messages::EnumValue }
|
71
|
+
it 'transforms integers to messages' do
|
72
|
+
assert_equal message_class.new(value: 1), transformer.to_message(1, field)
|
73
|
+
end
|
74
|
+
it 'transforms non-integers via :to_sym' do
|
75
|
+
assert_equal message_class.new(value: 1), transformer.to_message(one, field)
|
76
|
+
end
|
77
|
+
it 'throws an error when an out-of-range symbol is given' do
|
78
|
+
field.stubs(:name).returns('FOO') # The exception message contains this
|
79
|
+
exception = assert_raises RangeError do
|
80
|
+
transformer.to_message(two, field)
|
81
|
+
end
|
82
|
+
assert_match(/FOO/, exception.message)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe 'arrays' do
|
87
|
+
let(:message_class) { Protip::Messages::RepeatedEnum }
|
88
|
+
it 'transforms integers' do
|
89
|
+
assert_equal message_class.new(values: [1, 4]),
|
90
|
+
transformer.to_message([1, 4], field)
|
91
|
+
end
|
92
|
+
it 'transforms non-integers via :to_sym' do
|
93
|
+
assert_equal message_class.new(values: [0, 2, 1]),
|
94
|
+
transformer.to_message([zero, 2, one], field)
|
95
|
+
end
|
96
|
+
it 'throws an error when an out-of-range symbol is given' do
|
97
|
+
field.stubs(:name).returns('FOO') # The exception message contains this
|
98
|
+
exception = assert_raises RangeError do
|
99
|
+
transformer.to_message([0, two], field)
|
100
|
+
end
|
101
|
+
assert_match(/FOO/, exception.message)
|
102
|
+
end
|
103
|
+
it 'allows assigning a scalar value' do
|
104
|
+
assert_equal message_class.new(values: [1]), transformer.to_message(one, field)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
describe '.enum_for_field' do
|
111
|
+
# TODO pending https://github.com/google/protobuf/issues/1198
|
112
|
+
end
|
113
|
+
|
114
|
+
if false #describe '(functional)' do # Temp - test an actual compiled file to make sure our options hack is working
|
115
|
+
require 'protip/messages/test'
|
116
|
+
require 'protip/wrapper'
|
117
|
+
let(:wrapped_message) { Protip::Messages::EnumTest.new }
|
118
|
+
let(:wrapper) { Protip::Wrapper.new wrapped_message, transformer }
|
119
|
+
|
120
|
+
let(:value_map) do
|
121
|
+
{
|
122
|
+
:ONE => :ONE,
|
123
|
+
1 => :ONE,
|
124
|
+
2 => 2,
|
125
|
+
}
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'allows setting and getting a scalar field by Ruby value' do
|
129
|
+
value_map.each do |value, expected|
|
130
|
+
wrapper.enum = value
|
131
|
+
assert_equal expected, wrapper.enum
|
132
|
+
end
|
133
|
+
assert_raises RangeError do
|
134
|
+
wrapper.enum = :TWO
|
135
|
+
end
|
136
|
+
end
|
137
|
+
it 'allows setting and getting a scalar field by message' do
|
138
|
+
wrapper.enum = ::Protip::Messages::EnumValue.new(value: 1)
|
139
|
+
assert_equal :ONE, wrapper.enum
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'allows setting and getting a repeated field by Ruby value' do
|
143
|
+
value_map.each do |value, expected|
|
144
|
+
wrapper.repeated_enums = [value]
|
145
|
+
assert_equal [expected], wrapper.repeated_enums
|
146
|
+
end
|
147
|
+
assert_raises RangeError do
|
148
|
+
wrapper.repeated_enums = [:TWO]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
it 'allows setting and geting a repeated field by message' do
|
152
|
+
wrapper.repeated_enums = ::Protip::Messages::RepeatedEnum.new(values: [2])
|
153
|
+
assert_equal [2], wrapper.repeated_enums
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'base64'
|
3
|
+
|
4
|
+
require 'protip/transformers/primitives_transformer'
|
5
|
+
|
6
|
+
require 'google/protobuf/wrappers'
|
7
|
+
require 'protip/messages'
|
8
|
+
|
9
|
+
describe ::Protip::Transformers::PrimitivesTransformer do
|
10
|
+
let(:transformer) { ::Protip::Transformers::PrimitivesTransformer.new }
|
11
|
+
let(:message_class) { raise NotImplementedError } # sub-sections must define
|
12
|
+
let(:field) do
|
13
|
+
field = mock.responds_like_instance_of ::Google::Protobuf::FieldDescriptor
|
14
|
+
field.stubs(:submsg_name).returns(message_class.descriptor.name)
|
15
|
+
field.stubs(:subtype).returns(message_class.descriptor)
|
16
|
+
field
|
17
|
+
end
|
18
|
+
|
19
|
+
INTEGER_TYPES = %w(Int64 Int32 UInt64 UInt32)
|
20
|
+
FLOAT_TYPES = %w(Float Double)
|
21
|
+
STRING_TYPES = %w(String)
|
22
|
+
BOOLEAN_TYPES = %w(Bool)
|
23
|
+
BYTES_TYPES = %w(Bytes)
|
24
|
+
|
25
|
+
BYTES_VALUE = Base64.decode64("U2VuZCByZWluZm9yY2VtZW50cw==\n")
|
26
|
+
|
27
|
+
{
|
28
|
+
6 => INTEGER_TYPES,
|
29
|
+
5.5 => FLOAT_TYPES,
|
30
|
+
'foo' => STRING_TYPES,
|
31
|
+
true => BOOLEAN_TYPES,
|
32
|
+
BYTES_VALUE => BYTES_TYPES,
|
33
|
+
}.each do |value, types|
|
34
|
+
types.each do |type|
|
35
|
+
describe '#to_object' do
|
36
|
+
describe "google.protobuf.#{type}Value" do
|
37
|
+
let(:message_class) { Google::Protobuf.const_get("#{type}Value") }
|
38
|
+
it 'converts scalar messages' do
|
39
|
+
assert_equal value, transformer.to_object(message_class.new(value: value), field)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "protip.messages.Repeated#{type}" do
|
44
|
+
let(:message_class) { Protip::Messages.const_get("Repeated#{type}") }
|
45
|
+
it 'converts repeated mesages to an immutable array' do
|
46
|
+
result = transformer.to_object(message_class.new(values: [value, value]), field)
|
47
|
+
assert_equal [value, value], result
|
48
|
+
|
49
|
+
exception = assert_raises RuntimeError do
|
50
|
+
result << value
|
51
|
+
end
|
52
|
+
assert_equal 'can\'t modify frozen Array', exception.message
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#to_message' do
|
57
|
+
# Keys are the actual value that should be set on the message,
|
58
|
+
# values are an object of a different type that should be converted.
|
59
|
+
# Used for testing that e.g. integer types can be set using numeric strings.
|
60
|
+
if INTEGER_TYPES.include?(type) || FLOAT_TYPES.include?(type)
|
61
|
+
let(:native_to_non_native) { {value => value.to_s} }
|
62
|
+
elsif STRING_TYPES.include?(type)
|
63
|
+
let(:native_to_non_native) { {'3' => 3} }
|
64
|
+
elsif BOOLEAN_TYPES.include?(type)
|
65
|
+
let(:native_to_non_native) { {true => 'on', false => 'off'} }
|
66
|
+
else
|
67
|
+
let(:native_to_non_native) { {} }
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "google.protobuf.#{type}Value" do
|
71
|
+
let(:message_class) { Google::Protobuf.const_get("#{type}Value") }
|
72
|
+
it 'converts scalar types to a message' do
|
73
|
+
assert_equal message_class.new(value: value), transformer.to_message(value, field)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "converts non-#{type} types to a #{type} message" do
|
77
|
+
native_to_non_native.each do |native, non_native|
|
78
|
+
assert_equal message_class.new(value: native),
|
79
|
+
transformer.to_message(non_native, field)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "protip.messages.Repeated#{type}" do
|
85
|
+
let(:message_class) { Protip::Messages.const_get("Repeated#{type}") }
|
86
|
+
|
87
|
+
it 'converts repeated types when given a scalar' do
|
88
|
+
assert_equal message_class.new(values: [value]),
|
89
|
+
transformer.to_message(value, field)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'converts repeated types when given an array' do
|
93
|
+
assert_equal message_class.new(values: [value, value]),
|
94
|
+
transformer.to_message([value, value], field)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "converts non-#{type} scalar types to a repeated #{type} message" do
|
98
|
+
native_to_non_native.each do |native, non_native|
|
99
|
+
assert_equal message_class.new(values: [native]),
|
100
|
+
transformer.to_message(non_native, field)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
it "converts non-#{type} array types to a repeated #{type} message" do
|
105
|
+
native_to_non_native.each do |native, non_native|
|
106
|
+
assert_equal message_class.new(values: [native, native]),
|
107
|
+
transformer.to_message([non_native, non_native], field)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe '#to_message' do
|
117
|
+
let(:message_class) { Google::Protobuf::BoolValue }
|
118
|
+
it 'converts all truthy values to booleans' do
|
119
|
+
[true, 1, '1', 't', 'T', 'true', 'TRUE', 'on', 'ON'].each do |truth_value|
|
120
|
+
assert_equal Google::Protobuf::BoolValue.new(value: true),
|
121
|
+
transformer.to_message(truth_value, field)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
it 'converts all falsey values to booleans' do
|
125
|
+
[false, 0, '0', 'f', 'F', 'false', 'FALSE', 'off', 'OFF'].each do |false_value|
|
126
|
+
assert_equal Google::Protobuf::BoolValue.new(value: false),
|
127
|
+
transformer.to_message(false_value, field)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'raises an exception if non-boolean values passed to a boolean field' do
|
132
|
+
[nil, 'test', Object.new, 2, {}, []].each do |bad_value|
|
133
|
+
assert_raises TypeError do
|
134
|
+
transformer.to_message(bad_value, field)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'protip/transformers/timestamp_transformer'
|
3
|
+
require 'google/protobuf/timestamp'
|
4
|
+
|
5
|
+
describe Protip::Transformers::TimestampTransformer do
|
6
|
+
let(:transformer) { Protip::Transformers::TimestampTransformer.new }
|
7
|
+
let(:field) do
|
8
|
+
field = mock.responds_like_instance_of Google::Protobuf::FieldDescriptor
|
9
|
+
descriptor = Google::Protobuf::Timestamp.descriptor
|
10
|
+
field.stubs(:submsg_name).returns(descriptor.name)
|
11
|
+
field.stubs(:subtype).returns(descriptor)
|
12
|
+
field
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#to_object' do
|
16
|
+
it 'creates a timestamp' do
|
17
|
+
message = Google::Protobuf::Timestamp.new(seconds: 1415, nanos: 12345678)
|
18
|
+
result = transformer.to_object(message, field)
|
19
|
+
assert_instance_of ::Time, result
|
20
|
+
assert_equal 1415, result.to_i
|
21
|
+
assert_equal 12345678, result.nsec
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#to_message' do
|
26
|
+
let(:timestamp) do
|
27
|
+
::Time.at(601, 1)
|
28
|
+
end
|
29
|
+
let(:expected_message) do
|
30
|
+
Google::Protobuf::Timestamp.new(
|
31
|
+
seconds: 601,
|
32
|
+
nanos: 1000,
|
33
|
+
)
|
34
|
+
end
|
35
|
+
it 'converts times directly' do
|
36
|
+
assert_equal expected_message,
|
37
|
+
transformer.to_message(timestamp, field)
|
38
|
+
end
|
39
|
+
it 'converts non-times via :to_time' do
|
40
|
+
object = mock 'object'
|
41
|
+
object.expects(:to_time).once.returns(timestamp)
|
42
|
+
assert_equal expected_message,
|
43
|
+
transformer.to_message(object, field)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|