wrest 0.0.5 → 0.0.6

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