protip 0.18.2 → 0.18.3
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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b3cc36d1a0119a9d6a0c7aa985ef1c7ec9d0c80
|
4
|
+
data.tar.gz: 1172ca37789032767087b77783d8f274bac71e6e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 50fc9db60514ea58304d94e2b16ba3c9d565a748b9163ea0f1ef676a9d85c7d2b04355c9a3a92df812fb778d599b6631be9c8da79f1a2a9e0bcc082ca872c2ff
|
7
|
+
data.tar.gz: 1f3adf1b6aab2af7a433d9ab3257f584ea8fbaadf8126578b44248d83733bdfdb331ce508bab4c4ff748c45bd4cdc16c3bbc37c2810789308d2cd51cb9e4fb13
|
data/lib/protip/resource.rb
CHANGED
@@ -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 [
|
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,
|
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
|
-
@
|
32
|
-
raise "Invalid field name for polymorphic association: #{@id_field}" unless @
|
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
|
-
@
|
36
|
-
|
37
|
-
if @
|
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
|
-
@
|
41
|
+
@_indexed_belongs_to_associations[association.id_field.to_sym] = association
|
41
42
|
end
|
42
|
-
field_names = @
|
43
|
-
unless (field_names.length == @
|
44
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
|
69
|
-
value.is_a?
|
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
|
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
|
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
|
-
|
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.
|
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-
|
11
|
+
date: 2016-02-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|