active_remote 3.3.3 → 5.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +28 -0
  3. data/CHANGES.md +13 -0
  4. data/Gemfile +1 -1
  5. data/Rakefile +7 -3
  6. data/active_remote.gemspec +8 -6
  7. data/lib/active_remote.rb +9 -8
  8. data/lib/active_remote/association.rb +12 -14
  9. data/lib/active_remote/attribute_definition.rb +14 -12
  10. data/lib/active_remote/attributes.rb +6 -6
  11. data/lib/active_remote/base.rb +20 -27
  12. data/lib/active_remote/config.rb +1 -1
  13. data/lib/active_remote/dirty.rb +3 -3
  14. data/lib/active_remote/dsl.rb +3 -4
  15. data/lib/active_remote/errors.rb +1 -11
  16. data/lib/active_remote/persistence.rb +11 -12
  17. data/lib/active_remote/primary_key.rb +0 -1
  18. data/lib/active_remote/query_attributes.rb +13 -13
  19. data/lib/active_remote/rpc.rb +8 -14
  20. data/lib/active_remote/rpc_adapters/protobuf_adapter.rb +18 -17
  21. data/lib/active_remote/scope_keys.rb +1 -2
  22. data/lib/active_remote/search.rb +8 -6
  23. data/lib/active_remote/serializers/protobuf.rb +15 -25
  24. data/lib/active_remote/validations.rb +1 -1
  25. data/lib/active_remote/version.rb +1 -1
  26. data/spec/lib/active_remote/association_spec.rb +23 -23
  27. data/spec/lib/active_remote/attributes_spec.rb +49 -3
  28. data/spec/lib/active_remote/base_spec.rb +1 -1
  29. data/spec/lib/active_remote/dirty_spec.rb +12 -12
  30. data/spec/lib/active_remote/dsl_spec.rb +4 -4
  31. data/spec/lib/active_remote/integration_spec.rb +2 -2
  32. data/spec/lib/active_remote/persistence_spec.rb +26 -33
  33. data/spec/lib/active_remote/primary_key_spec.rb +3 -3
  34. data/spec/lib/active_remote/query_attribute_spec.rb +0 -120
  35. data/spec/lib/active_remote/rpc_adapters/protobuf_adapter_spec.rb +1 -1
  36. data/spec/lib/active_remote/rpc_spec.rb +1 -1
  37. data/spec/lib/active_remote/scope_keys_spec.rb +7 -7
  38. data/spec/lib/active_remote/search_spec.rb +8 -8
  39. data/spec/lib/active_remote/serialization_spec.rb +4 -4
  40. data/spec/lib/active_remote/serializers/protobuf_spec.rb +23 -23
  41. data/spec/lib/active_remote/validations_spec.rb +17 -17
  42. data/spec/spec_helper.rb +9 -9
  43. data/spec/support/helpers.rb +6 -6
  44. data/spec/support/models.rb +8 -8
  45. data/spec/support/models/author.rb +1 -1
  46. data/spec/support/models/category.rb +1 -2
  47. data/spec/support/models/default_author.rb +1 -1
  48. data/spec/support/models/post.rb +4 -4
  49. data/spec/support/models/tag.rb +1 -1
  50. data/spec/support/models/typecasted_author.rb +4 -5
  51. data/spec/support/protobuf.rb +5 -5
  52. metadata +24 -26
  53. data/lib/active_remote/attribute_assignment.rb +0 -53
  54. data/lib/active_remote/type.rb +0 -36
  55. data/lib/active_remote/type/registry.rb +0 -45
  56. data/lib/active_remote/typecasting.rb +0 -51
  57. data/lib/active_remote/typecasting/big_decimal_typecaster.rb +0 -21
  58. data/lib/active_remote/typecasting/boolean.rb +0 -7
  59. data/lib/active_remote/typecasting/boolean_typecaster.rb +0 -18
  60. data/lib/active_remote/typecasting/date_time_typecaster.rb +0 -10
  61. data/lib/active_remote/typecasting/date_typecaster.rb +0 -10
  62. data/lib/active_remote/typecasting/float_typecaster.rb +0 -9
  63. data/lib/active_remote/typecasting/integer_typecaster.rb +0 -10
  64. data/lib/active_remote/typecasting/object_typecaster.rb +0 -9
  65. data/lib/active_remote/typecasting/string_typecaster.rb +0 -9
  66. data/spec/lib/active_remote/errors_spec.rb +0 -31
  67. data/spec/lib/active_remote/typecasting_spec.rb +0 -53
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14b8e2f3b79e43639dcdcb56f75b99674bcd1cb79100e01e79b5b1e5aa4f8494
4
- data.tar.gz: bd0726676290ec68c5f7de7bb0aa5a1d39553bb88c72075f7e9879b31aeb99eb
3
+ metadata.gz: 20c9373eff2820fdfaeb4eefd815a1d4cfb752e9fd388e8fd0e2d4ef2c0c5f7f
4
+ data.tar.gz: 5f66d51af2723950bad69d3870fc83685e253f5fcfd894d6ae19dd6a78c27516
5
5
  SHA512:
6
- metadata.gz: 206c1006067983f39a3944ff67a25dcd7f269f5353e19b3b0e67c3b6aa2b897f52407132e0bfcae6917da9e9b9c041fe17f081a2ae4c05d5f21558ce8ff42daa
7
- data.tar.gz: 00fc6a154121e46f47b7bf57bbc8b51ccee44166189cb289f383a4cd038909792dbe470db7062decf37cb50f4a9b7bb98a47a36ad48c2827709241e01b3d1a0e
6
+ metadata.gz: 07d671953169e1eefc9db8b26d2de3af40a39302e1423fdd7beeb212df913c46db1017aeb2dbc2d02c21cf72f0ae35639732d6af86694f0ecd7be894ae03db04
7
+ data.tar.gz: 98ee4213dcd636baab1def67ba1848469ff8592aff9334b720348830e4fd797f65e2935450fe399fafdc84261a64f2a07197323d38b743c616d4b70475f7890f
data/.rubocop.yml ADDED
@@ -0,0 +1,28 @@
1
+ # Styles are inherited from Mad Rubocop
2
+
3
+ inherit_gem:
4
+ mad_rubocop: .rubocop.yml
5
+
6
+ # Styles that are modified from the defaults
7
+ AllCops:
8
+ TargetRubyVersion: 2.5
9
+ Exclude:
10
+ - "**/*.pb.rb"
11
+
12
+ Style/BlockDelimiters:
13
+ Description: >-
14
+ Avoid using {...} for multi-line blocks (multiline chaining is always ugly).
15
+ Prefer {...} over do...end for single-line blocks.
16
+ Exclude:
17
+ - "spec/**/*"
18
+
19
+ Style/HashSyntax:
20
+ Description: >-
21
+ Prefer Ruby 1.8 hash syntax { :a => 1, :b => 2 } over 1.9 syntax { a: 1, b: 2 }.
22
+ EnforcedStyle: hash_rockets
23
+ Exclude:
24
+ - "Gemfile"
25
+
26
+ Layout/SpaceAroundOperators:
27
+ Exclude:
28
+ - "*.gemspec"
data/CHANGES.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # ActiveRemote Changes
2
2
 
3
+ 5.0.0
4
+ ----------
5
+
6
+ - Use Active Model attributes [#72]
7
+ - Use type casting from Active Model (custom types must be registered) [#71]
8
+ - Use query attributes from Active Record (string values such as 'FALSE', and '0' are now considered present) [#71]
9
+ - Drop support for Rails 4.2 (versions will match Rails version moving forward) [#71]
10
+
11
+ 3.3.1
12
+ ----------
13
+
14
+ - Fix unknown type error in Protobuf serializer [#70]
15
+
3
16
  3.3.0
4
17
  ----------
5
18
 
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in active_remote.gemspec
4
4
  gemspec
data/Rakefile CHANGED
@@ -2,12 +2,16 @@
2
2
  require "bundler/gem_tasks"
3
3
  require "protobuf/tasks"
4
4
  require "rspec/core/rake_task"
5
+ require "rubocop/rake_task"
6
+
7
+ desc "Run cops"
8
+ ::RuboCop::RakeTask.new(:rubocop)
5
9
 
6
10
  desc "Run specs"
7
- RSpec::Core::RakeTask.new(:spec)
11
+ ::RSpec::Core::RakeTask.new(:spec)
8
12
 
9
- desc "Run specs (default)"
10
- task :default, [] => :spec
13
+ desc "Run cops and specs (default)"
14
+ task :default => [:rubocop, :spec]
11
15
 
12
16
  desc "Remove protobuf definitions that have been compiled"
13
17
  task :clean do
@@ -1,5 +1,6 @@
1
1
  # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ $LOAD_PATH.push File.expand_path("../lib", __FILE__)
3
4
  require "active_remote/version"
4
5
 
5
6
  Gem::Specification.new do |s|
@@ -8,19 +9,19 @@ Gem::Specification.new do |s|
8
9
  s.authors = ["Adam Hutchison"]
9
10
  s.email = ["liveh2o@gmail.com"]
10
11
  s.homepage = "https://github.com/liveh2o/active_remote"
11
- s.summary = %q{Active Record for your platform}
12
- s.description = %q{Active Remote provides Active Record-like object-relational mapping over RPC. It was written for use with Google Protocol Buffers, but could be extended to use any RPC data format.}
12
+ s.summary = "Active Record for your platform"
13
+ s.description = "Active Remote provides Active Record-like object-relational mapping over RPC. It was written for use with Google Protocol Buffers, but could be extended to use any RPC data format."
13
14
 
14
15
  s.files = `git ls-files`.split("\n")
15
16
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
17
18
  s.require_paths = ["lib"]
18
19
 
19
20
  ##
20
21
  # Dependencies
21
22
  #
22
- s.add_dependency "activemodel", ">= 4.0", "< 5.2"
23
- s.add_dependency "activesupport", ">= 4.0"
23
+ s.add_dependency "activemodel", ">= 5.0", "< 5.2"
24
+ s.add_dependency "activesupport", ">= 5.0"
24
25
  s.add_dependency "protobuf", ">= 3.0"
25
26
 
26
27
  ##
@@ -30,6 +31,7 @@ Gem::Specification.new do |s|
30
31
  s.add_development_dependency "rspec", ">= 3.3.0"
31
32
  s.add_development_dependency "rspec-its"
32
33
  s.add_development_dependency "rspec-pride", ">= 3.1.0"
34
+ s.add_development_dependency "mad_rubocop"
33
35
  s.add_development_dependency "pry"
34
36
  s.add_development_dependency "protobuf-rspec", ">= 1.1.2"
35
37
  s.add_development_dependency "simplecov"
data/lib/active_remote.rb CHANGED
@@ -1,11 +1,12 @@
1
- require 'active_model'
2
- require 'active_support'
3
- require 'protobuf'
1
+ require "active_model"
2
+ require "active_support"
3
+ require "active_support/core_ext"
4
+ require "protobuf"
4
5
 
5
- require 'active_remote/base'
6
- require 'active_remote/config'
7
- require 'active_remote/errors'
8
- require 'active_remote/version'
6
+ require "active_remote/base"
7
+ require "active_remote/config"
8
+ require "active_remote/errors"
9
+ require "active_remote/version"
9
10
 
10
11
  module ActiveRemote
11
12
  def self.config
@@ -16,4 +17,4 @@ module ActiveRemote
16
17
  config
17
18
  end
18
19
 
19
- require 'active_remote/railtie' if defined?(Rails)
20
+ require "active_remote/railtie" if defined?(Rails)
@@ -33,12 +33,12 @@ module ActiveRemote
33
33
  # end
34
34
  # end
35
35
  #
36
- def belongs_to(belongs_to_klass, options={})
36
+ def belongs_to(belongs_to_klass, options = {})
37
37
  perform_association(belongs_to_klass, options) do |klass, object|
38
38
  foreign_key = options.fetch(:foreign_key) { :"#{klass.name.demodulize.underscore}_guid" }
39
39
  search_hash = {}
40
40
  search_hash[:guid] = object.read_attribute(foreign_key)
41
- search_hash[options[:scope]] = object.read_attribute(options[:scope]) if options.has_key?(:scope)
41
+ search_hash[options[:scope]] = object.read_attribute(options[:scope]) if options.key?(:scope)
42
42
 
43
43
  search_hash.values.any?(&:nil?) ? nil : klass.search(search_hash).first
44
44
  end
@@ -74,17 +74,17 @@ module ActiveRemote
74
74
  # end
75
75
  # end
76
76
  #
77
- def has_many(has_many_class, options={})
77
+ def has_many(has_many_class, options = {})
78
78
  perform_association(has_many_class, options) do |klass, object|
79
79
  foreign_key = options.fetch(:foreign_key) { :"#{object.class.name.demodulize.underscore}_guid" }
80
80
  search_hash = {}
81
81
  search_hash[foreign_key] = object.guid
82
- search_hash[options[:scope]] = object.read_attribute(options[:scope]) if options.has_key?(:scope)
82
+ search_hash[options[:scope]] = object.read_attribute(options[:scope]) if options.key?(:scope)
83
83
 
84
84
  search_hash.values.any?(&:nil?) ? [] : klass.search(search_hash)
85
85
  end
86
86
 
87
- options.merge!(:has_many => true)
87
+ options[:has_many] = true
88
88
  create_setter_method(has_many_class, options)
89
89
  end
90
90
 
@@ -115,12 +115,12 @@ module ActiveRemote
115
115
  # end
116
116
  # end
117
117
  #
118
- def has_one(has_one_klass, options={})
118
+ def has_one(has_one_klass, options = {})
119
119
  perform_association(has_one_klass, options) do |klass, object|
120
120
  foreign_key = options.fetch(:foreign_key) { :"#{object.class.name.demodulize.underscore}_guid" }
121
121
  search_hash = {}
122
122
  search_hash[foreign_key] = object.guid
123
- search_hash[options[:scope]] = object.read_attribute(options[:scope]) if options.has_key?(:scope)
123
+ search_hash[options[:scope]] = object.read_attribute(options[:scope]) if options.key?(:scope)
124
124
 
125
125
  search_hash.values.any?(&:nil?) ? nil : klass.search(search_hash).first
126
126
  end
@@ -135,29 +135,27 @@ module ActiveRemote
135
135
 
136
136
  private
137
137
 
138
- def create_setter_method(associated_klass, options={})
138
+ def create_setter_method(associated_klass, options = {})
139
139
  writer_method = "#{associated_klass}=".to_sym
140
140
  define_method(writer_method) do |new_value|
141
141
  raise "New value must be an array" if options[:has_many] == true && new_value.class != Array
142
- klass_name = options.fetch(:class_name){ associated_klass }
143
- klass = klass_name.to_s.classify.constantize
144
142
 
145
143
  instance_variable_set(:"@#{new_value.class.name.demodulize.underscore}", new_value)
146
144
  new_value
147
145
  end
148
146
  end
149
147
 
150
- def perform_association(associated_klass, options={})
148
+ def perform_association(associated_klass, options = {})
151
149
  define_method(associated_klass) do
152
- klass_name = options.fetch(:class_name){ associated_klass }
150
+ klass_name = options.fetch(:class_name) { associated_klass }
153
151
  klass = klass_name.to_s.classify.constantize
154
152
 
155
- self.class.validate_scoped_attributes(klass, self.class, options) if options.has_key?(:scope)
153
+ self.class.validate_scoped_attributes(klass, self.class, options) if options.key?(:scope)
156
154
 
157
155
  value = instance_variable_get(:"@#{associated_klass}")
158
156
 
159
157
  unless value
160
- value = yield( klass, self )
158
+ value = yield(klass, self)
161
159
  instance_variable_set(:"@#{associated_klass}", value)
162
160
  end
163
161
 
@@ -1,4 +1,4 @@
1
- require "active_remote/type"
1
+ require "active_model/type"
2
2
 
3
3
  module ActiveRemote
4
4
  # Represents an attribute for reflection
@@ -55,17 +55,19 @@ module ActiveRemote
55
55
  # @return [ActiveAttr::AttributeDefinition]
56
56
  #
57
57
  # @since 0.2.0
58
- def initialize(name, type = :unknown, **options)
58
+ def initialize(name, type = :value, **options)
59
59
  raise TypeError, "can't convert #{name.class} into Symbol" unless name.respond_to? :to_sym
60
60
  @name = name.to_sym
61
+ @type = ::ActiveModel::Type.lookup(type)
61
62
  @options = options
62
- @options[:typecaster] = ::ActiveRemote::Type.lookup(type) unless type == :unknown
63
+ end
64
+
65
+ def from_rpc(value)
66
+ type.deserialize(value)
67
+ end
63
68
 
64
- if @options[:type]
65
- typecaster = ::ActiveRemote::Typecasting::TYPECASTER_MAP[@options[:type]]
66
- fail ::ActiveRemote::UnknownType unless typecaster
67
- @options[:typecaster] = typecaster
68
- end
69
+ def from_user(value)
70
+ type.cast(value)
69
71
  end
70
72
 
71
73
  # Returns the code that would generate the attribute definition
@@ -88,9 +90,7 @@ module ActiveRemote
88
90
  # @return [String] the attribute name
89
91
  #
90
92
  # @since 0.2.0
91
- def to_s
92
- name.to_s
93
- end
93
+ delegate :to_s, :to => :name
94
94
 
95
95
  # The attribute name
96
96
  #
@@ -101,10 +101,12 @@ module ActiveRemote
101
101
  name
102
102
  end
103
103
 
104
- protected
104
+ protected
105
105
 
106
106
  # The attribute options
107
107
  # @since 0.5.0
108
108
  attr_reader :options, :type
109
109
  end
110
+
111
+ ::ActiveModel::Type.register(:value, ::ActiveModel::Type::Value)
110
112
  end
@@ -68,7 +68,7 @@ module ActiveRemote
68
68
  # Write an attribute to the attributes hash
69
69
  #
70
70
  def attribute=(name, value)
71
- @attributes[name] = value
71
+ @attributes[name] = self.class.attributes[name].from_user(value)
72
72
  end
73
73
 
74
74
  def attribute_method?(attr_name)
@@ -88,9 +88,9 @@ module ActiveRemote
88
88
  # @example Define an attribute.
89
89
  # attribute :name
90
90
  #
91
- def attribute(name, options={})
92
- if dangerous_attribute_method_name = dangerous_attribute?(name)
93
- raise ::ActiveRemote::DangerousAttributeError, %{an attribute method named "#{dangerous_attribute_method_name}" would conflict with an existing method}
91
+ def attribute(name, options = {})
92
+ if (dangerous_attribute_method_name = dangerous_attribute?(name))
93
+ raise ::ActiveRemote::DangerousAttributeError, %(an attribute method named "#{dangerous_attribute_method_name}" would conflict with an existing method)
94
94
  else
95
95
  attribute!(name, options)
96
96
  end
@@ -107,7 +107,7 @@ module ActiveRemote
107
107
  # @example Define a dangerous attribute.
108
108
  # attribute! :timeout
109
109
  #
110
- def attribute!(name, options={})
110
+ def attribute!(name, options = {})
111
111
  ::ActiveRemote::AttributeDefinition.new(name, options).tap do |attribute_definition|
112
112
  attribute_name = attribute_definition.name.to_s
113
113
  # Force active model to generate attribute methods
@@ -164,7 +164,7 @@ module ActiveRemote
164
164
  #
165
165
  def inspect
166
166
  inspected_attributes = attribute_names.sort
167
- attributes_list = "(#{inspected_attributes.join(", ")})" unless inspected_attributes.empty?
167
+ attributes_list = "(#{inspected_attributes.join(', ')})" unless inspected_attributes.empty?
168
168
  "#{name}#{attributes_list}"
169
169
  end
170
170
 
@@ -1,33 +1,28 @@
1
- require 'active_model/callbacks'
2
-
3
- require 'active_remote/association'
4
- require 'active_remote/attribute_assignment'
5
- require 'active_remote/attribute_definition'
6
- require 'active_remote/attributes'
7
- require 'active_remote/config'
8
- require 'active_remote/dirty'
9
- require 'active_remote/dsl'
10
- require 'active_remote/integration'
11
- require 'active_remote/persistence'
12
- require 'active_remote/primary_key'
13
- require 'active_remote/query_attributes'
14
- require 'active_remote/rpc'
15
- require 'active_remote/scope_keys'
16
- require 'active_remote/search'
17
- require 'active_remote/serialization'
18
- require 'active_remote/typecasting'
19
- require 'active_remote/validations'
1
+ require "active_model/callbacks"
2
+
3
+ require "active_remote/association"
4
+ require "active_remote/attribute_definition"
5
+ require "active_remote/attributes"
6
+ require "active_remote/config"
7
+ require "active_remote/dirty"
8
+ require "active_remote/dsl"
9
+ require "active_remote/integration"
10
+ require "active_remote/persistence"
11
+ require "active_remote/primary_key"
12
+ require "active_remote/query_attributes"
13
+ require "active_remote/rpc"
14
+ require "active_remote/scope_keys"
15
+ require "active_remote/search"
16
+ require "active_remote/serialization"
17
+ require "active_remote/validations"
20
18
 
21
19
  module ActiveRemote
22
20
  class Base
23
21
  extend ::ActiveModel::Callbacks
24
- extend ::ActiveModel::Naming
25
22
 
26
- include ::ActiveModel::Conversion
27
- include ::ActiveModel::Validations
23
+ include ::ActiveModel::Model
28
24
 
29
25
  include ::ActiveRemote::Association
30
- include ::ActiveRemote::AttributeAssignment
31
26
  include ::ActiveRemote::Attributes
32
27
  include ::ActiveRemote::DSL
33
28
  include ::ActiveRemote::Integration
@@ -38,7 +33,6 @@ module ActiveRemote
38
33
  include ::ActiveRemote::ScopeKeys
39
34
  include ::ActiveRemote::Search
40
35
  include ::ActiveRemote::Serialization
41
- include ::ActiveRemote::Typecasting
42
36
 
43
37
  # Overrides some methods, providing support for dirty tracking,
44
38
  # so it needs to be included last.
@@ -48,8 +42,6 @@ module ActiveRemote
48
42
  include ::ActiveRemote::Validations
49
43
  include ::ActiveModel::Validations::Callbacks
50
44
 
51
- attr_reader :last_request, :last_response
52
-
53
45
  define_model_callbacks :initialize, :only => :after
54
46
 
55
47
  def initialize(attributes = {})
@@ -78,7 +70,8 @@ module ActiveRemote
78
70
  end
79
71
 
80
72
  def freeze
81
- @attributes.freeze; self
73
+ @attributes.freeze
74
+ self
82
75
  end
83
76
 
84
77
  def frozen?
@@ -1,4 +1,4 @@
1
- require 'active_support/ordered_options'
1
+ require "active_support/ordered_options"
2
2
 
3
3
  module ActiveRemote
4
4
  class Config < ::ActiveSupport::OrderedOptions
@@ -1,4 +1,4 @@
1
- require 'active_model/dirty'
1
+ require "active_model/dirty"
2
2
 
3
3
  # Overrides persistence methods, providing support for dirty tracking.
4
4
  #
@@ -32,7 +32,7 @@ module ActiveRemote
32
32
  # Override #save to store changes as previous changes then clear them.
33
33
  #
34
34
  def save(*)
35
- if status = super
35
+ if (status = super)
36
36
  @previously_changed = changes
37
37
  changed_attributes.clear
38
38
  end
@@ -49,7 +49,7 @@ module ActiveRemote
49
49
  end
50
50
  end
51
51
 
52
- def skip_dirty_tracking(&block)
52
+ def skip_dirty_tracking
53
53
  disable_dirty_tracking
54
54
 
55
55
  yield