odata 0.5.8 → 0.6.0

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: 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