ruby_odata 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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>