active_remote 2.3.2 → 2.3.3.pre

Sign up to get free protection for your applications and to get access to all the features.
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