protobuf-activerecord 7.0.0 → 7.1.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.
@@ -1,254 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Protobuf::ActiveRecord::Transformation do
4
- let(:user) { User.new(user_attributes) }
5
- let(:user_attributes) { {first_name: "foo", last_name: "bar", email: "foo@test.co"} }
6
- let(:proto_hash) { {name: "foo bar", email: "foo@test.co"} }
7
- let(:proto) { UserMessage.new(proto_hash) }
8
-
9
- describe "._filter_attribute_fields" do
10
- it "includes fields that have values" do
11
- attribute_fields = User._filter_attribute_fields(proto)
12
- expect(attribute_fields[:email]).to eq proto_hash[:email]
13
- end
14
-
15
- it "filters repeated fields" do
16
- attribute_fields = User._filter_attribute_fields(proto)
17
- expect(attribute_fields.key?(:tags)).to be false
18
- end
19
-
20
- it "includes attributes that aren't fields, but have attribute transformers" do
21
- allow(User).to receive(:_protobuf_attribute_transformers).and_return(account_id: :fetch_account_id)
22
- attribute_fields = User._filter_attribute_fields(proto)
23
- expect(attribute_fields.key?(:account_id)).to be true
24
- end
25
-
26
- it "includes fields that aren't attributes, but have attribute transformers" do
27
- attribute_fields = User._filter_attribute_fields(proto)
28
- expect(attribute_fields.key?(:password)).to be true
29
- end
30
- end
31
-
32
- describe "._protobuf_convert_fields_to_attributes" do
33
- context "when the given field's corresponding column type is :date" do
34
- let(:date) { Date.current }
35
- let(:value) { date.to_time.to_i }
36
-
37
- before {
38
- allow(User).to receive(:_protobuf_date_datetime_time_or_timestamp_column?).and_return(true)
39
- allow(User).to receive(:_protobuf_date_column?).and_return(true)
40
- }
41
-
42
- it "converts the given value to a Date object" do
43
- expect(User._protobuf_convert_fields_to_attributes(:foo_date, value)).to eq date
44
- end
45
- end
46
-
47
- context "when given field's corresponding the column type is :datetime" do
48
- let(:datetime) { DateTime.current }
49
- let(:value) { datetime.to_i }
50
-
51
- before {
52
- allow(User).to receive(:_protobuf_date_datetime_time_or_timestamp_column?).and_return(true)
53
- allow(User).to receive(:_protobuf_datetime_column?).and_return(true)
54
- }
55
-
56
- it "converts the given value to a DateTime object" do
57
- expect(User._protobuf_convert_fields_to_attributes(:foo_datetime, value)).to be_a(DateTime)
58
- end
59
-
60
- it "converts the given value to a DateTime object of the same value" do
61
- expect(User._protobuf_convert_fields_to_attributes(:foo_datetime, value)).to be_within(1).of(datetime)
62
- end
63
- end
64
-
65
- context "when given field's corresponding the column type is :time" do
66
- let(:time) { Time.current }
67
- let(:value) { time.to_i }
68
-
69
- before {
70
- allow(User).to receive(:_protobuf_date_datetime_time_or_timestamp_column?).and_return(true)
71
- allow(User).to receive(:_protobuf_time_column?).and_return(true)
72
- }
73
-
74
- it "converts the given value to a Time object" do
75
- expect(User._protobuf_convert_fields_to_attributes(:foo_time, value)).to be_a(Time)
76
- end
77
-
78
- it "converts the given value to a Time object of the same value" do
79
- expect(User._protobuf_convert_fields_to_attributes(:foo_time, value)).to be_within(1).of(time)
80
- end
81
- end
82
-
83
- context "when given field's corresponding the column type is :timestamp" do
84
- let(:time) { Time.current }
85
- let(:value) { time.to_i }
86
-
87
- before {
88
- allow(User).to receive(:_protobuf_date_datetime_time_or_timestamp_column?).and_return(true)
89
- allow(User).to receive(:_protobuf_timestamp_column?).and_return(true)
90
- }
91
-
92
- it "converts the given value to a Time object" do
93
- expect(User._protobuf_convert_fields_to_attributes(:foo_time, value)).to be_a(Time)
94
- end
95
-
96
- it "converts the given value to a Time object of the same value" do
97
- expect(User._protobuf_convert_fields_to_attributes(:foo_timestamp, value)).to be_within(1).of(time)
98
- end
99
- end
100
-
101
- context "when no conversion is necessary" do
102
- let(:value) { "Foo" }
103
-
104
- it "returns the given value" do
105
- expect(User._protobuf_convert_fields_to_attributes(:foo, value)).to eq value
106
- end
107
- end
108
- end
109
-
110
- describe ".attributes_from_proto" do
111
- let(:callable) { lambda { |_proto| 1 } }
112
- let(:transformer) { ::Protobuf::ActiveRecord::Transformer.new(callable) }
113
-
114
- context "when a transformer is defined for the attribute" do
115
- it "transforms the field value" do
116
- attribute_fields = User.attributes_from_proto(proto)
117
- expect(attribute_fields[:first_name]).to eq user_attributes[:first_name]
118
- end
119
- end
120
-
121
- context "when a transformer is a callable that returns nil" do
122
- let(:callable) { lambda { |_proto| } }
123
-
124
- before do
125
- transformers = User._protobuf_attribute_transformers
126
- allow(User).to receive(:_protobuf_attribute_transformers).and_return(
127
- {account_id: transformer}.merge(transformers)
128
- )
129
- end
130
-
131
- it "does not set the attribute" do
132
- attribute_fields = User.attributes_from_proto(proto)
133
- expect(attribute_fields).to eq user_attributes
134
- end
135
- end
136
-
137
- context "when the transformer has a nullify_on option" do
138
- let(:callable) { lambda { |_proto| } }
139
- let(:transformer) { ::Protobuf::ActiveRecord::Transformer.new(callable, nullify_on: :account_id) }
140
- let(:proto_hash) { {name: "foo bar", email: "foo@test.co", nullify: [:account_id]} }
141
-
142
- before do
143
- transformers = User._protobuf_attribute_transformers
144
- allow(User).to receive(:_protobuf_attribute_transformers).and_return(
145
- {account_id: transformer}.merge(transformers)
146
- )
147
- end
148
-
149
- it "does not set the attribute" do
150
- attribute_fields = User.attributes_from_proto(proto)
151
- expect(attribute_fields).to include(account_id: nil)
152
- end
153
- end
154
-
155
- context "when a transformer is a callable that returns a value" do
156
- before do
157
- transformers = User._protobuf_attribute_transformers
158
- allow(User).to receive(:_protobuf_attribute_transformers).and_return(
159
- {account_id: transformer}.merge(transformers)
160
- )
161
- end
162
-
163
- it "sets the attribute" do
164
- attribute_fields = User.attributes_from_proto(proto)
165
- expect(attribute_fields).to eq user_attributes.merge(account_id: 1)
166
- end
167
- end
168
-
169
- context "when a transformer is not defined for the attribute" do
170
- before {
171
- allow(User).to receive(:_protobuf_convert_fields_to_attributes) do |_key, value|
172
- value
173
- end
174
- }
175
-
176
- it "converts the field value" do
177
- attribute_fields = User.attributes_from_proto(proto)
178
- expect(attribute_fields).to eq user_attributes
179
- end
180
- end
181
- end
182
-
183
- describe ".attribute_from_proto" do
184
- context "when the given transformer is a symbol" do
185
- let(:callable) { lambda { |_value| User.__send__(:extract_first_name) } }
186
-
187
- before { User.attribute_from_proto :first_name, :extract_first_name }
188
-
189
- it "creates a callable method object from the converter" do
190
- expect(User).to receive(:extract_first_name)
191
- User._protobuf_attribute_transformers[:first_name].call(1)
192
- end
193
- end
194
-
195
- context "when the given transformer is not callable" do
196
- it "raises an exception" do
197
- expect { User.attribute_from_proto :name, nil }.to raise_exception(Protobuf::ActiveRecord::AttributeTransformerError)
198
- end
199
- end
200
-
201
- context "when the given transformer is callable" do
202
- let(:callable) { lambda { |_proto| } }
203
-
204
- before { allow(User).to receive(:_protobuf_attribute_transformers).and_return({}) }
205
-
206
- it "adds the given converter to the list of protobuf field transformers" do
207
- User.attribute_from_proto :account_id, callable
208
- expect(User._protobuf_attribute_transformers[:account_id].callable).to eq callable
209
- end
210
- end
211
- end
212
-
213
- describe ".convert_int64_to_date" do
214
- let(:date) { Date.current }
215
- let(:int64) { date.to_time.to_i }
216
-
217
- it "initializes a new Date object from the value" do
218
- Timecop.freeze(Date.current) do
219
- expect(User.convert_int64_to_date(int64)).to eq date
220
- end
221
- end
222
- end
223
-
224
- describe ".convert_int64_to_datetime" do
225
- let(:datetime) { DateTime.current }
226
- let(:int64) { datetime.to_i }
227
-
228
- it "initializes a new DateTime object from the value" do
229
- Timecop.freeze(DateTime.current) do
230
- expected_datetime = Time.at(datetime.to_i)
231
- converted_datetime = User.convert_int64_to_datetime(int64)
232
- expect(converted_datetime).to eq expected_datetime
233
- end
234
- end
235
- end
236
-
237
- describe ".convert_int64_to_time" do
238
- let(:time) { Time.current }
239
- let(:int64) { time.to_time.to_i }
240
-
241
- it "initializes a new Time object from the value" do
242
- Timecop.freeze(Time.current) do
243
- expect(User.convert_int64_to_time(int64)).to be_within(1).of(time)
244
- end
245
- end
246
- end
247
-
248
- describe "#attributes_from_proto" do
249
- it "gets attributes from the given protobuf message" do
250
- expect(User).to receive(:attributes_from_proto).with(proto)
251
- user.attributes_from_proto(proto)
252
- end
253
- end
254
- end
@@ -1,42 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe ::Protobuf::ActiveRecord::Transformer do
4
- let(:callable) { lambda { |proto| proto.name } }
5
- let(:proto) { ::UserMessage.new(name: "test", nullify: ["name"]) }
6
- let(:options) { {} }
7
-
8
- subject { described_class.new(callable, options) }
9
-
10
- describe "#call" do
11
- it "calls the callable" do
12
- result = subject.call(proto)
13
- expect(result).to eq("test")
14
- end
15
- end
16
-
17
- describe "#nullify?" do
18
- context "no nullify_on set" do
19
- it "returns false" do
20
- expect(subject.nullify?(proto)).to eq(false)
21
- end
22
- end
23
-
24
- context "nullify_on name" do
25
- let(:options) { {nullify_on: :name} }
26
-
27
- context "invalid message" do
28
- let(:proto) { ::UserSearchMessage.new }
29
-
30
- it "returns false" do
31
- expect(subject.nullify?(proto)).to eq(false)
32
- end
33
- end
34
-
35
- context "valid message" do
36
- it "returns true" do
37
- expect(subject.nullify?(proto)).to eq(true)
38
- end
39
- end
40
- end
41
- end
42
- end
data/spec/spec_helper.rb DELETED
@@ -1,27 +0,0 @@
1
- require "rubygems"
2
- require "bundler"
3
-
4
- require "simplecov"
5
- SimpleCov.start do
6
- add_filter "/spec/"
7
- end
8
-
9
- Bundler.require(:default, :development, :test)
10
-
11
- require "support/db"
12
- require "support/models"
13
- require "support/protobuf/messages.pb"
14
-
15
- # Silence protobuf"s logger
16
- Protobuf::Logging.logger.level = ::Logger::FATAL
17
-
18
- RSpec.configure do |config|
19
- # Turn deprecation warnings into errors with full backtrace.
20
- config.raise_errors_for_deprecations!
21
-
22
- # Verifies the existance of any stubbed methods, replaces better_receive and better_stub
23
- # https://www.relishapp.com/rspec/rspec-mocks/v/3-1/docs/verifying-doubles/partial-doubles
24
- config.mock_with :rspec do |mocks|
25
- mocks.verify_partial_doubles = true
26
- end
27
- end
@@ -1,29 +0,0 @@
1
- require "active_record"
2
-
3
- ActiveRecord::Base.establish_connection(
4
- adapter: "sqlite3",
5
- database: "spec/test.db"
6
- )
7
-
8
- ActiveRecord::Base.connection.data_sources.each do |table|
9
- ActiveRecord::Base.connection.drop_table(table)
10
- end
11
-
12
- ActiveRecord::Schema.define(version: 1) do
13
- create_table :photos do |t|
14
- t.string :url
15
- t.integer :user_id
16
-
17
- t.timestamps null: false
18
- end
19
-
20
- create_table :users do |t|
21
- t.string :guid
22
- t.string :first_name
23
- t.string :last_name
24
- t.string :email
25
- t.integer :account_id
26
-
27
- t.timestamps null: false
28
- end
29
- end
data/spec/support/db.rb DELETED
@@ -1 +0,0 @@
1
- require "support/db/setup"
@@ -1,23 +0,0 @@
1
- syntax = "proto3";
2
-
3
- message PhotoMessage {
4
- string url = 1;
5
- int64 user_guid = 2;
6
- }
7
-
8
- message UserMessage {
9
- string guid = 1;
10
- string name = 2;
11
- string email = 3;
12
- string email_domain = 4 [deprecated = true];
13
- string password = 5;
14
- repeated string nullify = 6;
15
- repeated PhotoMessage photos = 7;
16
- int64 created_at = 8;
17
- int64 updated_at = 9;
18
- }
19
-
20
- message UserSearchMessage {
21
- repeated string guid = 1;
22
- repeated string email = 2;
23
- }
@@ -1,3 +0,0 @@
1
- class Photo < ActiveRecord::Base
2
- include Protobuf::ActiveRecord::Model
3
- end
@@ -1,53 +0,0 @@
1
- class User < ActiveRecord::Base
2
- include Protobuf::ActiveRecord::Model
3
-
4
- attr_accessor :password
5
-
6
- has_many :photos
7
-
8
- accepts_nested_attributes_for :photos
9
-
10
- scope :by_guid, lambda { |*guids| where(guid: guids) }
11
- scope :by_email, lambda { |*emails| where(email: emails) }
12
-
13
- protobuf_fields except: :photos
14
-
15
- attribute_from_proto :first_name, :extract_first_name
16
- attribute_from_proto :last_name, :extract_last_name
17
- attribute_from_proto :password, lambda { |proto| proto.password! }
18
-
19
- field_from_record :email_domain, lambda { |record| record.email.split("@").last }
20
- field_from_record :password, :password_transformer
21
-
22
- def self.extract_first_name(proto)
23
- if proto.field?(:name)
24
- names = proto.name.split(" ")
25
- first_name = names.first
26
- end
27
-
28
- first_name
29
- end
30
-
31
- def self.extract_last_name(proto)
32
- if proto.field?(:name)
33
- names = proto.name.split(" ")
34
- names.shift # Drop the first name
35
- last_name = names.join(" ")
36
- end
37
-
38
- last_name
39
- end
40
-
41
- def self.password_transformer(user)
42
- # Simple way to test field transformers that call methods
43
- user.password
44
- end
45
-
46
- def token
47
- "key"
48
- end
49
-
50
- def name
51
- "#{first_name} #{last_name}"
52
- end
53
- end
@@ -1,2 +0,0 @@
1
- require "support/models/photo"
2
- require "support/models/user"
@@ -1,38 +0,0 @@
1
- ##
2
- # This file is auto-generated. DO NOT EDIT!
3
- #
4
- require "protobuf"
5
-
6
- ##
7
- # Message Classes
8
- #
9
- class PhotoMessage < ::Protobuf::Message; end
10
-
11
- class UserMessage < ::Protobuf::Message; end
12
-
13
- class UserSearchMessage < ::Protobuf::Message; end
14
-
15
- ##
16
- # Message Fields
17
- #
18
- class PhotoMessage
19
- optional :string, :url, 1
20
- optional :int64, :user_guid, 2
21
- end
22
-
23
- class UserMessage
24
- optional :string, :guid, 1
25
- optional :string, :name, 2
26
- optional :string, :email, 3
27
- optional :string, :email_domain, 4, deprecated: true
28
- optional :string, :password, 5
29
- repeated :string, :nullify, 6
30
- repeated ::PhotoMessage, :photos, 7
31
- optional :int64, :created_at, 8
32
- optional :int64, :updated_at, 9
33
- end
34
-
35
- class UserSearchMessage
36
- repeated :string, :guid, 1
37
- repeated :string, :email, 2
38
- end