wrest 0.0.5 → 0.0.6
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/README.rdoc +31 -17
- data/Rakefile +147 -134
- data/VERSION.yml +1 -1
- data/bin/jwrest +3 -0
- data/bin/wrest +1 -20
- data/bin/wrest_shell.rb +21 -0
- data/lib/wrest/components.rb +4 -1
- data/lib/wrest/components/attributes_container.rb +65 -10
- data/lib/wrest/{translators/xml.rb → components/mutators.rb} +11 -13
- data/lib/wrest/components/mutators/base.rb +43 -0
- data/lib/wrest/components/mutators/camel_to_snake_case.rb +20 -0
- data/lib/wrest/components/mutators/xml_simple_type_caster.rb +35 -0
- data/lib/wrest/{translators.rb → components/translators.rb} +6 -7
- data/lib/wrest/{translators → components/translators}/content_types.rb +5 -5
- data/lib/wrest/components/translators/json.rb +22 -0
- data/lib/wrest/components/translators/xml.rb +26 -0
- data/lib/wrest/components/typecast_helpers.rb +41 -0
- data/lib/wrest/core_ext/hash.rb +5 -0
- data/lib/wrest/core_ext/hash/conversions.rb +44 -0
- data/lib/wrest/exceptions.rb +6 -1
- data/lib/wrest/exceptions/method_not_overridden_exception.rb +17 -0
- data/lib/wrest/exceptions/unsupported_content_type_exception.rb +11 -9
- data/lib/wrest/resource/base.rb +5 -1
- data/lib/wrest/response.rb +2 -2
- data/lib/wrest/uri.rb +3 -3
- data/lib/wrest/version.rb +1 -1
- data/spec/spec_helper.rb +2 -1
- data/spec/wrest/components/attributes_container_spec.rb +66 -11
- data/spec/wrest/components/mutators/base_spec.rb +38 -0
- data/spec/wrest/components/mutators/camel_to_snake_spec.rb +22 -0
- data/spec/wrest/components/mutators/xml_simple_type_caster_spec.rb +47 -0
- data/spec/wrest/{translators → components/translators}/xml_spec.rb +3 -3
- data/spec/wrest/components/translators_spec.rb +9 -0
- data/spec/wrest/core_ext/hash/conversions_spec.rb +22 -0
- data/{lib/wrest/translators/json.rb → spec/wrest/core_ext/string/conversions_spec.rb} +4 -9
- data/spec/wrest/resource/base_spec.rb +1 -1
- data/spec/wrest/response_spec.rb +3 -3
- data/spec/wrest/uri_spec.rb +2 -2
- metadata +34 -19
- data/lib/wrest/translators/typed_hash.rb +0 -4
- data/spec/wrest/core_ext/string_spec.rb +0 -7
- data/spec/wrest/translators/typed_hash_spec.rb +0 -9
- data/spec/wrest/translators_spec.rb +0 -9
data/README.rdoc
CHANGED
@@ -2,7 +2,9 @@
|
|
2
2
|
|
3
3
|
(c) Copyright 2009 {Sidu Ponnappa}[http://blog.sidu.in]. All Rights Reserved.
|
4
4
|
|
5
|
-
Wrest is a ruby REST client library which allows you to quickly build object oriented wrappers around any web service. It has two components - Wrest Core and Wrest::Resource.
|
5
|
+
Wrest is a ruby REST client library which allows you to quickly build object oriented wrappers around any web service. It has two components - Wrest Core and Wrest::Resource.
|
6
|
+
|
7
|
+
Since no single framework can provide an object oriented wrapper suitable for _all_ available web services, it follows that Wrest should focus on providing you with the tools to help you roll your own with ease. Wrest::Resource is an example of this - an object oriented wrapper for the kind of REST APIs exposed by Rails applications built using Wrest Core.
|
6
8
|
|
7
9
|
== Installation
|
8
10
|
|
@@ -10,13 +12,12 @@ The source is available at git://github.com/kaiwren/wrest.git
|
|
10
12
|
|
11
13
|
To install as a Rails plugin, do <tt>script/plugin install git://github.com/kaiwren/wrest.git</tt>
|
12
14
|
|
13
|
-
To install the Wrest gem, do <tt>sudo gem install wrest</tt
|
15
|
+
To install the Wrest gem, do <tt>sudo gem install wrest</tt>; Wrest is also available as a gem for JRuby using the same command.
|
14
16
|
|
15
17
|
== Wrest Core
|
16
18
|
|
17
19
|
* Designed to be used as a library, not just a command line REST client
|
18
|
-
* Provides
|
19
|
-
* Makes it easy to extend and modify both serialisation, deserialisation and object creation
|
20
|
+
* Provides infrastructure components such as convenient HTTP wrappers api, caching, redirect handling, serialisation, deserialisation etc.
|
20
21
|
* Isn't coupled to Rails (usable in a pure Ruby application to consume any REST api)
|
21
22
|
* Can be used both stand alone as well as to build object oriented abstractions around web services (Wrest::Resource is an example of the latter)
|
22
23
|
|
@@ -46,14 +47,22 @@ A couple of ways to get the Yahoo news as hash map (needs the JSON gem - gem ins
|
|
46
47
|
* This example simply does a get on a uri and figures out the appropriate deserialiser using the content-type (in this case 'text/javascript', which uses Wrest::Translators::Json). See content_types.rb under lib/wrest/mappers/translators.
|
47
48
|
"http://search.yahooapis.com/NewsSearchService/V1/newsSearch?appid=YahooDemo&output=json&query=India&results=3&start=1".to_uri.get.deserialise
|
48
49
|
|
49
|
-
* This example does a get on a base uri with several parameters passed to it, resulting in a uri essentially the same as the one above. It also shows how you can
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
50
|
+
* This example does a get on a base uri with several parameters passed to it, resulting in a uri essentially the same as the one above. It also shows how you can specify a custom deserialiser to produce a hash-map from the response, as well as a hash mutator to clean up the deserialised hash.
|
51
|
+
require 'rubygems'
|
52
|
+
require 'wrest'
|
53
|
+
|
54
|
+
include Wrest::Components
|
55
|
+
p "http://search.yahooapis.com/NewsSearchService/V1/newsSearch".to_uri.get(
|
56
|
+
:appid => 'YahooDemo',
|
57
|
+
:output => 'xml',
|
58
|
+
:query => 'India',
|
59
|
+
:results=> '3',
|
60
|
+
:start => '1'
|
61
|
+
).deserialise_using(
|
62
|
+
Translators::Xml
|
63
|
+
).mutate_using(
|
64
|
+
Mutators::XmlSimpleTypeCaster.new
|
65
|
+
)
|
57
66
|
|
58
67
|
|
59
68
|
=== Logging
|
@@ -67,12 +76,13 @@ Standard options are available and can be listed using <tt>rake -T</tt>. Use rak
|
|
67
76
|
|
68
77
|
== Documentation
|
69
78
|
|
70
|
-
Wrest RDocs can be found at http://wrest.rubyforge.org
|
79
|
+
Wrest RDocs can be found at http://wrest.rubyforge.org
|
71
80
|
|
72
81
|
== Wrest::Resource
|
73
82
|
|
74
|
-
Wrest::Resource is an alternative to ActiveResource
|
83
|
+
Wrest::Resource is an alternative to ActiveResource. It targets Rails REST services and is currently under development.
|
75
84
|
|
85
|
+
* No more pretending that REST resources are the same as database records
|
76
86
|
* Out of the box support for collections
|
77
87
|
* Out of the box support for collection pagination (including support for WillPaginate), both header based and xml attribute based
|
78
88
|
* Out of the box support for operations on all the records on the collection
|
@@ -85,13 +95,17 @@ Wrest::Resource is an alternative to ActiveResource which targets Rails REST ser
|
|
85
95
|
|
86
96
|
== Dependencies
|
87
97
|
|
98
|
+
=== Source
|
88
99
|
* gems
|
89
100
|
* xmlsimple
|
90
|
-
* json
|
91
|
-
* rspec
|
92
|
-
* rcov
|
101
|
+
* json (json-jruby on JRuby)
|
93
102
|
* active_support
|
94
103
|
|
104
|
+
=== Build
|
105
|
+
* rspec
|
106
|
+
* rcov (unsupported on JRuby)
|
107
|
+
* jeweler
|
108
|
+
|
95
109
|
== Support
|
96
110
|
|
97
111
|
This project uses Assembla for ticketing: http://www.assembla.com/spaces/wrest/tickets
|
data/Rakefile
CHANGED
@@ -7,13 +7,14 @@
|
|
7
7
|
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
8
8
|
# See the License for the specific language governing permissions and limitations under the License.
|
9
9
|
|
10
|
+
require 'rubygems'
|
10
11
|
gem 'rspec'
|
11
12
|
require 'rake'
|
12
|
-
require '
|
13
|
+
require 'hanna/rdoctask'
|
13
14
|
require 'spec'
|
14
15
|
require 'spec/rake/spectask'
|
15
|
-
|
16
|
-
|
16
|
+
|
17
|
+
puts "Building on Ruby #{RUBY_VERSION}, #{RUBY_RELEASE_DATE}, #{RUBY_PLATFORM}"
|
17
18
|
|
18
19
|
desc 'Default: run spec tests.'
|
19
20
|
task :default => :spec
|
@@ -27,21 +28,27 @@ end
|
|
27
28
|
desc 'Generate documentation for Wrest'
|
28
29
|
Rake::RDocTask.new(:rdoc) do |rdoc|
|
29
30
|
rdoc.rdoc_dir = 'rdoc'
|
30
|
-
rdoc.title = '
|
31
|
+
rdoc.title = 'Wrest Documentation'
|
31
32
|
rdoc.options << '--line-numbers' << '--inline-source'
|
32
33
|
rdoc.rdoc_files.include('README.rdoc')
|
33
34
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
34
35
|
end
|
35
36
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
37
|
+
begin
|
38
|
+
require 'rcov'
|
39
|
+
require 'rcov/rcovtask'
|
40
|
+
desc "Run all specs in spec directory with RCov"
|
41
|
+
Spec::Rake::SpecTask.new(:rcov) do |t|
|
42
|
+
t.spec_opts = ['--options', "spec/spec.opts"]
|
43
|
+
t.spec_files = FileList["spec/wrest/**/*_spec.rb"]
|
44
|
+
t.rcov = true
|
45
|
+
t.rcov_opts = lambda do
|
46
|
+
IO.readlines("spec/rcov.opts").map {|l| l.chomp.split " "}.flatten
|
47
|
+
end
|
48
|
+
# t.verbose = true
|
43
49
|
end
|
44
|
-
|
50
|
+
rescue LoadError
|
51
|
+
puts "Rcov not available."
|
45
52
|
end
|
46
53
|
|
47
54
|
begin
|
@@ -55,14 +62,20 @@ begin
|
|
55
62
|
gemspec.homepage = "http://github.com/kaiwren/wrest"
|
56
63
|
gemspec.has_rdoc = true
|
57
64
|
gemspec.rubyforge_project = 'wrest'
|
58
|
-
gemspec.platform = Gem::Platform::RUBY
|
59
65
|
gemspec.executables = ['wrest']
|
60
66
|
gemspec.require_path = "lib"
|
61
67
|
gemspec.files.exclude 'spec/wrest/meh_spec.rb'
|
62
68
|
gemspec.test_files.exclude 'spec/wrest/meh_spec.rb'
|
63
|
-
gemspec.add_dependency('activesupport', '>= 2.1.0')
|
64
|
-
gemspec.add_dependency('
|
65
|
-
|
69
|
+
gemspec.add_dependency('activesupport', '>= 2.1.0')
|
70
|
+
gemspec.add_dependency('xml-simple', '>= 1.0.11')
|
71
|
+
case RUBY_PLATFORM
|
72
|
+
when /java/
|
73
|
+
gemspec.add_dependency('json-jruby', '>= 1.1.3')
|
74
|
+
gemspec.platform = 'java'
|
75
|
+
else
|
76
|
+
gemspec.add_dependency('json', '>= 1.1.3')
|
77
|
+
gemspec.platform = Gem::Platform::RUBY
|
78
|
+
end
|
66
79
|
end
|
67
80
|
rescue LoadError
|
68
81
|
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
@@ -79,7 +92,7 @@ begin
|
|
79
92
|
desc "Publish RDoc to RubyForge."
|
80
93
|
task :docs => [:rdoc] do
|
81
94
|
config = YAML.load(
|
82
|
-
|
95
|
+
File.read(File.expand_path('~/.rubyforge/user-config.yml'))
|
83
96
|
)
|
84
97
|
|
85
98
|
host = "#{config['username']}@rubyforge.org"
|
@@ -100,131 +113,131 @@ namespace (:benchmark) do
|
|
100
113
|
task :setup_test_classes do
|
101
114
|
require 'active_resource'
|
102
115
|
require 'wrest'
|
103
|
-
|
104
|
-
class Ooga < Wrest::Mappers::Resource::Base;end
|
105
|
-
class Booga < ActiveResource::Base; self.site='';end
|
106
|
-
end
|
107
|
-
|
108
|
-
desc "Benchmark when objects are created each time before getting data; i.e there are few queries per instantiation"
|
109
|
-
task :create_and_get => :setup_test_classes do |t|
|
110
|
-
|
111
|
-
n = 10000
|
112
|
-
puts "Running #{n} times per report"
|
113
|
-
Benchmark.bmbm(10) do |rpt|
|
114
|
-
rpt.report("Wrest::Resource") do
|
115
|
-
n.times {
|
116
|
-
ooga = Ooga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
117
|
-
ooga.profession
|
118
|
-
ooga.profession?
|
119
|
-
ooga.enhanced_by
|
120
|
-
ooga.enhanced_by?
|
121
|
-
}
|
122
|
-
end
|
123
116
|
|
124
|
-
|
125
|
-
|
126
|
-
booga = Booga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
127
|
-
booga.profession
|
128
|
-
booga.profession?
|
129
|
-
booga.enhanced_by
|
130
|
-
booga.enhanced_by?
|
131
|
-
}
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
desc "Benchmark when objects are created beforehand; i.e there are many queries per instantiation"
|
137
|
-
task :create_once_and_get => :setup_test_classes do |t|
|
138
|
-
|
139
|
-
n = 10000
|
140
|
-
puts "Running #{n} times per report"
|
141
|
-
|
142
|
-
Benchmark.bmbm(10) do |rpt|
|
143
|
-
rpt.report("Wrest::Resource") do
|
144
|
-
ooga = Ooga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
145
|
-
|
146
|
-
n.times {
|
147
|
-
ooga.profession
|
148
|
-
ooga.profession?
|
149
|
-
ooga.enhanced_by
|
150
|
-
ooga.enhanced_by?
|
151
|
-
}
|
117
|
+
class Ooga < Wrest::Mappers::Resource::Base;end
|
118
|
+
class Booga < ActiveResource::Base; self.site='';end
|
152
119
|
end
|
153
120
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
n
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
ooga.respond_to?(:profession=)
|
181
|
-
}
|
121
|
+
desc "Benchmark when objects are created each time before getting data; i.e there are few queries per instantiation"
|
122
|
+
task :create_and_get => :setup_test_classes do |t|
|
123
|
+
|
124
|
+
n = 10000
|
125
|
+
puts "Running #{n} times per report"
|
126
|
+
Benchmark.bmbm(10) do |rpt|
|
127
|
+
rpt.report("Wrest::Resource") do
|
128
|
+
n.times {
|
129
|
+
ooga = Ooga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
130
|
+
ooga.profession
|
131
|
+
ooga.profession?
|
132
|
+
ooga.enhanced_by
|
133
|
+
ooga.enhanced_by?
|
134
|
+
}
|
135
|
+
end
|
136
|
+
|
137
|
+
rpt.report("ActiveResource") do
|
138
|
+
n.times {
|
139
|
+
booga = Booga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
140
|
+
booga.profession
|
141
|
+
booga.profession?
|
142
|
+
booga.enhanced_by
|
143
|
+
booga.enhanced_by?
|
144
|
+
}
|
145
|
+
end
|
146
|
+
end
|
182
147
|
end
|
183
148
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
n
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
149
|
+
desc "Benchmark when objects are created beforehand; i.e there are many queries per instantiation"
|
150
|
+
task :create_once_and_get => :setup_test_classes do |t|
|
151
|
+
|
152
|
+
n = 10000
|
153
|
+
puts "Running #{n} times per report"
|
154
|
+
|
155
|
+
Benchmark.bmbm(10) do |rpt|
|
156
|
+
rpt.report("Wrest::Resource") do
|
157
|
+
ooga = Ooga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
158
|
+
|
159
|
+
n.times {
|
160
|
+
ooga.profession
|
161
|
+
ooga.profession?
|
162
|
+
ooga.enhanced_by
|
163
|
+
ooga.enhanced_by?
|
164
|
+
}
|
165
|
+
end
|
166
|
+
|
167
|
+
rpt.report("ActiveResource") do
|
168
|
+
booga = Booga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
169
|
+
|
170
|
+
n.times {
|
171
|
+
booga.profession
|
172
|
+
booga.profession?
|
173
|
+
booga.enhanced_by
|
174
|
+
booga.enhanced_by?
|
175
|
+
}
|
176
|
+
end
|
177
|
+
end
|
192
178
|
end
|
193
|
-
end
|
194
|
-
end
|
195
179
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
180
|
+
desc "Benchmark objects respond_to? performance without invocation"
|
181
|
+
task :responds_to_before => :setup_test_classes do |t|
|
182
|
+
|
183
|
+
n = 10000
|
184
|
+
puts "Running #{n} times per report"
|
185
|
+
|
186
|
+
Benchmark.bmbm(10) do |rpt|
|
187
|
+
rpt.report("Wrest::Resource") do
|
188
|
+
ooga = Ooga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
189
|
+
|
190
|
+
n.times {
|
191
|
+
ooga.respond_to?(:profession)
|
192
|
+
ooga.respond_to?(:profession?)
|
193
|
+
ooga.respond_to?(:profession=)
|
194
|
+
}
|
195
|
+
end
|
196
|
+
|
197
|
+
rpt.report("ActiveResource") do
|
198
|
+
booga = Booga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
199
|
+
|
200
|
+
n.times {
|
201
|
+
booga.respond_to?(:profession)
|
202
|
+
booga.respond_to?(:profession?)
|
203
|
+
booga.respond_to?(:profession=)
|
204
|
+
}
|
205
|
+
end
|
206
|
+
end
|
214
207
|
end
|
215
208
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
209
|
+
desc "Benchmark objects respond_to? performance after invocation"
|
210
|
+
task :responds_to_after => :setup_test_classes do |t|
|
211
|
+
|
212
|
+
n = 10000
|
213
|
+
puts "Running #{n} times per report"
|
214
|
+
|
215
|
+
Benchmark.bmbm(10) do |rpt|
|
216
|
+
rpt.report("Wrest::Resource") do
|
217
|
+
ooga = Ooga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
218
|
+
ooga.profession
|
219
|
+
ooga.profession?
|
220
|
+
ooga.profession = ''
|
221
|
+
|
222
|
+
n.times {
|
223
|
+
ooga.respond_to?(:profession)
|
224
|
+
ooga.respond_to?(:profession?)
|
225
|
+
ooga.respond_to?(:profession=)
|
226
|
+
}
|
227
|
+
end
|
228
|
+
|
229
|
+
rpt.report("ActiveResource") do
|
230
|
+
booga = Booga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
|
231
|
+
booga.profession
|
232
|
+
booga.profession?
|
233
|
+
booga.profession = ''
|
234
|
+
|
235
|
+
n.times {
|
236
|
+
booga.respond_to?(:profession)
|
237
|
+
booga.respond_to?(:profession?)
|
238
|
+
booga.respond_to?(:profession=)
|
239
|
+
}
|
240
|
+
end
|
241
|
+
end
|
227
242
|
end
|
228
243
|
end
|
229
|
-
end
|
230
|
-
end
|
data/VERSION.yml
CHANGED
data/bin/jwrest
ADDED
data/bin/wrest
CHANGED
@@ -1,22 +1,3 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
entry_point = "#{File.dirname(__FILE__)}/../lib/wrest.rb"
|
5
|
-
version = "#{File.dirname(__FILE__)}/../lib/wrest/version"
|
6
|
-
|
7
|
-
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
8
|
-
|
9
|
-
require 'optparse'
|
10
|
-
options = { :irb => irb }
|
11
|
-
OptionParser.new do |opt|
|
12
|
-
opt.banner = "Usage: console [options]"
|
13
|
-
opt.on("--irb=[#{irb}]", 'Invoke a different irb.') { |v| options[:irb] = v }
|
14
|
-
opt.parse!(ARGV)
|
15
|
-
end
|
16
|
-
|
17
|
-
libs = " -r irb/completion"
|
18
|
-
libs << " -r #{entry_point}"
|
19
|
-
|
20
|
-
require version
|
21
|
-
puts "Loading (Wrest #{Wrest::VERSION::STRING})"
|
22
|
-
exec "#{options[:irb]} #{libs} --simple-prompt"
|
3
|
+
load(File.dirname(__FILE__)+'/wrest_shell.rb')
|