active_remote 2.3.2 → 2.3.3.pre

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b08e44ec12d74b9ccbcad49d83a11410e113ad89
4
- data.tar.gz: 548d83e5dfa32d9d1509438facddf3004f7d34d9
3
+ metadata.gz: fde256631d072c0dbb9b64da285670f35907c207
4
+ data.tar.gz: f087ed474857994084ce213cd65334e171fce348
5
5
  SHA512:
6
- metadata.gz: 813cfdb4e920fa42af09933086d24c9bbcf119ec7727b385b5484f942cb74af791b5e0b64a4e501f9ff36b368feaaad9f925f20b3026d3fe93019e9e0a7a7e6f
7
- data.tar.gz: 1b232f29d892e3a9e09b269b12d0a8b60e180f90b290456bed7dca082c0a85dadedecdba341b7816e6e82c821036a2f8fb34531776edfddfba830949d4393002
6
+ metadata.gz: 8984da90d6fea1eb43c79d7ba7df6aaf4d08d9bd1967056a0d0b89861220fc82e60d699d1c509d7c698f25c70f668ad994d76672161731021431d176cd5075cc
7
+ data.tar.gz: c42d0d74c59126c346503556e9c39ac068de220ae27e6d0ef4a885c2b05ae8b90dceb58a725c2b188eb4ddf6099f56d1e0997f3b20e77b90f92957f7cd560197
@@ -1,5 +1,13 @@
1
1
  module ActiveRemote
2
2
  module Attributes
3
+ def attributes
4
+ @attributes ||= begin
5
+ attribute_names = self.class.attribute_names
6
+ Hash[attribute_names.map { |key| [key, send(key)] }]
7
+ end
8
+ @attributes.dup
9
+ end
10
+
3
11
  # Read attribute from the attributes hash
4
12
  #
5
13
  def read_attribute(name)
@@ -15,13 +15,20 @@ require 'active_remote/rpc'
15
15
  require 'active_remote/scope_keys'
16
16
  require 'active_remote/search'
17
17
  require 'active_remote/serialization'
18
+ require 'active_remote/typecasting'
18
19
  require 'active_remote/validations'
19
20
 
20
21
  module ActiveRemote
21
22
  class Base
22
23
  extend ActiveModel::Callbacks
23
24
 
24
- include ActiveAttr::Model
25
+ include ActiveAttr::BasicModel
26
+ include ActiveAttr::BlockInitialization
27
+ include ActiveAttr::Logger
28
+ include ActiveAttr::MassAssignment
29
+ include ActiveAttr::AttributeDefaults
30
+ include ActiveAttr::QueryAttributes
31
+ include ActiveAttr::Serialization
25
32
 
26
33
  include Association
27
34
  include Attributes
@@ -35,6 +42,7 @@ module ActiveRemote
35
42
  include ScopeKeys
36
43
  include Search
37
44
  include Serialization
45
+ include Typecasting
38
46
 
39
47
  # Overrides some methods, providing support for dirty tracking,
40
48
  # so it needs to be included last.
@@ -49,7 +57,11 @@ module ActiveRemote
49
57
  define_model_callbacks :initialize, :only => :after
50
58
 
51
59
  def initialize(*)
52
- @attributes ||= {}
60
+ @attributes ||= begin
61
+ attribute_names = self.class.attribute_names
62
+ Hash[attribute_names.map { |key| [key, send(key)] }]
63
+ end
64
+
53
65
  @new_record = true
54
66
 
55
67
  skip_dirty_tracking do
@@ -1,24 +1,26 @@
1
+ require "active_remote/typecasting"
2
+
1
3
  module ActiveRemote
2
4
  module Serializers
3
5
  module Protobuf
4
6
  extend ActiveSupport::Concern
5
7
 
6
8
  TYPECASTER_MAP = {
7
- ::Protobuf::Field::BoolField => ActiveAttr::Typecasting::BooleanTypecaster,
8
- ::Protobuf::Field::BytesField => ActiveAttr::Typecasting::StringTypecaster,
9
- ::Protobuf::Field::DoubleField => ActiveAttr::Typecasting::FloatTypecaster,
10
- ::Protobuf::Field::Fixed32Field => ActiveAttr::Typecasting::IntegerTypecaster,
11
- ::Protobuf::Field::Fixed64Field => ActiveAttr::Typecasting::IntegerTypecaster,
12
- ::Protobuf::Field::FloatField => ActiveAttr::Typecasting::FloatTypecaster,
13
- ::Protobuf::Field::Int32Field => ActiveAttr::Typecasting::IntegerTypecaster,
14
- ::Protobuf::Field::Int64Field => ActiveAttr::Typecasting::IntegerTypecaster,
15
- ::Protobuf::Field::Sfixed32Field => ActiveAttr::Typecasting::IntegerTypecaster,
16
- ::Protobuf::Field::Sfixed64Field => ActiveAttr::Typecasting::IntegerTypecaster,
17
- ::Protobuf::Field::Sint32Field => ActiveAttr::Typecasting::IntegerTypecaster,
18
- ::Protobuf::Field::Sint64Field => ActiveAttr::Typecasting::IntegerTypecaster,
19
- ::Protobuf::Field::StringField => ActiveAttr::Typecasting::StringTypecaster,
20
- ::Protobuf::Field::Uint32Field => ActiveAttr::Typecasting::IntegerTypecaster,
21
- ::Protobuf::Field::Uint64Field => ActiveAttr::Typecasting::IntegerTypecaster
9
+ ::Protobuf::Field::BoolField => ActiveRemote::Typecasting::BooleanTypecaster,
10
+ ::Protobuf::Field::BytesField => ActiveRemote::Typecasting::StringTypecaster,
11
+ ::Protobuf::Field::DoubleField => ActiveRemote::Typecasting::FloatTypecaster,
12
+ ::Protobuf::Field::Fixed32Field => ActiveRemote::Typecasting::IntegerTypecaster,
13
+ ::Protobuf::Field::Fixed64Field => ActiveRemote::Typecasting::IntegerTypecaster,
14
+ ::Protobuf::Field::FloatField => ActiveRemote::Typecasting::FloatTypecaster,
15
+ ::Protobuf::Field::Int32Field => ActiveRemote::Typecasting::IntegerTypecaster,
16
+ ::Protobuf::Field::Int64Field => ActiveRemote::Typecasting::IntegerTypecaster,
17
+ ::Protobuf::Field::Sfixed32Field => ActiveRemote::Typecasting::IntegerTypecaster,
18
+ ::Protobuf::Field::Sfixed64Field => ActiveRemote::Typecasting::IntegerTypecaster,
19
+ ::Protobuf::Field::Sint32Field => ActiveRemote::Typecasting::IntegerTypecaster,
20
+ ::Protobuf::Field::Sint64Field => ActiveRemote::Typecasting::IntegerTypecaster,
21
+ ::Protobuf::Field::StringField => ActiveRemote::Typecasting::StringTypecaster,
22
+ ::Protobuf::Field::Uint32Field => ActiveRemote::Typecasting::IntegerTypecaster,
23
+ ::Protobuf::Field::Uint64Field => ActiveRemote::Typecasting::IntegerTypecaster
22
24
  }
23
25
 
24
26
  module ClassMethods
@@ -127,10 +129,7 @@ module ActiveRemote
127
129
  end
128
130
 
129
131
  def typecaster
130
- @typecaster ||= begin
131
- typecaster = TYPECASTER_MAP[field.type_class]
132
- typecaster.new if typecaster
133
- end
132
+ @typecaster ||= TYPECASTER_MAP[field.type_class]
134
133
  end
135
134
 
136
135
  def typecaster?
@@ -0,0 +1,60 @@
1
+ require "active_remote/typecasting/big_decimal_typecaster"
2
+ require "active_remote/typecasting/boolean"
3
+ require "active_remote/typecasting/boolean_typecaster"
4
+ require "active_remote/typecasting/date_time_typecaster"
5
+ require "active_remote/typecasting/date_typecaster"
6
+ require "active_remote/typecasting/float_typecaster"
7
+ require "active_remote/typecasting/integer_typecaster"
8
+ require "active_remote/typecasting/object_typecaster"
9
+ require "active_remote/typecasting/string_typecaster"
10
+
11
+ module ActiveRemote
12
+ module Typecasting
13
+ extend ActiveSupport::Concern
14
+
15
+ TYPECASTER_MAP = {
16
+ BigDecimal => ::ActiveRemote::Typecasting::BigDecimalTypecaster,
17
+ Boolean => ::ActiveRemote::Typecasting::BooleanTypecaster,
18
+ Date => ::ActiveRemote::Typecasting::DateTypecaster,
19
+ DateTime => ::ActiveRemote::Typecasting::DateTimeTypecaster,
20
+ Float => ::ActiveRemote::Typecasting::FloatTypecaster,
21
+ Integer => ::ActiveRemote::Typecasting::IntegerTypecaster,
22
+ Object => ::ActiveRemote::Typecasting::ObjectTypecaster,
23
+ String => ::ActiveRemote::Typecasting::StringTypecaster
24
+ }.freeze
25
+
26
+ private
27
+
28
+ def attribute=(name, value)
29
+ return super if value.nil?
30
+
31
+ typecaster = _attribute_typecaster(name)
32
+ return super unless typecaster
33
+
34
+ super(name, typecaster.call(value))
35
+ end
36
+
37
+ def _attribute_typecaster(attribute_name)
38
+ self.class.attributes[attribute_name][:typecaster] || _typecaster_for(attribute_name)
39
+ end
40
+
41
+ def _typecaster_for(attribute_name)
42
+ type = self.class.attributes[attribute_name][:type]
43
+ return nil unless type
44
+
45
+ TYPECASTER_MAP[type]
46
+ end
47
+
48
+ module ClassMethods
49
+ def inspect
50
+ inspected_attributes = attribute_names.sort.map { |name| "#{name}: #{_attribute_type(name)}" }
51
+ attributes_list = "(#{inspected_attributes.join(", ")})" unless inspected_attributes.empty?
52
+ "#{name}#{attributes_list}"
53
+ end
54
+
55
+ def _attribute_type(attribute_name)
56
+ attributes[attribute_name][:type] || Object
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,21 @@
1
+ require "bigdecimal"
2
+ require "bigdecimal/util"
3
+ require "active_support/core_ext/big_decimal/conversions"
4
+
5
+ module ActiveRemote
6
+ module Typecasting
7
+ class BigDecimalTypecaster
8
+ def self.call(value)
9
+ if value.is_a?(BigDecimal)
10
+ value
11
+ elsif value.is_a?(Rational)
12
+ value.to_f.to_d
13
+ elsif value.respond_to?(:to_d)
14
+ value.to_d
15
+ else
16
+ BigDecimal.new(value.to_s)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,7 @@
1
+ module ActiveRemote
2
+ module Typecasting
3
+ # For use in :type dsl option
4
+ class Boolean
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ module ActiveRemote
2
+ module Typecasting
3
+ class BooleanTypecaster
4
+ FALSE_VALUES = ["n", "N", "no", "No", "NO", "false", "False", "FALSE", "off", "Off", "OFF", "f", "F"]
5
+
6
+ def self.call(value)
7
+ case value
8
+ when *FALSE_VALUES then false
9
+ when Numeric, /^\-?[0-9]/ then !value.to_f.zero?
10
+ else value.present?
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ module ActiveRemote
2
+ module Typecasting
3
+ class DateTimeTypecaster
4
+ def self.call(value)
5
+ value.to_datetime if value.respond_to?(:to_datetime)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ module ActiveRemote
2
+ module Typecasting
3
+ class DateTypecaster
4
+ def self.call(value)
5
+ value.to_date if value.respond_to?(:to_date)
6
+ rescue NoMethodError, ArgumentError
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module ActiveRemote
2
+ module Typecasting
3
+ class FloatTypecaster
4
+ def self.call(value)
5
+ value.to_f if value.respond_to?(:to_f)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ module ActiveRemote
2
+ module Typecasting
3
+ class IntegerTypecaster
4
+ def self.call(value)
5
+ value.to_i if value.respond_to?(:to_i)
6
+ rescue FloatDomainError
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module ActiveRemote
2
+ module Typecasting
3
+ class ObjectTypecaster
4
+ def self.call(value)
5
+ value
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module ActiveRemote
2
+ module Typecasting
3
+ class StringTypecaster
4
+ def self.call(value)
5
+ value.to_s if value.respond_to?(:to_s)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  module ActiveRemote
2
- VERSION = "2.3.2"
2
+ VERSION = "2.3.3.pre"
3
3
  end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+ describe ::ActiveRemote::Typecasting do
3
+ let(:test_class) { ::TypecastedAuthor }
4
+
5
+ describe "boolean" do
6
+ it "casts to boolean" do
7
+ record = test_class.new(:writes_fiction => "no")
8
+ expect(record.writes_fiction).to eq(false)
9
+ end
10
+ end
11
+
12
+ describe "datetime" do
13
+ it "casts to datetime" do
14
+ record = test_class.new(:birthday => "2016-01-01")
15
+ expect(record.birthday).to eq(DateTime.parse("2016-01-01"))
16
+ end
17
+ end
18
+
19
+ describe "float" do
20
+ it "casts to float" do
21
+ record = test_class.new(:net_sales => "2000.20")
22
+ expect(record.net_sales).to eq(2000.2)
23
+ end
24
+ end
25
+
26
+ describe "integer" do
27
+ it "casts to integer" do
28
+ record = test_class.new(:age => "40")
29
+ expect(record.age).to eq(40)
30
+ end
31
+ end
32
+
33
+ describe "string" do
34
+ it "casts to string" do
35
+ record = test_class.new(:guid => 1000)
36
+ expect(record.guid).to eq("1000")
37
+ end
38
+ end
39
+ end
@@ -3,3 +3,4 @@ require 'support/models/author'
3
3
  require 'support/models/category'
4
4
  require 'support/models/post'
5
5
  require 'support/models/tag'
6
+ require 'support/models/typecasted_author'
@@ -0,0 +1,8 @@
1
+ class TypecastedAuthor < ::ActiveRemote::Base
2
+ attribute :guid, :type => String
3
+ attribute :name, :typecaster => StringTypecaster
4
+ attribute :age, :type => Integer
5
+ attribute :birthday, :type => DateTime
6
+ attribute :writes_fiction, :type => Boolean
7
+ attribute :net_sales, :type => Float
8
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_remote
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.2
4
+ version: 2.3.3.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Hutchison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-13 00:00:00.000000000 Z
11
+ date: 2016-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_attr
@@ -191,6 +191,16 @@ files:
191
191
  - lib/active_remote/serialization.rb
192
192
  - lib/active_remote/serializers/json.rb
193
193
  - lib/active_remote/serializers/protobuf.rb
194
+ - lib/active_remote/typecasting.rb
195
+ - lib/active_remote/typecasting/big_decimal_typecaster.rb
196
+ - lib/active_remote/typecasting/boolean.rb
197
+ - lib/active_remote/typecasting/boolean_typecaster.rb
198
+ - lib/active_remote/typecasting/date_time_typecaster.rb
199
+ - lib/active_remote/typecasting/date_typecaster.rb
200
+ - lib/active_remote/typecasting/float_typecaster.rb
201
+ - lib/active_remote/typecasting/integer_typecaster.rb
202
+ - lib/active_remote/typecasting/object_typecaster.rb
203
+ - lib/active_remote/typecasting/string_typecaster.rb
194
204
  - lib/active_remote/validations.rb
195
205
  - lib/active_remote/version.rb
196
206
  - spec/core_ext/date_time_spec.rb
@@ -209,6 +219,7 @@ files:
209
219
  - spec/lib/active_remote/serialization_spec.rb
210
220
  - spec/lib/active_remote/serializers/json_spec.rb
211
221
  - spec/lib/active_remote/serializers/protobuf_spec.rb
222
+ - spec/lib/active_remote/typecasting_spec.rb
212
223
  - spec/lib/active_remote/validations_spec.rb
213
224
  - spec/spec_helper.rb
214
225
  - spec/support/definitions/author.proto
@@ -224,6 +235,7 @@ files:
224
235
  - spec/support/models/message_with_options.rb
225
236
  - spec/support/models/post.rb
226
237
  - spec/support/models/tag.rb
238
+ - spec/support/models/typecasted_author.rb
227
239
  - spec/support/protobuf.rb
228
240
  - spec/support/protobuf/author.pb.rb
229
241
  - spec/support/protobuf/category.pb.rb
@@ -245,9 +257,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
245
257
  version: '0'
246
258
  required_rubygems_version: !ruby/object:Gem::Requirement
247
259
  requirements:
248
- - - ">="
260
+ - - ">"
249
261
  - !ruby/object:Gem::Version
250
- version: '0'
262
+ version: 1.3.1
251
263
  requirements: []
252
264
  rubyforge_project:
253
265
  rubygems_version: 2.5.1
@@ -271,6 +283,7 @@ test_files:
271
283
  - spec/lib/active_remote/serialization_spec.rb
272
284
  - spec/lib/active_remote/serializers/json_spec.rb
273
285
  - spec/lib/active_remote/serializers/protobuf_spec.rb
286
+ - spec/lib/active_remote/typecasting_spec.rb
274
287
  - spec/lib/active_remote/validations_spec.rb
275
288
  - spec/spec_helper.rb
276
289
  - spec/support/definitions/author.proto
@@ -286,6 +299,7 @@ test_files:
286
299
  - spec/support/models/message_with_options.rb
287
300
  - spec/support/models/post.rb
288
301
  - spec/support/models/tag.rb
302
+ - spec/support/models/typecasted_author.rb
289
303
  - spec/support/protobuf.rb
290
304
  - spec/support/protobuf/author.pb.rb
291
305
  - spec/support/protobuf/category.pb.rb