ruby_odata 0.0.1 → 0.0.2

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.
data/.gitignore CHANGED
@@ -6,4 +6,5 @@ tmp/*
6
6
  .eprj
7
7
  test/SampleService/App_Data/TestDB.mdf
8
8
  test/SampleService/App_Data/TestDB_Log.ldf
9
- pkg/*
9
+ pkg/*
10
+ doc/*
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,10 @@
1
+ = ruby_odata Change Log
2
+
3
+ == 0.0.1
4
+ * Basic CRUD Operations
5
+ * Query: Filters
6
+ * Query: Expands
7
+
8
+ == 0.0.2
9
+ * Query: Order By
10
+
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.2
@@ -0,0 +1,96 @@
1
+ Feature: Query Builder
2
+ In order to query OData services
3
+ As a user
4
+ I want to be able to perform valid OData protocol operations
5
+
6
+ Background:
7
+ Given an ODataService exists with uri: "http://localhost:8888/SampleService/Entities.svc"
8
+ And blueprints exist for the service
9
+
10
+ # Expand
11
+ Scenario: Navigation Properties should be able to be eager loaded
12
+ Given I call "AddToCategories" on the service with a new "Category" object with Name: "Test Category"
13
+ And I save changes
14
+ And I call "AddToProducts" on the service with a new "Product" object with Category: "@@LastSave"
15
+ And I save changes
16
+ And I call "Products" on the service with args: "1"
17
+ And I expand the query to include "Category"
18
+ When I run the query
19
+ Then the method "Category" on the result should be of type "Category"
20
+ And the method "Name" on the result's method "Category" should equal: "Test Category"
21
+ And the method "Id" on the result's method "Category" should equal: "1"
22
+
23
+
24
+ # Filter
25
+ Scenario: Filters should be allowed on the root level entity
26
+ Given I call "AddToProducts" on the service with a new "Product" object with Name: "Test Product"
27
+ When I save changes
28
+ When I call "Products" on the service
29
+ And I filter the query with: "Name eq 'Test Product'"
30
+ And I run the query
31
+ Then the method "Name" on the result should equal: "Test Product"
32
+
33
+
34
+ # Order By
35
+ Scenario: Order by should be allowed on the root level entity
36
+ Given the following Products exist:
37
+ | Name |
38
+ | Product 2 |
39
+ | Product 4 |
40
+ | Product 5 |
41
+ | Product 1 |
42
+ | Product 3 |
43
+ When I call "Products" on the service
44
+ And I order by: "Name"
45
+ And I run the query
46
+ Then the result should be:
47
+ | Name |
48
+ | Product 1 |
49
+ | Product 2 |
50
+ | Product 3 |
51
+ | Product 4 |
52
+ | Product 5 |
53
+
54
+ Scenario: Order by should accept sorting descending
55
+ Given the following Products exist:
56
+ | Name |
57
+ | Product 2 |
58
+ | Product 4 |
59
+ | Product 5 |
60
+ | Product 1 |
61
+ | Product 3 |
62
+ When I call "Products" on the service
63
+ And I order by: "Name desc"
64
+ And I run the query
65
+ Then the result should be:
66
+ | Name |
67
+ | Product 5 |
68
+ | Product 4 |
69
+ | Product 3 |
70
+ | Product 2 |
71
+ | Product 1 |
72
+
73
+ Scenario: Order by should access sorting acsending
74
+ Given the following Products exist:
75
+ | Name |
76
+ | Product 2 |
77
+ | Product 4 |
78
+ | Product 5 |
79
+ | Product 1 |
80
+ | Product 3 |
81
+ When I call "Products" on the service
82
+ And I order by: "Name asc"
83
+ And I run the query
84
+ Then the result should be:
85
+ | Name |
86
+ | Product 1 |
87
+ | Product 2 |
88
+ | Product 3 |
89
+ | Product 4 |
90
+ | Product 5 |
91
+
92
+
93
+
94
+
95
+
96
+
@@ -47,36 +47,3 @@ Scenario: Navigation Properties should be included in results
47
47
  Then the result should have a method: "Category"
48
48
  And the method "Category" on the result should be nil
49
49
 
50
- Scenario: Navigation Properties should be able to be eager loaded
51
- Given I call "AddToCategories" on the service with a new "Category" object with Name: "Test Category"
52
- And I save changes
53
- And I call "AddToProducts" on the service with a new "Product" object with Category: "@@LastSave"
54
- And I save changes
55
- And I call "Products" on the service with args: "1"
56
- And I expand the query to include "Category"
57
- When I run the query
58
- Then the method "Category" on the result should be of type "Category"
59
- And the method "Name" on the result's method "Category" should equal: "Test Category"
60
- And the method "Id" on the result's method "Category" should equal: "1"
61
-
62
- Scenario: Filters should be allowed on the root level entity
63
- Given I call "AddToProducts" on the service with a new "Product" object with Name: "Test Product"
64
- When I save changes
65
- When I call "Products" on the service
66
- And I filter the query with: "Name eq 'Test Product'"
67
- And I run the query
68
- Then the method "Name" on the result should equal: "Test Product"
69
-
70
-
71
-
72
-
73
-
74
-
75
-
76
-
77
-
78
-
79
-
80
-
81
-
82
-
@@ -58,6 +58,10 @@ When /^I filter the query with: "([^\"]*)"$/ do |filter|
58
58
  @service_query.filter(filter)
59
59
  end
60
60
 
61
+ When /^I order by: "([^\"]*)"$/ do |order|
62
+ @service_query.order_by(order)
63
+ end
64
+
61
65
 
62
66
  Then /^the method "([^\"]*)" on the result should be of type "([^\"]*)"$/ do |method, type|
63
67
  result = @service_result.send(method.to_sym)
@@ -126,6 +130,37 @@ Then /^no "([^\"]*)" should exist$/ do |collection|
126
130
  results.should == []
127
131
  end
128
132
 
133
+ Given /^the following (.*) exist:$/ do |plural_factory, table|
134
+ # table is a Cucumber::Ast::Table
135
+ factory = plural_factory.singularize
136
+ table.hashes.map do |hash|
137
+ obj = factory.constantize.send(:make, hash)
138
+ @service.send("AddTo#{plural_factory}", obj)
139
+ @service.save_changes
140
+ end
141
+ end
142
+
143
+ Then /^the result should be:$/ do |table|
144
+ # table is a Cucumber::Ast::Table
145
+
146
+ fields = table.hashes[0].keys
147
+
148
+ # Build an array of hashes so that we can compare tables
149
+ results = []
150
+
151
+ @service_result.each do |result|
152
+ obj_hash = Hash.new
153
+ fields.each do |field|
154
+ obj_hash[field] = result.send(field)
155
+ end
156
+ results << obj_hash
157
+ end
158
+
159
+ result_table = Cucumber::Ast::Table.new(results)
160
+
161
+ table.diff!(result_table)
162
+ end
163
+
129
164
  Then /^the method "([^\"]*)" on the result's method "([^\"]*)" should equal: "([^\"]*)"$/ do |method, result_method, value|
130
165
  obj = @service_result.send(result_method.to_sym)
131
166
  obj.send(method.to_sym).should == value
@@ -14,6 +14,7 @@ class QueryBuilder
14
14
  @root = root.to_s
15
15
  @expands = []
16
16
  @filters = []
17
+ @order_bys = []
17
18
  end
18
19
 
19
20
  # Used to eagerly-load data for nested objects, for example, obtaining a Category for a Product within one call to the server
@@ -39,12 +40,24 @@ class QueryBuilder
39
40
  #
40
41
  # ==== Example
41
42
  # svc.Products.filter("Name eq 'Product 2'")
42
- # prod = svc.execute
43
+ # products = svc.execute
43
44
  def filter(filter)
44
45
  @filters << CGI.escape(filter)
45
46
  self
46
47
  end
47
48
 
49
+ # Used to order the data being returned
50
+ # ==== Required Attributes
51
+ # - order_by: The order by statement. Note to specify direction, use "desc" or "asc"; must be lowercase
52
+ #
53
+ # ==== Example
54
+ # svc.Products.order_by("Name")
55
+ # products = svc.execute
56
+ def order_by(order_by)
57
+ @order_bys << CGI.escape(order_by)
58
+ self
59
+ end
60
+
48
61
  # Builds the query URI (path, not including root) incorporating expands, filters, etc.
49
62
  # This is used internally when the execute method is called on the service
50
63
  def query
@@ -52,6 +65,7 @@ class QueryBuilder
52
65
  query_options = []
53
66
  query_options << "$expand=#{@expands.join(',')}" unless @expands.empty?
54
67
  query_options << "$filter=#{@filters.join('+and+')}" unless @filters.empty?
68
+ query_options << "$orderby=#{@order_bys.join(',')}" unless @order_bys.empty?
55
69
  if !query_options.empty?
56
70
  q << "?"
57
71
  q << query_options.join('&')
data/ruby_odata.gemspec CHANGED
@@ -5,41 +5,27 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ruby_odata}
8
- s.version = "0.0.1"
8
+ s.version = "0.0.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Damien White"]
12
- s.date = %q{2010-06-11}
12
+ s.date = %q{2010-06-12}
13
13
  s.description = %q{An OData Client Library for Ruby. Use this to interact with OData services}
14
14
  s.email = %q{damien.white@visoftinc.com}
15
15
  s.extra_rdoc_files = [
16
- "LICENSE",
16
+ "CHANGELOG.rdoc",
17
+ "LICENSE",
17
18
  "README.rdoc"
18
19
  ]
19
20
  s.files = [
20
21
  ".gitignore",
22
+ "CHANGELOG.rdoc",
21
23
  "LICENSE",
22
24
  "README.rdoc",
23
25
  "Rakefile",
24
26
  "VERSION",
25
27
  "config/cucumber.yml",
26
- "doc/classes/OData.html",
27
- "doc/classes/OData/ClassBuilder.html",
28
- "doc/classes/OData/Operation.html",
29
- "doc/classes/OData/QueryBuilder.html",
30
- "doc/classes/OData/Service.html",
31
- "doc/created.rid",
32
- "doc/files/README_rdoc.html",
33
- "doc/files/lib/odata_ruby/class_builder_rb.html",
34
- "doc/files/lib/odata_ruby/operation_rb.html",
35
- "doc/files/lib/odata_ruby/query_builder_rb.html",
36
- "doc/files/lib/odata_ruby/service_rb.html",
37
- "doc/files/lib/odata_ruby_rb.html",
38
- "doc/fr_class_index.html",
39
- "doc/fr_file_index.html",
40
- "doc/fr_method_index.html",
41
- "doc/index.html",
42
- "doc/rdoc-style.css",
28
+ "features/query_builder.feature",
43
29
  "features/service.feature",
44
30
  "features/service_manage.feature",
45
31
  "features/step_definitions/service_steps.rb",
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_odata
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Damien White
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-06-11 00:00:00 -04:00
18
+ date: 2010-06-12 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -73,32 +73,18 @@ executables: []
73
73
  extensions: []
74
74
 
75
75
  extra_rdoc_files:
76
+ - CHANGELOG.rdoc
76
77
  - LICENSE
77
78
  - README.rdoc
78
79
  files:
79
80
  - .gitignore
81
+ - CHANGELOG.rdoc
80
82
  - LICENSE
81
83
  - README.rdoc
82
84
  - Rakefile
83
85
  - VERSION
84
86
  - config/cucumber.yml
85
- - doc/classes/OData.html
86
- - doc/classes/OData/ClassBuilder.html
87
- - doc/classes/OData/Operation.html
88
- - doc/classes/OData/QueryBuilder.html
89
- - doc/classes/OData/Service.html
90
- - doc/created.rid
91
- - doc/files/README_rdoc.html
92
- - doc/files/lib/odata_ruby/class_builder_rb.html
93
- - doc/files/lib/odata_ruby/operation_rb.html
94
- - doc/files/lib/odata_ruby/query_builder_rb.html
95
- - doc/files/lib/odata_ruby/service_rb.html
96
- - doc/files/lib/odata_ruby_rb.html
97
- - doc/fr_class_index.html
98
- - doc/fr_file_index.html
99
- - doc/fr_method_index.html
100
- - doc/index.html
101
- - doc/rdoc-style.css
87
+ - features/query_builder.feature
102
88
  - features/service.feature
103
89
  - features/service_manage.feature
104
90
  - features/step_definitions/service_steps.rb
@@ -1,126 +0,0 @@
1
- <?xml version="1.0" encoding="iso-8859-1"?>
2
- <!DOCTYPE html
3
- PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
-
6
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
- <head>
8
- <title>Module: OData</title>
9
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
- <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
- <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
12
- <script type="text/javascript">
13
- // <![CDATA[
14
-
15
- function popupCode( url ) {
16
- window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
- }
18
-
19
- function toggleCode( id ) {
20
- if ( document.getElementById )
21
- elem = document.getElementById( id );
22
- else if ( document.all )
23
- elem = eval( "document.all." + id );
24
- else
25
- return false;
26
-
27
- elemStyle = elem.style;
28
-
29
- if ( elemStyle.display != "block" ) {
30
- elemStyle.display = "block"
31
- } else {
32
- elemStyle.display = "none"
33
- }
34
-
35
- return true;
36
- }
37
-
38
- // Make codeblocks hidden by default
39
- document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
-
41
- // ]]>
42
- </script>
43
-
44
- </head>
45
- <body>
46
-
47
-
48
-
49
- <div id="classHeader">
50
- <table class="header-table">
51
- <tr class="top-aligned-row">
52
- <td><strong>Module</strong></td>
53
- <td class="class-name-in-header">OData</td>
54
- </tr>
55
- <tr class="top-aligned-row">
56
- <td><strong>In:</strong></td>
57
- <td>
58
- <a href="../files/lib/odata_ruby/class_builder_rb.html">
59
- lib/odata_ruby/class_builder.rb
60
- </a>
61
- <br />
62
- <a href="../files/lib/odata_ruby/operation_rb.html">
63
- lib/odata_ruby/operation.rb
64
- </a>
65
- <br />
66
- <a href="../files/lib/odata_ruby/query_builder_rb.html">
67
- lib/odata_ruby/query_builder.rb
68
- </a>
69
- <br />
70
- <a href="../files/lib/odata_ruby/service_rb.html">
71
- lib/odata_ruby/service.rb
72
- </a>
73
- <br />
74
- </td>
75
- </tr>
76
-
77
- </table>
78
- </div>
79
- <!-- banner header -->
80
-
81
- <div id="bodyContent">
82
-
83
-
84
-
85
- <div id="contextContent">
86
-
87
-
88
-
89
- </div>
90
-
91
-
92
- </div>
93
-
94
-
95
- <!-- if includes -->
96
-
97
- <div id="section">
98
-
99
- <div id="class-list">
100
- <h3 class="section-bar">Classes and Modules</h3>
101
-
102
- Class <a href="OData/ClassBuilder.html" class="link">OData::ClassBuilder</a><br />
103
- Class <a href="OData/Operation.html" class="link">OData::Operation</a><br />
104
- Class <a href="OData/QueryBuilder.html" class="link">OData::QueryBuilder</a><br />
105
- Class <a href="OData/Service.html" class="link">OData::Service</a><br />
106
-
107
- </div>
108
-
109
-
110
-
111
-
112
-
113
-
114
-
115
- <!-- if method_list -->
116
-
117
-
118
- </div>
119
-
120
-
121
- <div id="validator-badges">
122
- <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
123
- </div>
124
-
125
- </body>
126
- </html>