protip 0.18.2 → 0.18.3

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: b37a5ba7e9e56a626b357a5ccc3ffc7f476e4df4
4
- data.tar.gz: 45f60bb6fdfe7e6d2119ef418313d614b02fc554
3
+ metadata.gz: 8b3cc36d1a0119a9d6a0c7aa985ef1c7ec9d0c80
4
+ data.tar.gz: 1172ca37789032767087b77783d8f274bac71e6e
5
5
  SHA512:
6
- metadata.gz: 84348345f6f1a671badc27cacaf9a310f3bfaa10c86b8697d25c33b5b1de0278552736962b2070579ab2185a08805437bcaf6c3c4cb2bd6f4a0f1c57d5d1e2e9
7
- data.tar.gz: d010f3a673368d5b941be895465b359db1335bb5d077995dea3935e9c1bf6c6f25cdc64348364ff09d9bdd335559e149a762ad256d6ab34da6b3e030b404d1bd
6
+ metadata.gz: 50fc9db60514ea58304d94e2b16ba3c9d565a748b9163ea0f1ef676a9d85c7d2b04355c9a3a92df812fb778d599b6631be9c8da79f1a2a9e0bcc082ca872c2ff
7
+ data.tar.gz: 1f3adf1b6aab2af7a433d9ab3257f584ea8fbaadf8126578b44248d83733bdfdb331ce508bab4c4ff748c45bd4cdc16c3bbc37c2810789308d2cd51cb9e4fb13
@@ -50,6 +50,10 @@ module Protip
50
50
 
51
51
  def_delegator :@wrapper, :message
52
52
  def_delegator :@wrapper, :as_json
53
+
54
+ # Initialize housekeeping variables
55
+ @belongs_to_associations = Set.new
56
+ @belongs_to_polymorphic_associations = Set.new
53
57
  end
54
58
 
55
59
  module ClassMethods
@@ -58,7 +62,7 @@ module Protip
58
62
 
59
63
  attr_accessor :client
60
64
 
61
- attr_reader :message, :nested_resources
65
+ attr_reader :message, :nested_resources, :belongs_to_associations, :belongs_to_polymorphic_associations
62
66
 
63
67
  attr_writer :base_path, :converter
64
68
 
@@ -210,6 +214,7 @@ module Protip
210
214
  def belongs_to(association_name, options = {})
211
215
  association = ::Protip::Resource::Associations::BelongsToAssociation.new(self, association_name, options)
212
216
  association.define_accessors!
217
+ @belongs_to_associations.add association
213
218
  association
214
219
  end
215
220
 
@@ -233,6 +238,7 @@ module Protip
233
238
  association = ::Protip::Resource::Associations::BelongsToPolymorphicAssociation.new self,
234
239
  association_name, nested_association_creator.associations, options
235
240
  association.define_accessors!
241
+ @belongs_to_polymorphic_associations.add association
236
242
  association
237
243
  end
238
244
 
@@ -7,18 +7,18 @@ module Protip
7
7
  class BelongsToPolymorphicAssociation
8
8
 
9
9
  include Protip::Resource::Associations::Association
10
- attr_reader :resource_class, :association_name, :id_field
10
+ attr_reader :resource_class, :association_name, :id_field, :belongs_to_associations
11
11
 
12
12
  # Define a polymorphic association based on a one-of field. The options for the oneof must all be IDs with
13
13
  # an associated +Protip::Resource::Associations::BelongsToAssociation+ that's already been created.
14
14
  #
15
15
  # @param [Class] resource_class The +Protip::Resource+ class that holds a reference to an associated object.
16
16
  # @param [String] association_name The name to use when defining accessors for the associated object.
17
- # @param [Array<Protip::Resource::Associations::BelongsToAssociation>] nested_associations The individual
18
- # associations corresponding to the fields within the `oneof`.
17
+ # @param [Enumerable<Protip::Resource::Associations::BelongsToAssociation>] belongs_to_associations The
18
+ # individual associations corresponding to the fields within the `oneof`.
19
19
  # @param [Symbol|String] id_field The name of the `oneof` field that holds the association ID. Defaults to
20
20
  # `#{association_name}_id`.
21
- def initialize(resource_class, association_name, nested_associations, id_field: nil)
21
+ def initialize(resource_class, association_name, belongs_to_associations, id_field: nil)
22
22
  # The class where accessors will be defined
23
23
  @resource_class = resource_class
24
24
 
@@ -28,30 +28,32 @@ module Protip
28
28
  # The oneof field that holds the ID of the foreign resource
29
29
  @id_field = (id_field ||
30
30
  Protip::Resource::Associations::BelongsToAssociation.default_id_field(association_name)).to_sym
31
- @oneof = @resource_class.message.descriptor.lookup_oneof(@id_field.to_s)
32
- raise "Invalid field name for polymorphic association: #{@id_field}" unless @oneof
31
+ @_oneof = @resource_class.message.descriptor.lookup_oneof(@id_field.to_s)
32
+ raise "Invalid field name for polymorphic association: #{@id_field}" unless @_oneof
33
+
33
34
 
34
35
  # Internally, keep the nested associations indexed by ID field
35
- @_nested_associations = {}
36
- nested_associations.each do |association|
37
- if @_nested_associations.has_key? association.id_field.to_sym
36
+ @_indexed_belongs_to_associations = {}
37
+ belongs_to_associations.each do |association|
38
+ if @_indexed_belongs_to_associations.has_key? association.id_field.to_sym
38
39
  raise ArgumentError.new("Duplicate association for #{id_field}")
39
40
  end
40
- @_nested_associations[association.id_field.to_sym] = association
41
+ @_indexed_belongs_to_associations[association.id_field.to_sym] = association
41
42
  end
42
- field_names = @oneof.map{|desc| desc.name.to_sym}
43
- unless (field_names.length == @_nested_associations.length &&
44
- @_nested_associations.keys.all?{|id_field| field_names.include? id_field})
43
+ field_names = @_oneof.map{|desc| desc.name.to_sym}
44
+ unless (field_names.length == @_indexed_belongs_to_associations.length &&
45
+ @_indexed_belongs_to_associations.keys.all?{|id_field| field_names.include? id_field})
45
46
  raise ArgumentError.new(
46
47
  'Polymorphic association requires an association to be defined for all nested fields'
47
48
  )
48
49
  end
50
+ @belongs_to_associations = Set.new(belongs_to_associations)
49
51
  end
50
52
 
51
53
  def read(resource)
52
54
  field = resource.message.public_send(id_field)
53
55
  if field
54
- @_nested_associations[field].read(resource)
56
+ @_indexed_belongs_to_associations[field].read(resource)
55
57
  else
56
58
  nil
57
59
  end
@@ -59,28 +61,28 @@ module Protip
59
61
 
60
62
  def write(resource, value)
61
63
  if value == nil
62
- @oneof.each do |field_descriptor|
64
+ @_oneof.each do |field_descriptor|
63
65
  resource.public_send(:"#{field_descriptor.name}=", nil)
64
66
  end
65
67
  nil
66
68
  else
67
69
  # Find the nested reference matching this association type
68
- matching_references = @_nested_associations.select do |id_field, reference|
69
- value.is_a? reference.associated_resource_class
70
+ matching_associations = belongs_to_associations.select do |association|
71
+ value.is_a? association.associated_resource_class
70
72
  end
71
73
 
72
74
  # Make sure we found exactly one
73
- if matching_references.empty?
75
+ if matching_associations.empty?
74
76
  raise ArgumentError.new("Could not find matching reference for value of type #{value.class}")
75
77
  end
76
- if matching_references.length > 1
78
+ if matching_associations.length > 1
77
79
  raise ArgumentError.new(
78
80
  "Value of type #{value.class} matched with #{matching_references.keys.map(&:to_s).join(', ')}"
79
81
  )
80
82
  end
81
83
 
82
84
  # And forward the write operation
83
- matching_references.values.first.write(resource, value)
85
+ matching_associations.first.write(resource, value)
84
86
  end
85
87
  end
86
88
  end
@@ -70,6 +70,14 @@ describe Protip::Resource::Associations::BelongsToPolymorphicAssociation do
70
70
  :foo, [rick_ross_association, fetty_wap_association], id_field: :reference_id
71
71
  assert_equal :reference_id, association.id_field
72
72
  end
73
+
74
+ it 'stores the nested belongs-to associations' do
75
+ association = Protip::Resource::Associations::BelongsToPolymorphicAssociation.new resource_class,
76
+ :reference, [rick_ross_association, fetty_wap_association]
77
+ assert_equal 2, association.belongs_to_associations.length
78
+ assert_includes association.belongs_to_associations, rick_ross_association
79
+ assert_includes association.belongs_to_associations, fetty_wap_association
80
+ end
73
81
  end
74
82
 
75
83
  describe '(accessors)' do
@@ -882,6 +882,18 @@ module Protip::ResourceTest # Namespace for internal constants
882
882
  assert_equal association, resource_class.instance_variable_get(:'@result'), 'association was not returned'
883
883
  end
884
884
 
885
+ it 'stores the created association' do
886
+ association_class.expects(:new).once.returns(association)
887
+ resource_class.class_exec(method) { |method| send method, :association_name, &block }
888
+ assert_includes resource_class.public_send(:"#{method}_associations"), association
889
+ end
890
+
891
+ it 'initializes the set of associations to the empty set' do
892
+ stored_associations = resource_class.public_send(:"#{method}_associations")
893
+ assert_instance_of Set, stored_associations
894
+ assert_empty stored_associations
895
+ end
896
+
885
897
  it 'raises an error on invalid options' do
886
898
  error = assert_raises ArgumentError do
887
899
  resource_class.class_exec(method) do |method|
@@ -935,31 +947,6 @@ module Protip::ResourceTest # Namespace for internal constants
935
947
  Protip::Resource::Associations::BelongsToPolymorphicAssociation) { }
936
948
  end
937
949
 
938
- # {
939
- # references_through_one_of: Protip::Resource::Associations::ReferencesThroughOneOfAssociation,
940
- # }.each do |method, association_class|
941
- # describe ".#{method}" do
942
- # it 'creates an association of the correct type and defines accessors' do
943
- # association = mock.responds_like_instance_of(association_class)
944
- # association_class.expects(:new).once.with(resource_class, :some_id, {class_name: 'Foo'}).returns(association)
945
- # association.expects(:define_accessors!)
946
- # resource_class.class_exec(method) do
947
- # send(method, :some_id, class_name: 'Foo')
948
- # end
949
- # end
950
- #
951
- # it 'raises an error on invalid options' do
952
- # error = assert_raises ArgumentError do
953
- # resource_class.class_exec(method) do
954
- # send(method, :some_id, bad_option: 'bad')
955
- # end
956
- # end
957
- #
958
- # assert_match /bad_option/, error.message
959
- # end
960
- # end
961
- # end
962
-
963
950
  describe '.converter' do
964
951
  describe 'default value' do
965
952
  it 'defaults to the standard converter' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protip
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.2
4
+ version: 0.18.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - AngelList
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-09 00:00:00.000000000 Z
11
+ date: 2016-02-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel