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.
Files changed (43) hide show
  1. data/README.rdoc +31 -17
  2. data/Rakefile +147 -134
  3. data/VERSION.yml +1 -1
  4. data/bin/jwrest +3 -0
  5. data/bin/wrest +1 -20
  6. data/bin/wrest_shell.rb +21 -0
  7. data/lib/wrest/components.rb +4 -1
  8. data/lib/wrest/components/attributes_container.rb +65 -10
  9. data/lib/wrest/{translators/xml.rb → components/mutators.rb} +11 -13
  10. data/lib/wrest/components/mutators/base.rb +43 -0
  11. data/lib/wrest/components/mutators/camel_to_snake_case.rb +20 -0
  12. data/lib/wrest/components/mutators/xml_simple_type_caster.rb +35 -0
  13. data/lib/wrest/{translators.rb → components/translators.rb} +6 -7
  14. data/lib/wrest/{translators → components/translators}/content_types.rb +5 -5
  15. data/lib/wrest/components/translators/json.rb +22 -0
  16. data/lib/wrest/components/translators/xml.rb +26 -0
  17. data/lib/wrest/components/typecast_helpers.rb +41 -0
  18. data/lib/wrest/core_ext/hash.rb +5 -0
  19. data/lib/wrest/core_ext/hash/conversions.rb +44 -0
  20. data/lib/wrest/exceptions.rb +6 -1
  21. data/lib/wrest/exceptions/method_not_overridden_exception.rb +17 -0
  22. data/lib/wrest/exceptions/unsupported_content_type_exception.rb +11 -9
  23. data/lib/wrest/resource/base.rb +5 -1
  24. data/lib/wrest/response.rb +2 -2
  25. data/lib/wrest/uri.rb +3 -3
  26. data/lib/wrest/version.rb +1 -1
  27. data/spec/spec_helper.rb +2 -1
  28. data/spec/wrest/components/attributes_container_spec.rb +66 -11
  29. data/spec/wrest/components/mutators/base_spec.rb +38 -0
  30. data/spec/wrest/components/mutators/camel_to_snake_spec.rb +22 -0
  31. data/spec/wrest/components/mutators/xml_simple_type_caster_spec.rb +47 -0
  32. data/spec/wrest/{translators → components/translators}/xml_spec.rb +3 -3
  33. data/spec/wrest/components/translators_spec.rb +9 -0
  34. data/spec/wrest/core_ext/hash/conversions_spec.rb +22 -0
  35. data/{lib/wrest/translators/json.rb → spec/wrest/core_ext/string/conversions_spec.rb} +4 -9
  36. data/spec/wrest/resource/base_spec.rb +1 -1
  37. data/spec/wrest/response_spec.rb +3 -3
  38. data/spec/wrest/uri_spec.rb +2 -2
  39. metadata +34 -19
  40. data/lib/wrest/translators/typed_hash.rb +0 -4
  41. data/spec/wrest/core_ext/string_spec.rb +0 -7
  42. data/spec/wrest/translators/typed_hash_spec.rb +0 -9
  43. 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 basic infrastructure (including an interactive shell) and convenient HTTP wrappers
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 use a custom deserialiser to produce a hash-map from the response.
50
- "http://search.yahooapis.com/NewsSearchService/V1/newsSearch".to_uri.get(
51
- :appid => 'YahooDemo',
52
- :output => 'xml',
53
- :query => 'India',
54
- :results=> '3',
55
- :start => '1'
56
- ).deserialise_using(Wrest::Translators::Xml)
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 which targets Rails REST services; it is currently under development.
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 'rake/rdoctask'
13
+ require 'hanna/rdoctask'
13
14
  require 'spec'
14
15
  require 'spec/rake/spectask'
15
- require 'rcov'
16
- require 'rcov/rcovtask'
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 = 'WRest'
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
- desc "Run all specs in spec directory with RCov"
37
- Spec::Rake::SpecTask.new(:rcov) do |t|
38
- t.spec_opts = ['--options', "spec/spec.opts"]
39
- t.spec_files = FileList["spec/wrest/**/*_spec.rb"]
40
- t.rcov = true
41
- t.rcov_opts = lambda do
42
- IO.readlines("spec/rcov.opts").map {|l| l.chomp.split " "}.flatten
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
- # t.verbose = true
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('json', '>= 1.1.3')
65
- gemspec.add_dependency('xml-simple', '>= 1.0.11')
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
- File.read(File.expand_path('~/.rubyforge/user-config.yml'))
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
- rpt.report("ActiveResource") do
125
- n.times {
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
- rpt.report("ActiveResource") do
155
- booga = Booga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
156
-
157
- n.times {
158
- booga.profession
159
- booga.profession?
160
- booga.enhanced_by
161
- booga.enhanced_by?
162
- }
163
- end
164
- end
165
- end
166
-
167
- desc "Benchmark objects respond_to? performance without invocation"
168
- task :responds_to_before => :setup_test_classes do |t|
169
-
170
- n = 10000
171
- puts "Running #{n} times per report"
172
-
173
- Benchmark.bmbm(10) do |rpt|
174
- rpt.report("Wrest::Resource") do
175
- ooga = Ooga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
176
-
177
- n.times {
178
- ooga.respond_to?(:profession)
179
- ooga.respond_to?(:profession?)
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
- rpt.report("ActiveResource") do
185
- booga = Booga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
186
-
187
- n.times {
188
- booga.respond_to?(:profession)
189
- booga.respond_to?(:profession?)
190
- booga.respond_to?(:profession=)
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
- desc "Benchmark objects respond_to? performance after invocation"
197
- task :responds_to_after => :setup_test_classes do |t|
198
-
199
- n = 10000
200
- puts "Running #{n} times per report"
201
-
202
- Benchmark.bmbm(10) do |rpt|
203
- rpt.report("Wrest::Resource") do
204
- ooga = Ooga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
205
- ooga.profession
206
- ooga.profession?
207
- ooga.profession = ''
208
-
209
- n.times {
210
- ooga.respond_to?(:profession)
211
- ooga.respond_to?(:profession?)
212
- ooga.respond_to?(:profession=)
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
- rpt.report("ActiveResource") do
217
- booga = Booga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
218
- booga.profession
219
- booga.profession?
220
- booga.profession = ''
221
-
222
- n.times {
223
- booga.respond_to?(:profession)
224
- booga.respond_to?(:profession?)
225
- booga.respond_to?(:profession=)
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
@@ -1,4 +1,4 @@
1
1
  ---
2
- :patch: 5
2
+ :patch: 6
3
3
  :minor: 0
4
4
  :major: 0
data/bin/jwrest ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env jruby
2
+
3
+ load(File.dirname(__FILE__)+'/wrest_shell.rb')
data/bin/wrest CHANGED
@@ -1,22 +1,3 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- #!/usr/bin/env ruby
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')