odata 0.5.0 → 0.5.1

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: 44a27c048ec4706996d0eccc9aff655a5c60be94
4
- data.tar.gz: de691ae9f3cb75ab544642f9826521cfc3bb09e5
3
+ metadata.gz: 0168d51fbc598d14a4ad183bf905476b1c7e0c33
4
+ data.tar.gz: 2b1678db31c28a5bd4122753d43153f9d83ac6a7
5
5
  SHA512:
6
- metadata.gz: cdaae668ecb311bbb45f7abd54b116c9576d6c158c86968379405890aafad70bd14b0deda585c8f7e0cdbe9cb50e258d2590ccec2e3f78561ea851e58cc7a096
7
- data.tar.gz: 84222c7cf63702ccc0f6073962a3ce3317cfb32507560dc49ada9c6ac6fb676cf66061a264fba8fa72849638448739d03c2a47bccdd684097499e1cf473a3cc2
6
+ metadata.gz: 315c0846a3e364a234fa63595618d89e8a6d340d0046440c815ba9153ec7db419136443027203ae6d307ba82883d089af0fcb02379c1c33010b53f21979f3251
7
+ data.tar.gz: 53b3c627ab42f413d264c23aa8dfea0f64e559e87c0cd747ceba9e786de2c0f537836c6fdf528d27bcc6fd1cdfa32c4746350c681a22daed1664f3dfcfa63cd6
data/lib/odata.rb CHANGED
@@ -11,6 +11,7 @@ require 'typhoeus'
11
11
  require 'odata/version'
12
12
  require 'odata/property'
13
13
  require 'odata/properties'
14
+ require 'odata/complex_type'
14
15
  require 'odata/entity'
15
16
  require 'odata/entity_set'
16
17
  require 'odata/query/criteria'
@@ -0,0 +1,67 @@
1
+ module OData
2
+ # ComplexTypes are used in OData to either encapsulate richer data types for
3
+ # use as Entity properties. ComplexTypes are composed of properties the same
4
+ # way that Entities are and, so, the interface for working with the various
5
+ # properties of a ComplexType mimics that of Entities.
6
+ class ComplexType
7
+ # The name of the ComplexType
8
+ attr_reader :name
9
+
10
+ # Creates a new ComplexType based on the supplied options.
11
+ # @param options [Hash]
12
+ # @return [self]
13
+ def initialize(options = {})
14
+ validate_options(options)
15
+
16
+ @name = options[:name].to_s
17
+ @service = options[:service]
18
+
19
+ collect_properties
20
+ end
21
+
22
+ # Returns the namespace this ComplexType belongs to.
23
+ # @return [String]
24
+ def namespace
25
+ @namespace ||= service.namespace
26
+ end
27
+
28
+ # Returns a list of this ComplexType's property names.
29
+ # @return [Array<String>]
30
+ def property_names
31
+ @property_names ||= properties.collect {|name, property| name}
32
+ end
33
+
34
+ # Returns the value of the requested property.
35
+ # @param property_name [to_s]
36
+ # @return [*]
37
+ def [](property_name)
38
+ properties[property_name.to_s].value
39
+ end
40
+
41
+ # Sets the value of the named property.
42
+ # @param property_name [to_s]
43
+ # @param value [*]
44
+ # @return [*]
45
+ def []=(property_name, value)
46
+ properties[property_name.to_s].value = value
47
+ end
48
+
49
+ private
50
+
51
+ def service
52
+ @service
53
+ end
54
+
55
+ def properties
56
+ @properties
57
+ end
58
+
59
+ def validate_options(options)
60
+
61
+ end
62
+
63
+ def collect_properties
64
+ @properties = service.properties_for_complex_type(name)
65
+ end
66
+ end
67
+ end
data/lib/odata/entity.rb CHANGED
@@ -30,22 +30,22 @@ module OData
30
30
  # @param property_name [to_s]
31
31
  # @return [*]
32
32
  def [](property_name)
33
- begin
34
- properties[property_name.to_s].value
35
- rescue NoMethodError
36
- raise ArgumentError, "Unknown property: #{property_name}"
33
+ if properties[property_name.to_s].is_a?(::OData::ComplexType)
34
+ properties[property_name.to_s]
35
+ else
36
+ properties[property_name.to_s].value
37
37
  end
38
+ rescue NoMethodError
39
+ raise ArgumentError, "Unknown property: #{property_name}"
38
40
  end
39
41
 
40
42
  # Set property value
41
43
  # @param property_name [to_s]
42
44
  # @param value [*]
43
45
  def []=(property_name, value)
44
- begin
45
- properties[property_name.to_s].value = value
46
- rescue NoMethodError
47
- raise ArgumentError, "Unknown property: #{property_name}"
48
- end
46
+ properties[property_name.to_s].value = value
47
+ rescue NoMethodError
48
+ raise ArgumentError, "Unknown property: #{property_name}"
49
49
  end
50
50
 
51
51
  # Create Entity with provided properties and options.
@@ -55,7 +55,7 @@ module OData
55
55
  def self.with_properties(new_properties = {}, options = {})
56
56
  entity = OData::Entity.new(options)
57
57
  entity.instance_eval do
58
- service.properties_for(name).each do |name, instance|
58
+ service.properties_for_entity(name).each do |name, instance|
59
59
  set_property(name, instance)
60
60
  end
61
61
 
@@ -118,10 +118,20 @@ module OData
118
118
 
119
119
  private
120
120
 
121
- def get_property_class(property_name)
121
+ def instantiate_property(property_name, value)
122
122
  value_type = service.get_property_type(name, property_name)
123
- klass_name = value_type.gsub(/^Edm\./, '')
124
- ::OData::Properties.const_get(klass_name)
123
+ if value_type =~ /^#{namespace}\./
124
+ type_name = value_type.gsub(/^#{namespace}\./, '')
125
+ property = ::OData::ComplexType.new(name: type_name, service: service)
126
+ value.element_children.each do |node|
127
+ property[node.name] = node.content
128
+ end
129
+ property
130
+ else
131
+ klass_name = value_type.gsub(/^Edm\./, '')
132
+ value = value.content unless value.nil?
133
+ ::OData::Properties.const_get(klass_name).new(property_name, value)
134
+ end
125
135
  end
126
136
 
127
137
  def properties
@@ -144,9 +154,9 @@ module OData
144
154
  property_xml.attributes['null'].value == 'true'
145
155
  value = nil
146
156
  else
147
- value = property_xml.content
157
+ value = property_xml
148
158
  end
149
- property = get_property_class(property_name).new(property_name, value)
159
+ property = instantiate_property(property_name, value)
150
160
  set_property(property_name, property)
151
161
  end
152
162
  end
@@ -154,9 +164,10 @@ module OData
154
164
 
155
165
  def self.process_feed_property(entity, xml_doc, property_name)
156
166
  entity.instance_eval do
157
- property_value = xml_doc.xpath("//#{property_name}").first.content
167
+ property_value = xml_doc.xpath("//#{property_name}").first
158
168
  property_name = service.send("get_#{property_name}_property_name", name)
159
- property = get_property_class(property_name).new(property_name, property_value)
169
+ return if property_name.nil?
170
+ property = instantiate_property(property_name, property_value)
160
171
  set_property(property_name, property)
161
172
  end
162
173
  end
@@ -11,4 +11,5 @@ require 'odata/properties/float'
11
11
  require 'odata/properties/guid'
12
12
  require 'odata/properties/integer'
13
13
  require 'odata/properties/string'
14
- require 'odata/properties/time'
14
+ require 'odata/properties/time'
15
+ require 'odata/properties/geography_point'
@@ -0,0 +1,6 @@
1
+ module OData
2
+ module Properties
3
+ class GeographyPoint < OData::Property
4
+ end
5
+ end
6
+ end
data/lib/odata/service.rb CHANGED
@@ -142,6 +142,8 @@ module OData
142
142
  # @return [String] the name of the property used as the entity summary
143
143
  def get_summary_property_name(entity_name)
144
144
  metadata.xpath("//EntityType[@Name='#{entity_name}']/Property[@FC_TargetPath='SyndicationSummary']").first.attributes['Name'].value
145
+ rescue NoMethodError
146
+ nil
145
147
  end
146
148
 
147
149
  # Get the primary key for the supplied Entity.
@@ -154,20 +156,32 @@ module OData
154
156
 
155
157
  # Get the list of properties and their various options for the supplied
156
158
  # Entity name.
157
- #
158
159
  # @param entity_name [to_s]
159
160
  # @return [Hash]
160
- def properties_for(entity_name)
161
+ # @api private
162
+ def properties_for_entity(entity_name)
161
163
  type_definition = metadata.xpath("//EntityType[@Name='#{entity_name}']").first
162
164
  raise ArgumentError, "Unknown EntityType: #{entity_name}" if type_definition.nil?
163
165
  properties_to_return = {}
164
166
  type_definition.xpath('./Property').each do |property_xml|
165
- property_name = property_xml.attributes['Name'].value
166
- value_type = property_xml.attributes['Type'].value
167
- property_options = {}
168
- property_options[:allows_nil] = false if property_xml.attributes['Nullable'] == 'false'
169
- klass_name = value_type.gsub(/^Edm\./, '')
170
- properties_to_return[property_name] = get_property_class(klass_name).new(property_name, nil, property_options)
167
+ property_name, property = process_property_from_xml(property_xml)
168
+ properties_to_return[property_name] = property
169
+ end
170
+ properties_to_return
171
+ end
172
+
173
+ # Get list of properties and their various options for the supplied
174
+ # ComplexType name.
175
+ # @param type_name [to_s]
176
+ # @return [Hash]
177
+ # @api private
178
+ def properties_for_complex_type(type_name)
179
+ type_definition = metadata.xpath("//ComplexType[@Name='#{type_name}']").first
180
+ raise ArgumentError, "Unknown ComplexType: #{type_name}" if type_definition.nil?
181
+ properties_to_return = {}
182
+ type_definition.xpath('./Property').each do |property_xml|
183
+ property_name, property = process_property_from_xml(property_xml)
184
+ properties_to_return[property_name] = property
171
185
  end
172
186
  properties_to_return
173
187
  end
@@ -197,5 +211,15 @@ module OData
197
211
  ::Nokogiri::XML(response.body).remove_namespaces!
198
212
  }.call
199
213
  end
214
+
215
+ def process_property_from_xml(property_xml)
216
+ property_name = property_xml.attributes['Name'].value
217
+ value_type = property_xml.attributes['Type'].value
218
+ property_options = {}
219
+ property_options[:allows_nil] = false if property_xml.attributes['Nullable'] == 'false'
220
+ klass_name = value_type.gsub(/^Edm\./, '')
221
+ property = get_property_class(klass_name).new(property_name, nil, property_options)
222
+ return [property_name, property]
223
+ end
200
224
  end
201
225
  end
data/lib/odata/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module OData
2
- VERSION = '0.5.0'
2
+ VERSION = '0.5.1'
3
3
  end
@@ -0,0 +1,37 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <entry xml:base="http://services.odata.org/OData/OData.svc/" xmlns="http://www.w3.org/2005/Atom"
3
+ xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
4
+ xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
5
+ xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" m:etag="W/&quot;0&quot;">
6
+ <id>http://services.odata.org/OData/OData.svc/Suppliers(0)</id>
7
+ <category term="ODataDemo.Supplier" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
8
+ <link rel="edit" title="Supplier" href="Suppliers(0)"/>
9
+ <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Products"
10
+ type="application/atom+xml;type=feed" title="Products" href="Suppliers(0)/Products"/>
11
+ <title type="text">Exotic Liquids</title>
12
+ <updated>2014-09-15T04:34:42Z</updated>
13
+ <author>
14
+ <name/>
15
+ </author>
16
+ <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/relatedlinks/Products" type="application/xml"
17
+ title="Products" href="Suppliers(0)/$links/Products"/>
18
+ <content type="application/xml">
19
+ <m:properties>
20
+ <d:ID m:type="Edm.Int32">0</d:ID>
21
+ <d:Name>Exotic Liquids</d:Name>
22
+ <d:Address m:type="ODataDemo.Address">
23
+ <d:Street>NE 228th</d:Street>
24
+ <d:City>Sammamish</d:City>
25
+ <d:State>WA</d:State>
26
+ <d:ZipCode>98074</d:ZipCode>
27
+ <d:Country>USA</d:Country>
28
+ </d:Address>
29
+ <d:Location m:type="Edm.GeographyPoint">
30
+ <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
31
+ <gml:pos>47.6316604614258 -122.03547668457</gml:pos>
32
+ </gml:Point>
33
+ </d:Location>
34
+ <d:Concurrency m:type="Edm.Int32">0</d:Concurrency>
35
+ </m:properties>
36
+ </content>
37
+ </entry>
@@ -0,0 +1,164 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://services.odata.org/OData/OData.svc/$metadata
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - Typhoeus - https://github.com/typhoeus/typhoeus
12
+ response:
13
+ status:
14
+ code: 200
15
+ message: OK
16
+ headers:
17
+ Cache-Control:
18
+ - no-cache
19
+ Content-Length:
20
+ - '10034'
21
+ Content-Type:
22
+ - application/xml;charset=utf-8
23
+ Server:
24
+ - Microsoft-IIS/8.0
25
+ X-Content-Type-Options:
26
+ - nosniff
27
+ DataServiceVersion:
28
+ - 3.0;
29
+ X-AspNet-Version:
30
+ - 4.0.30319
31
+ X-Powered-By:
32
+ - ASP.NET
33
+ Access-Control-Allow-Origin:
34
+ - "*"
35
+ Access-Control-Allow-Methods:
36
+ - GET
37
+ Access-Control-Allow-Headers:
38
+ - Accept, Origin, Content-Type, MaxDataServiceVersion
39
+ Access-Control-Expose-Headers:
40
+ - DataServiceVersion
41
+ Set-Cookie:
42
+ - ARRAffinity=9df27d486a924e1ae61bad0640ee28788b5a0f49ab9983f64ad6636df0c674a5;Path=/;Domain=services.odata.org
43
+ Date:
44
+ - Wed, 23 Jul 2014 17:40:38 GMT
45
+ body:
46
+ encoding: UTF-8
47
+ string: <?xml version="1.0" encoding="utf-8"?><edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx"><edmx:DataServices
48
+ m:DataServiceVersion="3.0" m:MaxDataServiceVersion="3.0" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><Schema
49
+ Namespace="ODataDemo" xmlns="http://schemas.microsoft.com/ado/2009/11/edm"><EntityType
50
+ Name="Product"><Key><PropertyRef Name="ID" /></Key><Property Name="ID" Type="Edm.Int32"
51
+ Nullable="false" /><Property Name="Name" Type="Edm.String" m:FC_TargetPath="SyndicationTitle"
52
+ m:FC_ContentKind="text" m:FC_KeepInContent="false" /><Property Name="Description"
53
+ Type="Edm.String" m:FC_TargetPath="SyndicationSummary" m:FC_ContentKind="text"
54
+ m:FC_KeepInContent="false" /><Property Name="ReleaseDate" Type="Edm.DateTime"
55
+ Nullable="false" /><Property Name="DiscontinuedDate" Type="Edm.DateTime" /><Property
56
+ Name="Rating" Type="Edm.Int16" Nullable="false" /><Property Name="Price" Type="Edm.Double"
57
+ Nullable="false" /><NavigationProperty Name="Categories" Relationship="ODataDemo.Product_Categories_Category_Products"
58
+ ToRole="Category_Products" FromRole="Product_Categories" /><NavigationProperty
59
+ Name="Supplier" Relationship="ODataDemo.Product_Supplier_Supplier_Products"
60
+ ToRole="Supplier_Products" FromRole="Product_Supplier" /><NavigationProperty
61
+ Name="ProductDetail" Relationship="ODataDemo.Product_ProductDetail_ProductDetail_Product"
62
+ ToRole="ProductDetail_Product" FromRole="Product_ProductDetail" /></EntityType><EntityType
63
+ Name="FeaturedProduct" BaseType="ODataDemo.Product"><NavigationProperty Name="Advertisement"
64
+ Relationship="ODataDemo.FeaturedProduct_Advertisement_Advertisement_FeaturedProduct"
65
+ ToRole="Advertisement_FeaturedProduct" FromRole="FeaturedProduct_Advertisement"
66
+ /></EntityType><EntityType Name="ProductDetail"><Key><PropertyRef Name="ProductID"
67
+ /></Key><Property Name="ProductID" Type="Edm.Int32" Nullable="false" /><Property
68
+ Name="Details" Type="Edm.String" /><NavigationProperty Name="Product" Relationship="ODataDemo.Product_ProductDetail_ProductDetail_Product"
69
+ ToRole="Product_ProductDetail" FromRole="ProductDetail_Product" /></EntityType><EntityType
70
+ Name="Category" OpenType="true"><Key><PropertyRef Name="ID" /></Key><Property
71
+ Name="ID" Type="Edm.Int32" Nullable="false" /><Property Name="Name" Type="Edm.String"
72
+ m:FC_TargetPath="SyndicationTitle" m:FC_ContentKind="text" m:FC_KeepInContent="true"
73
+ /><NavigationProperty Name="Products" Relationship="ODataDemo.Product_Categories_Category_Products"
74
+ ToRole="Product_Categories" FromRole="Category_Products" /></EntityType><EntityType
75
+ Name="Supplier"><Key><PropertyRef Name="ID" /></Key><Property Name="ID" Type="Edm.Int32"
76
+ Nullable="false" /><Property Name="Name" Type="Edm.String" m:FC_TargetPath="SyndicationTitle"
77
+ m:FC_ContentKind="text" m:FC_KeepInContent="true" /><Property Name="Address"
78
+ Type="ODataDemo.Address" /><Property Name="Location" Type="Edm.GeographyPoint"
79
+ SRID="Variable" /><Property Name="Concurrency" Type="Edm.Int32" ConcurrencyMode="Fixed"
80
+ Nullable="false" /><NavigationProperty Name="Products" Relationship="ODataDemo.Product_Supplier_Supplier_Products"
81
+ ToRole="Product_Supplier" FromRole="Supplier_Products" /></EntityType><ComplexType
82
+ Name="Address"><Property Name="Street" Type="Edm.String" /><Property Name="City"
83
+ Type="Edm.String" /><Property Name="State" Type="Edm.String" /><Property Name="ZipCode"
84
+ Type="Edm.String" /><Property Name="Country" Type="Edm.String" /></ComplexType><EntityType
85
+ Name="Person"><Key><PropertyRef Name="ID" /></Key><Property Name="ID" Type="Edm.Int32"
86
+ Nullable="false" /><Property Name="Name" Type="Edm.String" /><NavigationProperty
87
+ Name="PersonDetail" Relationship="ODataDemo.Person_PersonDetail_PersonDetail_Person"
88
+ ToRole="PersonDetail_Person" FromRole="Person_PersonDetail" /></EntityType><EntityType
89
+ Name="Customer" BaseType="ODataDemo.Person"><Property Name="TotalExpense"
90
+ Type="Edm.Decimal" Nullable="false" /></EntityType><EntityType Name="Employee"
91
+ BaseType="ODataDemo.Person"><Property Name="EmployeeID" Type="Edm.Int64" Nullable="false"
92
+ /><Property Name="HireDate" Type="Edm.DateTime" Nullable="false" /><Property
93
+ Name="Salary" Type="Edm.Single" Nullable="false" /></EntityType><EntityType
94
+ Name="PersonDetail"><Key><PropertyRef Name="PersonID" /></Key><Property Name="PersonID"
95
+ Type="Edm.Int32" Nullable="false" /><Property Name="Age" Type="Edm.Byte" Nullable="false"
96
+ /><Property Name="Gender" Type="Edm.Boolean" Nullable="false" /><Property
97
+ Name="Phone" Type="Edm.String" /><Property Name="Address" Type="ODataDemo.Address"
98
+ /><Property Name="Photo" Type="Edm.Stream" Nullable="false" /><NavigationProperty
99
+ Name="Person" Relationship="ODataDemo.Person_PersonDetail_PersonDetail_Person"
100
+ ToRole="Person_PersonDetail" FromRole="PersonDetail_Person" /></EntityType><EntityType
101
+ Name="Advertisement" m:HasStream="true"><Key><PropertyRef Name="ID" /></Key><Property
102
+ Name="ID" Type="Edm.Guid" Nullable="false" /><Property Name="Name" Type="Edm.String"
103
+ /><Property Name="AirDate" Type="Edm.DateTime" Nullable="false" /><NavigationProperty
104
+ Name="FeaturedProduct" Relationship="ODataDemo.FeaturedProduct_Advertisement_Advertisement_FeaturedProduct"
105
+ ToRole="FeaturedProduct_Advertisement" FromRole="Advertisement_FeaturedProduct"
106
+ /></EntityType><Association Name="Product_Categories_Category_Products"><End
107
+ Type="ODataDemo.Category" Role="Category_Products" Multiplicity="*" /><End
108
+ Type="ODataDemo.Product" Role="Product_Categories" Multiplicity="*" /></Association><Association
109
+ Name="Product_Supplier_Supplier_Products"><End Type="ODataDemo.Supplier" Role="Supplier_Products"
110
+ Multiplicity="0..1" /><End Type="ODataDemo.Product" Role="Product_Supplier"
111
+ Multiplicity="*" /></Association><Association Name="Product_ProductDetail_ProductDetail_Product"><End
112
+ Type="ODataDemo.ProductDetail" Role="ProductDetail_Product" Multiplicity="0..1"
113
+ /><End Type="ODataDemo.Product" Role="Product_ProductDetail" Multiplicity="0..1"
114
+ /></Association><Association Name="FeaturedProduct_Advertisement_Advertisement_FeaturedProduct"><End
115
+ Type="ODataDemo.Advertisement" Role="Advertisement_FeaturedProduct" Multiplicity="0..1"
116
+ /><End Type="ODataDemo.FeaturedProduct" Role="FeaturedProduct_Advertisement"
117
+ Multiplicity="0..1" /></Association><Association Name="Person_PersonDetail_PersonDetail_Person"><End
118
+ Type="ODataDemo.PersonDetail" Role="PersonDetail_Person" Multiplicity="0..1"
119
+ /><End Type="ODataDemo.Person" Role="Person_PersonDetail" Multiplicity="0..1"
120
+ /></Association><EntityContainer Name="DemoService" m:IsDefaultEntityContainer="true"><EntitySet
121
+ Name="Products" EntityType="ODataDemo.Product" /><EntitySet Name="ProductDetails"
122
+ EntityType="ODataDemo.ProductDetail" /><EntitySet Name="Categories" EntityType="ODataDemo.Category"
123
+ /><EntitySet Name="Suppliers" EntityType="ODataDemo.Supplier" /><EntitySet
124
+ Name="Persons" EntityType="ODataDemo.Person" /><EntitySet Name="PersonDetails"
125
+ EntityType="ODataDemo.PersonDetail" /><EntitySet Name="Advertisements" EntityType="ODataDemo.Advertisement"
126
+ /><FunctionImport Name="GetProductsByRating" ReturnType="Collection(ODataDemo.Product)"
127
+ EntitySet="Products" m:HttpMethod="GET"><Parameter Name="rating" Type="Edm.Int16"
128
+ Nullable="false" /></FunctionImport><AssociationSet Name="Products_Advertisement_Advertisements"
129
+ Association="ODataDemo.FeaturedProduct_Advertisement_Advertisement_FeaturedProduct"><End
130
+ Role="FeaturedProduct_Advertisement" EntitySet="Products" /><End Role="Advertisement_FeaturedProduct"
131
+ EntitySet="Advertisements" /></AssociationSet><AssociationSet Name="Products_Categories_Categories"
132
+ Association="ODataDemo.Product_Categories_Category_Products"><End Role="Product_Categories"
133
+ EntitySet="Products" /><End Role="Category_Products" EntitySet="Categories"
134
+ /></AssociationSet><AssociationSet Name="Products_Supplier_Suppliers" Association="ODataDemo.Product_Supplier_Supplier_Products"><End
135
+ Role="Product_Supplier" EntitySet="Products" /><End Role="Supplier_Products"
136
+ EntitySet="Suppliers" /></AssociationSet><AssociationSet Name="Products_ProductDetail_ProductDetails"
137
+ Association="ODataDemo.Product_ProductDetail_ProductDetail_Product"><End Role="Product_ProductDetail"
138
+ EntitySet="Products" /><End Role="ProductDetail_Product" EntitySet="ProductDetails"
139
+ /></AssociationSet><AssociationSet Name="Persons_PersonDetail_PersonDetails"
140
+ Association="ODataDemo.Person_PersonDetail_PersonDetail_Person"><End Role="Person_PersonDetail"
141
+ EntitySet="Persons" /><End Role="PersonDetail_Person" EntitySet="PersonDetails"
142
+ /></AssociationSet></EntityContainer><Annotations Target="ODataDemo.DemoService"><ValueAnnotation
143
+ Term="Org.OData.Display.V1.Description" String="This is a sample OData service
144
+ with vocabularies" /></Annotations><Annotations Target="ODataDemo.Product"><ValueAnnotation
145
+ Term="Org.OData.Display.V1.Description" String="All Products available in
146
+ the online store" /></Annotations><Annotations Target="ODataDemo.Product/Name"><ValueAnnotation
147
+ Term="Org.OData.Display.V1.DisplayName" String="Product Name" /></Annotations><Annotations
148
+ Target="ODataDemo.DemoService/Suppliers"><ValueAnnotation Term="Org.OData.Publication.V1.PublisherName"
149
+ String="Microsoft Corp." /><ValueAnnotation Term="Org.OData.Publication.V1.PublisherId"
150
+ String="MSFT" /><ValueAnnotation Term="Org.OData.Publication.V1.Keywords"
151
+ String="Inventory, Supplier, Advertisers, Sales, Finance" /><ValueAnnotation
152
+ Term="Org.OData.Publication.V1.AttributionUrl" String="http://www.odata.org/"
153
+ /><ValueAnnotation Term="Org.OData.Publication.V1.AttributionDescription"
154
+ String="All rights reserved" /><ValueAnnotation Term="Org.OData.Publication.V1.DocumentationUrl
155
+ " String="http://www.odata.org/" /><ValueAnnotation Term="Org.OData.Publication.V1.TermsOfUseUrl"
156
+ String="All rights reserved" /><ValueAnnotation Term="Org.OData.Publication.V1.PrivacyPolicyUrl"
157
+ String="http://www.odata.org/" /><ValueAnnotation Term="Org.OData.Publication.V1.LastModified"
158
+ String="4/2/2013" /><ValueAnnotation Term="Org.OData.Publication.V1.ImageUrl
159
+ " String="http://www.odata.org/" /></Annotations></Schema></edmx:DataServices></edmx:Edmx>
160
+ http_version: '1.1'
161
+ adapter_metadata:
162
+ effective_url: http://services.odata.org/OData/OData.svc/$metadata
163
+ recorded_at: Wed, 23 Jul 2014 17:40:40 GMT
164
+ recorded_with: VCR 2.9.2
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe OData::ComplexType, vcr: {cassette_name: 'complex_type_specs'} do
4
+ before(:example) do
5
+ OData::Service.open('http://services.odata.org/OData/OData.svc', name: 'ODataDemo')
6
+ end
7
+
8
+ let(:subject) { OData::ComplexType.new(name: 'Address', service: service) }
9
+ let(:service) { OData::ServiceRegistry['ODataDemo'] }
10
+
11
+ it { expect(subject).to respond_to(:name) }
12
+ it { expect(subject).to respond_to(:namespace) }
13
+ it { expect(subject).to respond_to(:property_names) }
14
+ it { expect(subject).to respond_to(:[]) }
15
+ it { expect(subject).to respond_to(:[]=) }
16
+
17
+ describe 'is properly parsed from service metadata' do
18
+ it { expect(subject.name).to eq('Address') }
19
+ it { expect(subject.namespace).to eq('ODataDemo') }
20
+ it { expect(subject.property_names).to eq(%w{Street City State ZipCode Country}) }
21
+
22
+ it { expect(subject['Street']).to be_nil }
23
+ it { expect(subject['City']).to be_nil }
24
+ it { expect(subject['State']).to be_nil }
25
+ it { expect(subject['ZipCode']).to be_nil }
26
+ it { expect(subject['Country']).to be_nil }
27
+
28
+ it { subject['Street'] = 'Test'; expect(subject['Street']).to eq('Test') }
29
+ it { subject['City'] = 'Test'; expect(subject['City']).to eq('Test') }
30
+ it { subject['State'] = 'Test'; expect(subject['State']).to eq('Test') }
31
+ it { subject['ZipCode'] = 'Test'; expect(subject['ZipCode']).to eq('Test') }
32
+ it { subject['Country'] = 'Test'; expect(subject['Country']).to eq('Test') }
33
+ end
34
+ end
@@ -45,5 +45,27 @@ describe OData::Entity, vcr: {cassette_name: 'entity_specs'} do
45
45
 
46
46
  it { expect {subject['NonExistant']}.to raise_error(ArgumentError) }
47
47
  it { expect {subject['NonExistant'] = 5}.to raise_error(ArgumentError) }
48
+
49
+ context 'with a complex type property' do
50
+ let(:options) { {
51
+ type: 'ODataDemo.Supplier',
52
+ namespace: 'ODataDemo',
53
+ service_name: 'ODataDemo'
54
+ } }
55
+
56
+ let(:subject) { OData::Entity.from_xml(supplier_xml, options) }
57
+ let(:supplier_xml) {
58
+ document = ::Nokogiri::XML(File.open('spec/fixtures/sample_service/supplier_0.xml'))
59
+ document.remove_namespaces!
60
+ document.xpath('//entry').first
61
+ }
62
+
63
+ it { expect(subject.name).to eq('Supplier') }
64
+ it { expect(subject.type).to eq('ODataDemo.Supplier') }
65
+
66
+ it { expect(subject['Address']).to be_a(OData::ComplexType) }
67
+ it { expect(subject['Address']['Street']).to eq('NE 228th') }
68
+ it { expect(subject['Address']['City']).to eq('Sammamish') }
69
+ end
48
70
  end
49
71
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: odata
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Thompson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-21 00:00:00.000000000 Z
11
+ date: 2014-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -153,6 +153,7 @@ files:
153
153
  - README.md
154
154
  - Rakefile
155
155
  - lib/odata.rb
156
+ - lib/odata/complex_type.rb
156
157
  - lib/odata/entity.rb
157
158
  - lib/odata/entity_set.rb
158
159
  - lib/odata/properties.rb
@@ -162,6 +163,7 @@ files:
162
163
  - lib/odata/properties/date_time_offset.rb
163
164
  - lib/odata/properties/decimal.rb
164
165
  - lib/odata/properties/float.rb
166
+ - lib/odata/properties/geography_point.rb
165
167
  - lib/odata/properties/guid.rb
166
168
  - lib/odata/properties/integer.rb
167
169
  - lib/odata/properties/number.rb
@@ -187,6 +189,8 @@ files:
187
189
  - spec/fixtures/sample_service/products_skip0_top5.xml
188
190
  - spec/fixtures/sample_service/products_skip10_top5.xml
189
191
  - spec/fixtures/sample_service/products_skip5_top5.xml
192
+ - spec/fixtures/sample_service/supplier_0.xml
193
+ - spec/fixtures/vcr_cassettes/complex_type_specs.yml
190
194
  - spec/fixtures/vcr_cassettes/entity_set_specs.yml
191
195
  - spec/fixtures/vcr_cassettes/entity_set_specs/bad_entry.yml
192
196
  - spec/fixtures/vcr_cassettes/entity_set_specs/existing_entry.yml
@@ -196,6 +200,7 @@ files:
196
200
  - spec/fixtures/vcr_cassettes/query_specs.yml
197
201
  - spec/fixtures/vcr_cassettes/service_registry_specs.yml
198
202
  - spec/fixtures/vcr_cassettes/service_specs.yml
203
+ - spec/odata/complex_type_spec.rb
199
204
  - spec/odata/entity_set_spec.rb
200
205
  - spec/odata/entity_spec.rb
201
206
  - spec/odata/properties/binary_spec.rb
@@ -251,6 +256,8 @@ test_files:
251
256
  - spec/fixtures/sample_service/products_skip0_top5.xml
252
257
  - spec/fixtures/sample_service/products_skip10_top5.xml
253
258
  - spec/fixtures/sample_service/products_skip5_top5.xml
259
+ - spec/fixtures/sample_service/supplier_0.xml
260
+ - spec/fixtures/vcr_cassettes/complex_type_specs.yml
254
261
  - spec/fixtures/vcr_cassettes/entity_set_specs.yml
255
262
  - spec/fixtures/vcr_cassettes/entity_set_specs/bad_entry.yml
256
263
  - spec/fixtures/vcr_cassettes/entity_set_specs/existing_entry.yml
@@ -260,6 +267,7 @@ test_files:
260
267
  - spec/fixtures/vcr_cassettes/query_specs.yml
261
268
  - spec/fixtures/vcr_cassettes/service_registry_specs.yml
262
269
  - spec/fixtures/vcr_cassettes/service_specs.yml
270
+ - spec/odata/complex_type_spec.rb
263
271
  - spec/odata/entity_set_spec.rb
264
272
  - spec/odata/entity_spec.rb
265
273
  - spec/odata/properties/binary_spec.rb