odata 0.5.8 → 0.6.0

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: c8fdea1fa3181e24c43f5f2121d48d6685df3780
4
- data.tar.gz: 4eeda811bf149b107b23a540162041c025c9647d
3
+ metadata.gz: 7e31316dd4d29bcce7e8ce68e80686d868b939e6
4
+ data.tar.gz: 7b0ae9591a494b1520d9b4b1f65686b0b3282fe0
5
5
  SHA512:
6
- metadata.gz: 436b465b08302628869a881377446d3dcbef41d788c5be2052d4fa9741503d7198959010ab956e0a81685a15435e3e3f96375e27cdf4e959ee34824b0476c41a
7
- data.tar.gz: 8498c3425a1b3999857c863dc211d5f5c0aaceb69598cd025456cb15c9c7b485e065524e6e86182c8dfbfe4645ead9e33a0e7d7e2d3ec2a7b6e16d4e8426ca9f
6
+ metadata.gz: 38a384c17104bc6b6febb1e6511f226395ec99cddcbaa36b42b7d6341128d7066e747d438423b913e8403f22e8567772f56c093209647d061b35e106154f4ce0
7
+ data.tar.gz: 8dc9e056e2ad635675011a229dea3713d3d711d14f8196cfbdcffbc5959512dc26749a3849e7842e81739b5f9f4e231c3f7fb5d060b2d83460099046584e27e6
data/.autotest ADDED
@@ -0,0 +1,2 @@
1
+ require 'autotest/bundler'
2
+
data/.rspec CHANGED
@@ -1 +1,2 @@
1
1
  --color
2
+ --format progress
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.6.0
4
+
5
+ * Added ability to handle associations in a reasonable way.
6
+
7
+ ## 0.5.1-8
8
+
9
+ * Tons of changes throughout the code base
10
+
3
11
  ## 0.5.0
4
12
 
5
13
  * Stopped using namespace from OData service as unique identifier in favor of
data/lib/odata.rb CHANGED
@@ -13,6 +13,7 @@ require 'odata/property_registry'
13
13
  require 'odata/property'
14
14
  require 'odata/properties'
15
15
  require 'odata/complex_type'
16
+ require 'odata/association'
16
17
  require 'odata/entity'
17
18
  require 'odata/entity_set'
18
19
  require 'odata/query/criteria'
@@ -0,0 +1,16 @@
1
+ require 'odata/association/end'
2
+ require 'odata/association/proxy'
3
+
4
+ module OData
5
+ class Association
6
+ attr_reader :name, :ends
7
+
8
+ def initialize(options)
9
+ @name = options[:name]
10
+ @ends = options[:ends] || []
11
+
12
+ raise ArgumentError, 'name must be provided' if name.nil? || name == ''
13
+ raise ArgumentError, 'too many association ends' if ends.size > 2
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,30 @@
1
+ module OData
2
+ class Association
3
+ class End
4
+ attr_reader :entity_type, :multiplicity
5
+
6
+ def initialize(options)
7
+ @entity_type = options[:entity_type]
8
+ @multiplicity = self.class.multiplicity_map[options[:multiplicity].to_s]
9
+
10
+ raise ArgumentError, ':entity_type option is required' if entity_type.nil? || entity_type == ''
11
+ raise ArgumentError, ':multiplicity option is required' if multiplicity.nil?
12
+ raise ArgumentError, ':multiplicity option must be one of [1, *, 0..1]' unless valid_multiplicities.include?(multiplicity)
13
+ end
14
+
15
+ def self.multiplicity_map
16
+ {
17
+ '1' => :one,
18
+ '*' => :many,
19
+ '0..1' => :zero_to_one
20
+ }
21
+ end
22
+
23
+ private
24
+
25
+ def valid_multiplicities
26
+ [:one, :many, :zero_to_one]
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,66 @@
1
+ module OData
2
+ class Association
3
+ class Proxy
4
+ def initialize(entity)
5
+ @entity = entity
6
+ end
7
+
8
+ def [](association_name)
9
+ if entity.links[association_name].nil? || associations[association_name].nil?
10
+ raise ArgumentError, "unknown association: #{association_name}"
11
+ end
12
+
13
+ association_results(association_name)
14
+ end
15
+
16
+ def size
17
+ associations.size
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :entity
23
+
24
+ def service
25
+ @service ||= OData::ServiceRegistry[entity.service_name]
26
+ end
27
+
28
+ def namespace
29
+ @namespace ||= service.namespace
30
+ end
31
+
32
+ def entity_type
33
+ @entity_type ||= entity.name
34
+ end
35
+
36
+ def associations
37
+ @associations ||= service.navigation_properties[entity_type]
38
+ end
39
+
40
+ def association_results(association_name)
41
+ association = associations[association_name]
42
+ link = entity.links[association_name]
43
+ association_end = association.ends.select {|details| details.entity_type != "#{namespace}.#{entity_type}"}.first
44
+ raise RuntimeError, 'association ends undefined' if association_end.nil?
45
+
46
+ results = service.execute(link[:href])
47
+ options = {
48
+ type: association_end.entity_type,
49
+ namespace: namespace,
50
+ service_name: entity.service_name
51
+ }
52
+
53
+ if association_end.multiplicity == :many
54
+ service.find_entities(results).collect do |entity_xml|
55
+ OData::Entity.from_xml(entity_xml, options)
56
+ #block_given? ? block.call(entity) : yield(entity)
57
+ end
58
+ else
59
+ document = ::Nokogiri::XML(results.body)
60
+ document.remove_namespaces!
61
+ OData::Entity.from_xml(document, options)
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
data/lib/odata/entity.rb CHANGED
@@ -11,6 +11,8 @@ module OData
11
11
  attr_reader :namespace
12
12
  # The OData::Service's identifying name
13
13
  attr_reader :service_name
14
+ # Links to other OData entitites
15
+ attr_reader :links
14
16
 
15
17
  # Initializes a bare Entity
16
18
  # @param options [Hash]
@@ -18,6 +20,7 @@ module OData
18
20
  @type = options[:type]
19
21
  @namespace = options[:namespace]
20
22
  @service_name = options[:service_name]
23
+ @links = options[:links] || {}
21
24
  end
22
25
 
23
26
  # Returns name of Entity from Service specified type.
@@ -48,6 +51,10 @@ module OData
48
51
  raise ArgumentError, "Unknown property: #{property_name}"
49
52
  end
50
53
 
54
+ def associations
55
+ @associations ||= OData::Association::Proxy.new(self)
56
+ end
57
+
51
58
  # Create Entity with provided properties and options.
52
59
  # @param new_properties [Hash]
53
60
  # @param options [Hash]
@@ -76,6 +83,7 @@ module OData
76
83
  process_properties(entity, xml_doc)
77
84
  process_feed_property(entity, xml_doc, 'title')
78
85
  process_feed_property(entity, xml_doc, 'summary')
86
+ process_links(entity, xml_doc)
79
87
  entity
80
88
  end
81
89
 
@@ -174,5 +182,22 @@ module OData
174
182
  set_property(property_name, property)
175
183
  end
176
184
  end
185
+
186
+ def self.process_links(entity, xml_doc)
187
+ entity.instance_eval do
188
+ service.navigation_properties[name].each do |nav_name, details|
189
+ xml_doc.xpath("//link[@title='#{nav_name}']").each do |node|
190
+ next unless node.attributes['type'].value =~ /^application\/atom\+xml;type=(feed|entry)$/i
191
+ link_type = node.attributes['type'].value =~ /type=entry$/i ? :entry : :feed
192
+ new_links = instance_variable_get(:@links)
193
+ new_links[nav_name] = {
194
+ type: link_type,
195
+ href: node.attributes['href'].value
196
+ }
197
+ instance_variable_set(:@links, new_links)
198
+ end
199
+ end
200
+ end
201
+ end
177
202
  end
178
203
  end
@@ -15,7 +15,7 @@ module OData
15
15
  # Sets the property value
16
16
  # @params new_value something BigDecimal() can parse
17
17
  def value=(new_value)
18
- validate(BigDecimal(new_value))
18
+ validate(BigDecimal(new_value.to_s))
19
19
  @value = new_value.to_s
20
20
  end
21
21
 
data/lib/odata/service.rb CHANGED
@@ -56,6 +56,37 @@ module OData
56
56
  @complex_types ||= metadata.xpath('//ComplexType').collect {|entity| entity.attributes['Name'].value}
57
57
  end
58
58
 
59
+ # Returns the associations defined by the service
60
+ # @return [Hash<OData::Association>]
61
+ def associations
62
+ @associations ||= Hash[metadata.xpath('//Association').collect do |association_definition|
63
+ [
64
+ association_definition.attributes['Name'].value,
65
+ build_association(association_definition)
66
+ ]
67
+ end]
68
+ end
69
+
70
+ # Returns a hash for finding an association through an entity type's defined
71
+ # NavigationProperty elements.
72
+ # @return [Hash<Hash<OData::Association>>]
73
+ def navigation_properties
74
+ @navigation_properties ||= Hash[metadata.xpath('//EntityType').collect do |entity_type_def|
75
+ entity_type_name = entity_type_def.attributes['Name'].value
76
+ [
77
+ entity_type_name,
78
+ Hash[entity_type_def.xpath('./NavigationProperty').collect do |nav_property_def|
79
+ relationship_name = nav_property_def.attributes['Relationship'].value
80
+ relationship_name.gsub!(/^#{namespace}\./, '')
81
+ [
82
+ nav_property_def.attributes['Name'].value,
83
+ associations[relationship_name]
84
+ ]
85
+ end]
86
+ ]
87
+ end]
88
+ end
89
+
59
90
  # Returns the namespace defined on the service's schema
60
91
  def namespace
61
92
  @namespace ||= metadata.xpath('//Schema').first.attributes['Namespace'].value
@@ -133,7 +164,8 @@ module OData
133
164
  # @param entity_name [to_s] the name of the relevant entity
134
165
  # @return [String] the name of the property used as the entity title
135
166
  def get_title_property_name(entity_name)
136
- metadata.xpath("//EntityType[@Name='#{entity_name}']/Property[@FC_TargetPath='SyndicationTitle']").first.attributes['Name'].value
167
+ node = metadata.xpath("//EntityType[@Name='#{entity_name}']/Property[@FC_TargetPath='SyndicationTitle']").first
168
+ node.nil? ? nil : node.attributes['Name'].value
137
169
  end
138
170
 
139
171
  # Get the property used as the summary for an entity from metadata.
@@ -229,5 +261,23 @@ module OData
229
261
 
230
262
  return [property_name, property]
231
263
  end
264
+
265
+ def build_association(association_definition)
266
+ options = {
267
+ name: association_definition.attributes['Name'].value,
268
+ ends: build_association_ends(association_definition.xpath('./End'))
269
+ }
270
+ ::OData::Association.new(options)
271
+ end
272
+
273
+ def build_association_ends(end_definitions)
274
+ end_definitions.collect do |end_definition|
275
+ options = {
276
+ entity_type: end_definition.attributes['Type'].value,
277
+ multiplicity: end_definition.attributes['Multiplicity'].value
278
+ }
279
+ ::OData::Association::End.new(options)
280
+ end
281
+ end
232
282
  end
233
283
  end
data/lib/odata/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module OData
2
- VERSION = '0.5.8'
2
+ VERSION = '0.6.0'
3
3
  end
data/odata.gemspec CHANGED
@@ -23,6 +23,8 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency 'simplecov', '~> 0.8.2'
24
24
  spec.add_development_dependency 'codeclimate-test-reporter'
25
25
  spec.add_development_dependency 'rspec', '~> 3.0.0'
26
+ spec.add_development_dependency 'rspec-autotest', '~> 1.0.0'
27
+ spec.add_development_dependency 'autotest', '~> 4.4.6'
26
28
  spec.add_development_dependency 'vcr', '~> 2.9.2'
27
29
  spec.add_development_dependency 'timecop', '~> 0.7.1'
28
30
 
@@ -0,0 +1,415 @@
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
+ DataServiceVersion:
13
+ - '3.0'
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Cache-Control:
20
+ - no-cache
21
+ Content-Length:
22
+ - '10034'
23
+ Content-Type:
24
+ - application/xml;charset=utf-8
25
+ Server:
26
+ - Microsoft-IIS/8.0
27
+ X-Content-Type-Options:
28
+ - nosniff
29
+ DataServiceVersion:
30
+ - 3.0;
31
+ X-AspNet-Version:
32
+ - 4.0.30319
33
+ X-Powered-By:
34
+ - ASP.NET
35
+ Access-Control-Allow-Origin:
36
+ - "*"
37
+ Access-Control-Allow-Methods:
38
+ - GET
39
+ Access-Control-Allow-Headers:
40
+ - Accept, Origin, Content-Type, MaxDataServiceVersion
41
+ Access-Control-Expose-Headers:
42
+ - DataServiceVersion
43
+ Set-Cookie:
44
+ - ARRAffinity=cb44902b614a02a3a0dc1bccc3de360d89b180ff17e14b11fd9b289a8de75827;Path=/;Domain=services.odata.org
45
+ Date:
46
+ - Tue, 30 Sep 2014 21:24:51 GMT
47
+ body:
48
+ encoding: UTF-8
49
+ 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
50
+ m:DataServiceVersion="3.0" m:MaxDataServiceVersion="3.0" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><Schema
51
+ Namespace="ODataDemo" xmlns="http://schemas.microsoft.com/ado/2009/11/edm"><EntityType
52
+ Name="Product"><Key><PropertyRef Name="ID" /></Key><Property Name="ID" Type="Edm.Int32"
53
+ Nullable="false" /><Property Name="Name" Type="Edm.String" m:FC_TargetPath="SyndicationTitle"
54
+ m:FC_ContentKind="text" m:FC_KeepInContent="false" /><Property Name="Description"
55
+ Type="Edm.String" m:FC_TargetPath="SyndicationSummary" m:FC_ContentKind="text"
56
+ m:FC_KeepInContent="false" /><Property Name="ReleaseDate" Type="Edm.DateTime"
57
+ Nullable="false" /><Property Name="DiscontinuedDate" Type="Edm.DateTime" /><Property
58
+ Name="Rating" Type="Edm.Int16" Nullable="false" /><Property Name="Price" Type="Edm.Double"
59
+ Nullable="false" /><NavigationProperty Name="Categories" Relationship="ODataDemo.Product_Categories_Category_Products"
60
+ ToRole="Category_Products" FromRole="Product_Categories" /><NavigationProperty
61
+ Name="Supplier" Relationship="ODataDemo.Product_Supplier_Supplier_Products"
62
+ ToRole="Supplier_Products" FromRole="Product_Supplier" /><NavigationProperty
63
+ Name="ProductDetail" Relationship="ODataDemo.Product_ProductDetail_ProductDetail_Product"
64
+ ToRole="ProductDetail_Product" FromRole="Product_ProductDetail" /></EntityType><EntityType
65
+ Name="FeaturedProduct" BaseType="ODataDemo.Product"><NavigationProperty Name="Advertisement"
66
+ Relationship="ODataDemo.FeaturedProduct_Advertisement_Advertisement_FeaturedProduct"
67
+ ToRole="Advertisement_FeaturedProduct" FromRole="FeaturedProduct_Advertisement"
68
+ /></EntityType><EntityType Name="ProductDetail"><Key><PropertyRef Name="ProductID"
69
+ /></Key><Property Name="ProductID" Type="Edm.Int32" Nullable="false" /><Property
70
+ Name="Details" Type="Edm.String" /><NavigationProperty Name="Product" Relationship="ODataDemo.Product_ProductDetail_ProductDetail_Product"
71
+ ToRole="Product_ProductDetail" FromRole="ProductDetail_Product" /></EntityType><EntityType
72
+ Name="Category" OpenType="true"><Key><PropertyRef Name="ID" /></Key><Property
73
+ Name="ID" Type="Edm.Int32" Nullable="false" /><Property Name="Name" Type="Edm.String"
74
+ m:FC_TargetPath="SyndicationTitle" m:FC_ContentKind="text" m:FC_KeepInContent="true"
75
+ /><NavigationProperty Name="Products" Relationship="ODataDemo.Product_Categories_Category_Products"
76
+ ToRole="Product_Categories" FromRole="Category_Products" /></EntityType><EntityType
77
+ Name="Supplier"><Key><PropertyRef Name="ID" /></Key><Property Name="ID" Type="Edm.Int32"
78
+ Nullable="false" /><Property Name="Name" Type="Edm.String" m:FC_TargetPath="SyndicationTitle"
79
+ m:FC_ContentKind="text" m:FC_KeepInContent="true" /><Property Name="Address"
80
+ Type="ODataDemo.Address" /><Property Name="Location" Type="Edm.GeographyPoint"
81
+ SRID="Variable" /><Property Name="Concurrency" Type="Edm.Int32" ConcurrencyMode="Fixed"
82
+ Nullable="false" /><NavigationProperty Name="Products" Relationship="ODataDemo.Product_Supplier_Supplier_Products"
83
+ ToRole="Product_Supplier" FromRole="Supplier_Products" /></EntityType><ComplexType
84
+ Name="Address"><Property Name="Street" Type="Edm.String" /><Property Name="City"
85
+ Type="Edm.String" /><Property Name="State" Type="Edm.String" /><Property Name="ZipCode"
86
+ Type="Edm.String" /><Property Name="Country" Type="Edm.String" /></ComplexType><EntityType
87
+ Name="Person"><Key><PropertyRef Name="ID" /></Key><Property Name="ID" Type="Edm.Int32"
88
+ Nullable="false" /><Property Name="Name" Type="Edm.String" /><NavigationProperty
89
+ Name="PersonDetail" Relationship="ODataDemo.Person_PersonDetail_PersonDetail_Person"
90
+ ToRole="PersonDetail_Person" FromRole="Person_PersonDetail" /></EntityType><EntityType
91
+ Name="Customer" BaseType="ODataDemo.Person"><Property Name="TotalExpense"
92
+ Type="Edm.Decimal" Nullable="false" /></EntityType><EntityType Name="Employee"
93
+ BaseType="ODataDemo.Person"><Property Name="EmployeeID" Type="Edm.Int64" Nullable="false"
94
+ /><Property Name="HireDate" Type="Edm.DateTime" Nullable="false" /><Property
95
+ Name="Salary" Type="Edm.Single" Nullable="false" /></EntityType><EntityType
96
+ Name="PersonDetail"><Key><PropertyRef Name="PersonID" /></Key><Property Name="PersonID"
97
+ Type="Edm.Int32" Nullable="false" /><Property Name="Age" Type="Edm.Byte" Nullable="false"
98
+ /><Property Name="Gender" Type="Edm.Boolean" Nullable="false" /><Property
99
+ Name="Phone" Type="Edm.String" /><Property Name="Address" Type="ODataDemo.Address"
100
+ /><Property Name="Photo" Type="Edm.Stream" Nullable="false" /><NavigationProperty
101
+ Name="Person" Relationship="ODataDemo.Person_PersonDetail_PersonDetail_Person"
102
+ ToRole="Person_PersonDetail" FromRole="PersonDetail_Person" /></EntityType><EntityType
103
+ Name="Advertisement" m:HasStream="true"><Key><PropertyRef Name="ID" /></Key><Property
104
+ Name="ID" Type="Edm.Guid" Nullable="false" /><Property Name="Name" Type="Edm.String"
105
+ /><Property Name="AirDate" Type="Edm.DateTime" Nullable="false" /><NavigationProperty
106
+ Name="FeaturedProduct" Relationship="ODataDemo.FeaturedProduct_Advertisement_Advertisement_FeaturedProduct"
107
+ ToRole="FeaturedProduct_Advertisement" FromRole="Advertisement_FeaturedProduct"
108
+ /></EntityType><Association Name="Product_Categories_Category_Products"><End
109
+ Type="ODataDemo.Category" Role="Category_Products" Multiplicity="*" /><End
110
+ Type="ODataDemo.Product" Role="Product_Categories" Multiplicity="*" /></Association><Association
111
+ Name="Product_Supplier_Supplier_Products"><End Type="ODataDemo.Supplier" Role="Supplier_Products"
112
+ Multiplicity="0..1" /><End Type="ODataDemo.Product" Role="Product_Supplier"
113
+ Multiplicity="*" /></Association><Association Name="Product_ProductDetail_ProductDetail_Product"><End
114
+ Type="ODataDemo.ProductDetail" Role="ProductDetail_Product" Multiplicity="0..1"
115
+ /><End Type="ODataDemo.Product" Role="Product_ProductDetail" Multiplicity="0..1"
116
+ /></Association><Association Name="FeaturedProduct_Advertisement_Advertisement_FeaturedProduct"><End
117
+ Type="ODataDemo.Advertisement" Role="Advertisement_FeaturedProduct" Multiplicity="0..1"
118
+ /><End Type="ODataDemo.FeaturedProduct" Role="FeaturedProduct_Advertisement"
119
+ Multiplicity="0..1" /></Association><Association Name="Person_PersonDetail_PersonDetail_Person"><End
120
+ Type="ODataDemo.PersonDetail" Role="PersonDetail_Person" Multiplicity="0..1"
121
+ /><End Type="ODataDemo.Person" Role="Person_PersonDetail" Multiplicity="0..1"
122
+ /></Association><EntityContainer Name="DemoService" m:IsDefaultEntityContainer="true"><EntitySet
123
+ Name="Products" EntityType="ODataDemo.Product" /><EntitySet Name="ProductDetails"
124
+ EntityType="ODataDemo.ProductDetail" /><EntitySet Name="Categories" EntityType="ODataDemo.Category"
125
+ /><EntitySet Name="Suppliers" EntityType="ODataDemo.Supplier" /><EntitySet
126
+ Name="Persons" EntityType="ODataDemo.Person" /><EntitySet Name="PersonDetails"
127
+ EntityType="ODataDemo.PersonDetail" /><EntitySet Name="Advertisements" EntityType="ODataDemo.Advertisement"
128
+ /><FunctionImport Name="GetProductsByRating" ReturnType="Collection(ODataDemo.Product)"
129
+ EntitySet="Products" m:HttpMethod="GET"><Parameter Name="rating" Type="Edm.Int16"
130
+ Nullable="false" /></FunctionImport><AssociationSet Name="Products_Advertisement_Advertisements"
131
+ Association="ODataDemo.FeaturedProduct_Advertisement_Advertisement_FeaturedProduct"><End
132
+ Role="FeaturedProduct_Advertisement" EntitySet="Products" /><End Role="Advertisement_FeaturedProduct"
133
+ EntitySet="Advertisements" /></AssociationSet><AssociationSet Name="Products_Categories_Categories"
134
+ Association="ODataDemo.Product_Categories_Category_Products"><End Role="Product_Categories"
135
+ EntitySet="Products" /><End Role="Category_Products" EntitySet="Categories"
136
+ /></AssociationSet><AssociationSet Name="Products_Supplier_Suppliers" Association="ODataDemo.Product_Supplier_Supplier_Products"><End
137
+ Role="Product_Supplier" EntitySet="Products" /><End Role="Supplier_Products"
138
+ EntitySet="Suppliers" /></AssociationSet><AssociationSet Name="Products_ProductDetail_ProductDetails"
139
+ Association="ODataDemo.Product_ProductDetail_ProductDetail_Product"><End Role="Product_ProductDetail"
140
+ EntitySet="Products" /><End Role="ProductDetail_Product" EntitySet="ProductDetails"
141
+ /></AssociationSet><AssociationSet Name="Persons_PersonDetail_PersonDetails"
142
+ Association="ODataDemo.Person_PersonDetail_PersonDetail_Person"><End Role="Person_PersonDetail"
143
+ EntitySet="Persons" /><End Role="PersonDetail_Person" EntitySet="PersonDetails"
144
+ /></AssociationSet></EntityContainer><Annotations Target="ODataDemo.DemoService"><ValueAnnotation
145
+ Term="Org.OData.Display.V1.Description" String="This is a sample OData service
146
+ with vocabularies" /></Annotations><Annotations Target="ODataDemo.Product"><ValueAnnotation
147
+ Term="Org.OData.Display.V1.Description" String="All Products available in
148
+ the online store" /></Annotations><Annotations Target="ODataDemo.Product/Name"><ValueAnnotation
149
+ Term="Org.OData.Display.V1.DisplayName" String="Product Name" /></Annotations><Annotations
150
+ Target="ODataDemo.DemoService/Suppliers"><ValueAnnotation Term="Org.OData.Publication.V1.PublisherName"
151
+ String="Microsoft Corp." /><ValueAnnotation Term="Org.OData.Publication.V1.PublisherId"
152
+ String="MSFT" /><ValueAnnotation Term="Org.OData.Publication.V1.Keywords"
153
+ String="Inventory, Supplier, Advertisers, Sales, Finance" /><ValueAnnotation
154
+ Term="Org.OData.Publication.V1.AttributionUrl" String="http://www.odata.org/"
155
+ /><ValueAnnotation Term="Org.OData.Publication.V1.AttributionDescription"
156
+ String="All rights reserved" /><ValueAnnotation Term="Org.OData.Publication.V1.DocumentationUrl
157
+ " String="http://www.odata.org/" /><ValueAnnotation Term="Org.OData.Publication.V1.TermsOfUseUrl"
158
+ String="All rights reserved" /><ValueAnnotation Term="Org.OData.Publication.V1.PrivacyPolicyUrl"
159
+ String="http://www.odata.org/" /><ValueAnnotation Term="Org.OData.Publication.V1.LastModified"
160
+ String="4/2/2013" /><ValueAnnotation Term="Org.OData.Publication.V1.ImageUrl
161
+ " String="http://www.odata.org/" /></Annotations></Schema></edmx:DataServices></edmx:Edmx>
162
+ http_version: '1.1'
163
+ adapter_metadata:
164
+ effective_url: http://services.odata.org/OData/OData.svc/$metadata
165
+ recorded_at: Tue, 30 Sep 2014 21:24:52 GMT
166
+ - request:
167
+ method: get
168
+ uri: http://services.odata.org/OData/OData.svc/Products?$top=1
169
+ body:
170
+ encoding: US-ASCII
171
+ string: ''
172
+ headers:
173
+ User-Agent:
174
+ - Typhoeus - https://github.com/typhoeus/typhoeus
175
+ DataServiceVersion:
176
+ - '3.0'
177
+ response:
178
+ status:
179
+ code: 200
180
+ message: OK
181
+ headers:
182
+ Cache-Control:
183
+ - no-cache
184
+ Content-Length:
185
+ - '2266'
186
+ Content-Type:
187
+ - application/atom+xml;type=feed;charset=utf-8
188
+ Server:
189
+ - Microsoft-IIS/8.0
190
+ X-Content-Type-Options:
191
+ - nosniff
192
+ DataServiceVersion:
193
+ - 3.0;
194
+ X-AspNet-Version:
195
+ - 4.0.30319
196
+ X-Powered-By:
197
+ - ASP.NET
198
+ Access-Control-Allow-Origin:
199
+ - "*"
200
+ Access-Control-Allow-Methods:
201
+ - GET
202
+ Access-Control-Allow-Headers:
203
+ - Accept, Origin, Content-Type, MaxDataServiceVersion
204
+ Access-Control-Expose-Headers:
205
+ - DataServiceVersion
206
+ Set-Cookie:
207
+ - ARRAffinity=cb44902b614a02a3a0dc1bccc3de360d89b180ff17e14b11fd9b289a8de75827;Path=/;Domain=services.odata.org
208
+ Date:
209
+ - Tue, 30 Sep 2014 23:01:09 GMT
210
+ body:
211
+ encoding: UTF-8
212
+ string: <?xml version="1.0" encoding="utf-8"?><feed xml:base="http://services.odata.org/OData/OData.svc/"
213
+ xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
214
+ xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss"
215
+ xmlns:gml="http://www.opengis.net/gml"><id>http://services.odata.org/OData/OData.svc/Products</id><title
216
+ type="text">Products</title><updated>2014-09-30T23:01:09Z</updated><link rel="self"
217
+ title="Products" href="Products" /><entry><id>http://services.odata.org/OData/OData.svc/Products(0)</id><category
218
+ term="ODataDemo.Product" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"
219
+ /><link rel="edit" title="Product" href="Products(0)" /><link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Categories"
220
+ type="application/atom+xml;type=feed" title="Categories" href="Products(0)/Categories"
221
+ /><link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Supplier"
222
+ type="application/atom+xml;type=entry" title="Supplier" href="Products(0)/Supplier"
223
+ /><link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ProductDetail"
224
+ type="application/atom+xml;type=entry" title="ProductDetail" href="Products(0)/ProductDetail"
225
+ /><title type="text">Bread</title><summary type="text">Whole grain bread</summary><updated>2014-09-30T23:01:09Z</updated><author><name
226
+ /></author><link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/relatedlinks/Categories"
227
+ type="application/xml" title="Categories" href="Products(0)/$links/Categories"
228
+ /><link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/relatedlinks/Supplier"
229
+ type="application/xml" title="Supplier" href="Products(0)/$links/Supplier"
230
+ /><link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/relatedlinks/ProductDetail"
231
+ type="application/xml" title="ProductDetail" href="Products(0)/$links/ProductDetail"
232
+ /><content type="application/xml"><m:properties><d:ID m:type="Edm.Int32">0</d:ID><d:ReleaseDate
233
+ m:type="Edm.DateTime">1992-01-01T00:00:00</d:ReleaseDate><d:DiscontinuedDate
234
+ m:null="true" /><d:Rating m:type="Edm.Int16">4</d:Rating><d:Price m:type="Edm.Double">2.5</d:Price></m:properties></content></entry></feed>
235
+ http_version: '1.1'
236
+ adapter_metadata:
237
+ effective_url: http://services.odata.org/OData/OData.svc/Products?$top=1
238
+ recorded_at: Tue, 30 Sep 2014 23:01:09 GMT
239
+ - request:
240
+ method: get
241
+ uri: http://services.odata.org/OData/OData.svc/Products(0)/Categories
242
+ body:
243
+ encoding: US-ASCII
244
+ string: ''
245
+ headers:
246
+ User-Agent:
247
+ - Typhoeus - https://github.com/typhoeus/typhoeus
248
+ DataServiceVersion:
249
+ - '3.0'
250
+ response:
251
+ status:
252
+ code: 200
253
+ message: OK
254
+ headers:
255
+ Cache-Control:
256
+ - no-cache
257
+ Content-Length:
258
+ - '1367'
259
+ Content-Type:
260
+ - application/atom+xml;type=feed;charset=utf-8
261
+ Server:
262
+ - Microsoft-IIS/8.0
263
+ X-Content-Type-Options:
264
+ - nosniff
265
+ DataServiceVersion:
266
+ - 3.0;
267
+ X-AspNet-Version:
268
+ - 4.0.30319
269
+ X-Powered-By:
270
+ - ASP.NET
271
+ Access-Control-Allow-Origin:
272
+ - "*"
273
+ Access-Control-Allow-Methods:
274
+ - GET
275
+ Access-Control-Allow-Headers:
276
+ - Accept, Origin, Content-Type, MaxDataServiceVersion
277
+ Access-Control-Expose-Headers:
278
+ - DataServiceVersion
279
+ Set-Cookie:
280
+ - ARRAffinity=cb44902b614a02a3a0dc1bccc3de360d89b180ff17e14b11fd9b289a8de75827;Path=/;Domain=services.odata.org
281
+ Date:
282
+ - Wed, 01 Oct 2014 17:34:27 GMT
283
+ body:
284
+ encoding: UTF-8
285
+ string: <?xml version="1.0" encoding="utf-8"?><feed xml:base="http://services.odata.org/OData/OData.svc/"
286
+ xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
287
+ xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss"
288
+ xmlns:gml="http://www.opengis.net/gml"><id>http://services.odata.org/OData/OData.svc/Products(0)/Categories</id><title
289
+ type="text">Categories</title><updated>2014-10-01T17:34:28Z</updated><link
290
+ rel="self" title="Categories" href="Categories" /><entry><id>http://services.odata.org/OData/OData.svc/Categories(0)</id><category
291
+ term="ODataDemo.Category" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"
292
+ /><link rel="edit" title="Category" href="Categories(0)" /><link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Products"
293
+ type="application/atom+xml;type=feed" title="Products" href="Categories(0)/Products"
294
+ /><title type="text">Food</title><updated>2014-10-01T17:34:28Z</updated><author><name
295
+ /></author><link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/relatedlinks/Products"
296
+ type="application/xml" title="Products" href="Categories(0)/$links/Products"
297
+ /><content type="application/xml"><m:properties><d:ID m:type="Edm.Int32">0</d:ID><d:Name>Food</d:Name></m:properties></content></entry></feed>
298
+ http_version: '1.1'
299
+ adapter_metadata:
300
+ effective_url: http://services.odata.org/OData/OData.svc/Products(0)/Categories
301
+ recorded_at: Wed, 01 Oct 2014 17:34:28 GMT
302
+ - request:
303
+ method: get
304
+ uri: http://services.odata.org/OData/OData.svc/Products(0)/Supplier
305
+ body:
306
+ encoding: US-ASCII
307
+ string: ''
308
+ headers:
309
+ User-Agent:
310
+ - Typhoeus - https://github.com/typhoeus/typhoeus
311
+ DataServiceVersion:
312
+ - '3.0'
313
+ response:
314
+ status:
315
+ code: 200
316
+ message: OK
317
+ headers:
318
+ Cache-Control:
319
+ - no-cache
320
+ Content-Length:
321
+ - '1602'
322
+ Content-Type:
323
+ - application/atom+xml;type=entry;charset=utf-8
324
+ ETag:
325
+ - W/"0"
326
+ Server:
327
+ - Microsoft-IIS/8.0
328
+ X-Content-Type-Options:
329
+ - nosniff
330
+ DataServiceVersion:
331
+ - 3.0;
332
+ X-AspNet-Version:
333
+ - 4.0.30319
334
+ X-Powered-By:
335
+ - ASP.NET
336
+ Access-Control-Allow-Origin:
337
+ - "*"
338
+ Access-Control-Allow-Methods:
339
+ - GET
340
+ Access-Control-Allow-Headers:
341
+ - Accept, Origin, Content-Type, MaxDataServiceVersion
342
+ Access-Control-Expose-Headers:
343
+ - DataServiceVersion
344
+ Set-Cookie:
345
+ - ARRAffinity=cb44902b614a02a3a0dc1bccc3de360d89b180ff17e14b11fd9b289a8de75827;Path=/;Domain=services.odata.org
346
+ Date:
347
+ - Wed, 01 Oct 2014 17:34:27 GMT
348
+ body:
349
+ encoding: UTF-8
350
+ string: <?xml version="1.0" encoding="utf-8"?><entry xml:base="http://services.odata.org/OData/OData.svc/"
351
+ xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
352
+ xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss"
353
+ xmlns:gml="http://www.opengis.net/gml" m:etag="W/&quot;0&quot;"><id>http://services.odata.org/OData/OData.svc/Suppliers(1)</id><category
354
+ term="ODataDemo.Supplier" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"
355
+ /><link rel="edit" title="Supplier" href="Suppliers(1)" /><link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Products"
356
+ type="application/atom+xml;type=feed" title="Products" href="Suppliers(1)/Products"
357
+ /><title type="text">Tokyo Traders</title><updated>2014-10-01T17:34:28Z</updated><author><name
358
+ /></author><link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/relatedlinks/Products"
359
+ type="application/xml" title="Products" href="Suppliers(1)/$links/Products"
360
+ /><content type="application/xml"><m:properties><d:ID m:type="Edm.Int32">1</d:ID><d:Name>Tokyo
361
+ Traders</d:Name><d:Address m:type="ODataDemo.Address"><d:Street>NE 40th</d:Street><d:City>Redmond</d:City><d:State>WA</d:State><d:ZipCode>98052</d:ZipCode><d:Country>USA</d:Country></d:Address><d:Location
362
+ m:type="Edm.GeographyPoint"><gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326"><gml:pos>47.6472206115723
363
+ -122.107711791992</gml:pos></gml:Point></d:Location><d:Concurrency m:type="Edm.Int32">0</d:Concurrency></m:properties></content></entry>
364
+ http_version: '1.1'
365
+ adapter_metadata:
366
+ effective_url: http://services.odata.org/OData/OData.svc/Products(0)/Supplier
367
+ recorded_at: Wed, 01 Oct 2014 17:34:28 GMT
368
+ - request:
369
+ method: get
370
+ uri: http://services.odata.org/OData/OData.svc/Products(0)/ProductDetail
371
+ body:
372
+ encoding: US-ASCII
373
+ string: ''
374
+ headers:
375
+ User-Agent:
376
+ - Typhoeus - https://github.com/typhoeus/typhoeus
377
+ DataServiceVersion:
378
+ - '3.0'
379
+ response:
380
+ status:
381
+ code: 204
382
+ message: No Content
383
+ headers:
384
+ Cache-Control:
385
+ - no-cache
386
+ Server:
387
+ - Microsoft-IIS/8.0
388
+ X-Content-Type-Options:
389
+ - nosniff
390
+ DataServiceVersion:
391
+ - 3.0;
392
+ X-AspNet-Version:
393
+ - 4.0.30319
394
+ X-Powered-By:
395
+ - ASP.NET
396
+ Access-Control-Allow-Origin:
397
+ - "*"
398
+ Access-Control-Allow-Methods:
399
+ - GET
400
+ Access-Control-Allow-Headers:
401
+ - Accept, Origin, Content-Type, MaxDataServiceVersion
402
+ Access-Control-Expose-Headers:
403
+ - DataServiceVersion
404
+ Set-Cookie:
405
+ - ARRAffinity=cb44902b614a02a3a0dc1bccc3de360d89b180ff17e14b11fd9b289a8de75827;Path=/;Domain=services.odata.org
406
+ Date:
407
+ - Wed, 01 Oct 2014 17:41:03 GMT
408
+ body:
409
+ encoding: UTF-8
410
+ string: ''
411
+ http_version: '1.1'
412
+ adapter_metadata:
413
+ effective_url: http://services.odata.org/OData/OData.svc/Products(0)/ProductDetail
414
+ recorded_at: Wed, 01 Oct 2014 17:41:03 GMT
415
+ recorded_with: VCR 2.9.2
@@ -426,4 +426,55 @@ http_interactions:
426
426
  adapter_metadata:
427
427
  effective_url: http://services.odata.org/OData/OData.svc/Products
428
428
  recorded_at: Mon, 29 Sep 2014 04:25:33 GMT
429
+ - request:
430
+ method: get
431
+ uri: http://services.odata.org/OData/OData.svc/Products/$count
432
+ body:
433
+ encoding: US-ASCII
434
+ string: ''
435
+ headers:
436
+ User-Agent:
437
+ - Typhoeus - https://github.com/typhoeus/typhoeus
438
+ DataServiceVersion:
439
+ - '3.0'
440
+ response:
441
+ status:
442
+ code: 200
443
+ message: OK
444
+ headers:
445
+ Cache-Control:
446
+ - no-cache
447
+ Content-Length:
448
+ - '2'
449
+ Content-Type:
450
+ - text/plain;charset=utf-8
451
+ Server:
452
+ - Microsoft-IIS/8.0
453
+ X-Content-Type-Options:
454
+ - nosniff
455
+ DataServiceVersion:
456
+ - 2.0;
457
+ X-AspNet-Version:
458
+ - 4.0.30319
459
+ X-Powered-By:
460
+ - ASP.NET
461
+ Access-Control-Allow-Origin:
462
+ - "*"
463
+ Access-Control-Allow-Methods:
464
+ - GET
465
+ Access-Control-Allow-Headers:
466
+ - Accept, Origin, Content-Type, MaxDataServiceVersion
467
+ Access-Control-Expose-Headers:
468
+ - DataServiceVersion
469
+ Set-Cookie:
470
+ - ARRAffinity=cb44902b614a02a3a0dc1bccc3de360d89b180ff17e14b11fd9b289a8de75827;Path=/;Domain=services.odata.org
471
+ Date:
472
+ - Mon, 29 Sep 2014 20:25:02 GMT
473
+ body:
474
+ encoding: UTF-8
475
+ string: '11'
476
+ http_version: '1.1'
477
+ adapter_metadata:
478
+ effective_url: http://services.odata.org/OData/OData.svc/Products/$count
479
+ recorded_at: Mon, 29 Sep 2014 20:25:03 GMT
429
480
  recorded_with: VCR 2.9.2
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe OData::Association::End do
4
+ let(:subject) { OData::Association::End.new(options) }
5
+ let(:options) { { entity_type: 'Product', multiplicity: '1' } }
6
+
7
+ it { expect(subject).to respond_to(:entity_type) }
8
+ it { expect(subject).to respond_to(:multiplicity) }
9
+
10
+ describe '#new' do
11
+ it 'raises error without entity_type option' do
12
+ expect {
13
+ OData::Association::End.new(multiplicity: '1')
14
+ }.to raise_error(ArgumentError)
15
+ end
16
+
17
+ it 'raises error without multiplicity option' do
18
+ expect {
19
+ OData::Association::End.new(entity_type: 'Product')
20
+ }.to raise_error(ArgumentError)
21
+ end
22
+
23
+ it 'raises error with invalid multiplicity option' do
24
+ expect {
25
+ OData::Association::End.new(entity_type: 'Product', multiplicity: :invalid)
26
+ }.to raise_error(ArgumentError)
27
+ end
28
+ end
29
+
30
+ it { expect(OData::Association::End).to respond_to(:multiplicity_map) }
31
+ it { expect(OData::Association::End.multiplicity_map['1']).to eq(:one) }
32
+ it { expect(OData::Association::End.multiplicity_map['*']).to eq(:many) }
33
+ it { expect(OData::Association::End.multiplicity_map['0..1']).to eq(:zero_to_one) }
34
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe OData::Association::Proxy, vcr: {cassette_name: 'association_proxy_specs'} do
4
+ before :each do
5
+ OData::Service.open('http://services.odata.org/OData/OData.svc', name: 'ODataDemo')
6
+ end
7
+
8
+ let(:subject) { OData::Association::Proxy.new(entity) }
9
+ let(:entity) { OData::ServiceRegistry['ODataDemo']['Products'].first }
10
+
11
+ it { expect(subject).to respond_to(:size)}
12
+
13
+ describe '#[]' do
14
+ it { expect(subject).to respond_to(:[]) }
15
+ it { expect(subject['ProductDetail']).to be_a(OData::Entity) }
16
+ it { expect(subject['Categories']).to be_a(Enumerable) }
17
+ it { expect(subject['Categories'].first).to be_a(OData::Entity) }
18
+ end
19
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe OData::Association do
4
+ let(:subject) { OData::Association.new(name: 'Product_Categories_Category_Products') }
5
+ let(:product_end) { nil }
6
+ let(:category_end) { nil }
7
+
8
+ it { expect(subject).to respond_to(:name) }
9
+
10
+ it { expect(subject).to respond_to(:ends) }
11
+ it { expect(subject.ends).to be_a(Array) }
12
+
13
+ context 'when initialized' do
14
+ let(:subject) do
15
+ OData::Association.new(name: 'Product_Categories_Category_Products',
16
+ ends: {
17
+ 'Category_Products' => category_end,
18
+ 'Product_Categories' => product_end
19
+ })
20
+ end
21
+
22
+ it { expect(subject.name).to eq('Product_Categories_Category_Products') }
23
+ it { expect(subject.ends.size).to eq(2) }
24
+ end
25
+
26
+ context 'when initialized with too many ends' do
27
+ let(:subject) do
28
+ OData::Association.new(name: 'Product_Categories_Category_Products',
29
+ ends: {
30
+ 'Category_Products' => category_end,
31
+ 'Product_Categories' => product_end,
32
+ 'Invalid' => category_end
33
+ })
34
+ end
35
+
36
+ it { expect { subject }.to raise_error(ArgumentError) }
37
+ end
38
+
39
+ context 'when initialized without a name' do
40
+ let(:subject) do
41
+ OData::Association.new
42
+ end
43
+
44
+ it { expect { subject }.to raise_error(ArgumentError) }
45
+ end
46
+ end
@@ -19,6 +19,32 @@ describe OData::Entity, vcr: {cassette_name: 'entity_specs'} do
19
19
  it { expect(subject.namespace).to eq('ODataDemo') }
20
20
  it { expect(subject.service_name).to eq('ODataDemo') }
21
21
 
22
+ describe '#links' do
23
+ let(:subject) { OData::Entity.from_xml(product_xml, options) }
24
+ let(:product_xml) {
25
+ document = ::Nokogiri::XML(File.open('spec/fixtures/sample_service/product_0.xml'))
26
+ document.remove_namespaces!
27
+ document.xpath('//entry').first
28
+ }
29
+ let(:links) do
30
+ {
31
+ 'Categories' => {type: :feed, href: 'Products(0)/Categories'},
32
+ 'Supplier' => {type: :entry, href: 'Products(0)/Supplier'},
33
+ 'ProductDetail' => {type: :entry, href: 'Products(0)/ProductDetail'}
34
+ }
35
+ end
36
+
37
+ it { expect(subject).to respond_to(:links) }
38
+ it { expect(subject.links.size).to eq(3) }
39
+ it { expect(subject.links).to eq(links) }
40
+ end
41
+
42
+ describe '#associations' do
43
+ it { expect(subject).to respond_to(:associations) }
44
+ it { expect(subject.associations.size).to eq(3) }
45
+ it { expect {subject.associations['NonExistant']}.to raise_error(ArgumentError) }
46
+ end
47
+
22
48
  describe '.from_xml' do
23
49
  let(:subject) { OData::Entity.from_xml(product_xml, options) }
24
50
  let(:product_xml) {
@@ -99,4 +99,9 @@ describe OData::Query, vcr: {cassette_name: 'query_specs'} do
99
99
  describe '#execute' do
100
100
  it { expect(subject.execute).to be_a(OData::Query::Result) }
101
101
  end
102
+
103
+ it { expect(subject).to respond_to(:count) }
104
+ describe '#count' do
105
+ it { expect(subject.count).to be_a(Integer) }
106
+ end
102
107
  end
@@ -6,6 +6,11 @@ describe OData::Service, vcr: {cassette_name: 'service_specs'} do
6
6
  let(:entity_sets) { %w{Products ProductDetails Categories Suppliers Persons PersonDetails Advertisements} }
7
7
  let(:entity_set_types) { %w{Product ProductDetail Category Supplier Person PersonDetail Advertisement} }
8
8
  let(:complex_types) { %w{Address} }
9
+ let(:associations) { %w{Product_Categories_Category_Products
10
+ Product_Supplier_Supplier_Products
11
+ Product_ProductDetail_ProductDetail_Product
12
+ FeaturedProduct_Advertisement_Advertisement_FeaturedProduct
13
+ Person_PersonDetail_PersonDetail_Person} }
9
14
 
10
15
  describe '.open' do
11
16
  it { expect(OData::Service).to respond_to(:open) }
@@ -26,6 +31,7 @@ describe OData::Service, vcr: {cassette_name: 'service_specs'} do
26
31
  it { expect(subject).to respond_to(:entity_types) }
27
32
  it { expect(subject).to respond_to(:entity_sets) }
28
33
  it { expect(subject).to respond_to(:complex_types) }
34
+ it { expect(subject).to respond_to(:associations) }
29
35
  it { expect(subject).to respond_to(:namespace) }
30
36
  end
31
37
 
@@ -49,6 +55,22 @@ describe OData::Service, vcr: {cassette_name: 'service_specs'} do
49
55
  it { expect(subject.complex_types).to eq(complex_types) }
50
56
  end
51
57
 
58
+ describe '#associations' do
59
+ it { expect(subject.associations.size).to eq(5) }
60
+ it { expect(subject.associations.keys).to eq(associations) }
61
+ it do
62
+ subject.associations.each do |name, association|
63
+ expect(association).to be_a(OData::Association)
64
+ end
65
+ end
66
+ end
67
+
68
+ describe '#navigation_properties' do
69
+ it { expect(subject).to respond_to(:navigation_properties) }
70
+ it { expect(subject.navigation_properties['Product'].size).to eq(3) }
71
+ it { expect(subject.navigation_properties['Product']['Categories']).to be_a(OData::Association) }
72
+ end
73
+
52
74
  describe '#namespace' do
53
75
  it { expect(subject.namespace).to eq('ODataDemo') }
54
76
  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.8
4
+ version: 0.6.0
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-09-29 00:00:00.000000000 Z
11
+ date: 2014-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,6 +80,34 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: 3.0.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec-autotest
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 1.0.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 1.0.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: autotest
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 4.4.6
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 4.4.6
83
111
  - !ruby/object:Gem::Dependency
84
112
  name: vcr
85
113
  requirement: !ruby/object:Gem::Requirement
@@ -143,6 +171,7 @@ executables: []
143
171
  extensions: []
144
172
  extra_rdoc_files: []
145
173
  files:
174
+ - ".autotest"
146
175
  - ".gitignore"
147
176
  - ".rspec"
148
177
  - ".ruby-version"
@@ -153,6 +182,9 @@ files:
153
182
  - README.md
154
183
  - Rakefile
155
184
  - lib/odata.rb
185
+ - lib/odata/association.rb
186
+ - lib/odata/association/end.rb
187
+ - lib/odata/association/proxy.rb
156
188
  - lib/odata/complex_type.rb
157
189
  - lib/odata/entity.rb
158
190
  - lib/odata/entity_set.rb
@@ -191,6 +223,7 @@ files:
191
223
  - spec/fixtures/sample_service/products_skip10_top5.xml
192
224
  - spec/fixtures/sample_service/products_skip5_top5.xml
193
225
  - spec/fixtures/sample_service/supplier_0.xml
226
+ - spec/fixtures/vcr_cassettes/association_proxy_specs.yml
194
227
  - spec/fixtures/vcr_cassettes/complex_type_specs.yml
195
228
  - spec/fixtures/vcr_cassettes/entity_set_specs.yml
196
229
  - spec/fixtures/vcr_cassettes/entity_set_specs/bad_entry.yml
@@ -201,6 +234,9 @@ files:
201
234
  - spec/fixtures/vcr_cassettes/query_specs.yml
202
235
  - spec/fixtures/vcr_cassettes/service_registry_specs.yml
203
236
  - spec/fixtures/vcr_cassettes/service_specs.yml
237
+ - spec/odata/association/end_spec.rb
238
+ - spec/odata/association/proxy_spec.rb
239
+ - spec/odata/association_spec.rb
204
240
  - spec/odata/complex_type_spec.rb
205
241
  - spec/odata/entity_set_spec.rb
206
242
  - spec/odata/entity_spec.rb
@@ -259,6 +295,7 @@ test_files:
259
295
  - spec/fixtures/sample_service/products_skip10_top5.xml
260
296
  - spec/fixtures/sample_service/products_skip5_top5.xml
261
297
  - spec/fixtures/sample_service/supplier_0.xml
298
+ - spec/fixtures/vcr_cassettes/association_proxy_specs.yml
262
299
  - spec/fixtures/vcr_cassettes/complex_type_specs.yml
263
300
  - spec/fixtures/vcr_cassettes/entity_set_specs.yml
264
301
  - spec/fixtures/vcr_cassettes/entity_set_specs/bad_entry.yml
@@ -269,6 +306,9 @@ test_files:
269
306
  - spec/fixtures/vcr_cassettes/query_specs.yml
270
307
  - spec/fixtures/vcr_cassettes/service_registry_specs.yml
271
308
  - spec/fixtures/vcr_cassettes/service_specs.yml
309
+ - spec/odata/association/end_spec.rb
310
+ - spec/odata/association/proxy_spec.rb
311
+ - spec/odata/association_spec.rb
272
312
  - spec/odata/complex_type_spec.rb
273
313
  - spec/odata/entity_set_spec.rb
274
314
  - spec/odata/entity_spec.rb