rufus-jig 0.1.23 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/.rspec +1 -0
  2. data/CHANGELOG.txt +8 -0
  3. data/README.rdoc +41 -11
  4. data/Rakefile +37 -12
  5. data/TODO.txt +6 -3
  6. data/lib/rufus/jig/adapters/em.rb +21 -24
  7. data/lib/rufus/jig/adapters/net.rb +3 -4
  8. data/lib/rufus/jig/adapters/net_persistent.rb +26 -7
  9. data/lib/rufus/jig/adapters/patron.rb +25 -10
  10. data/lib/rufus/jig/couch.rb +199 -36
  11. data/lib/rufus/jig/http.rb +183 -90
  12. data/lib/rufus/jig/path.rb +4 -4
  13. data/lib/rufus/jig/version.rb +1 -1
  14. data/rufus-jig.gemspec +55 -34
  15. data/spec/couch/attachements_spec.rb +113 -0
  16. data/spec/couch/basic_auth_spec.rb +75 -0
  17. data/spec/couch/conditional_spec.rb +178 -0
  18. data/spec/couch/continuous.rb +97 -0
  19. data/spec/couch/couch_spec.rb +64 -0
  20. data/spec/couch/db_spec.rb +366 -0
  21. data/{test → spec/couch}/tweet.png +0 -0
  22. data/spec/couch/views_spec.rb +326 -0
  23. data/spec/couch_url.txt +2 -0
  24. data/spec/jig/basic_auth_spec.rb +51 -0
  25. data/spec/jig/conditional_spec.rb +76 -0
  26. data/spec/jig/delete_spec.rb +32 -0
  27. data/spec/jig/get_spec.rb +116 -0
  28. data/spec/jig/misc_spec.rb +120 -0
  29. data/spec/jig/new_spec.rb +95 -0
  30. data/spec/jig/parse_uri_spec.rb +139 -0
  31. data/spec/jig/post_spec.rb +79 -0
  32. data/spec/jig/prefix_spec.rb +51 -0
  33. data/spec/jig/put_spec.rb +68 -0
  34. data/spec/jig/timeout_spec.rb +94 -0
  35. data/{test → spec}/server.rb +14 -4
  36. data/spec/spec_helper.rb +61 -0
  37. data/spec/support/couch_helper.rb +14 -0
  38. data/spec/support/server_helper.rb +32 -0
  39. metadata +98 -43
  40. data/lib/rufus/jig/adapters/net_response.rb +0 -42
  41. data/test/base.rb +0 -53
  42. data/test/bm/bm0.rb +0 -49
  43. data/test/bm/bm1.rb +0 -43
  44. data/test/conc/put_vs_delete.rb +0 -28
  45. data/test/couch_base.rb +0 -52
  46. data/test/couch_url.txt +0 -1
  47. data/test/ct_0_couch.rb +0 -64
  48. data/test/ct_1_couchdb.rb +0 -204
  49. data/test/ct_2_couchdb_options.rb +0 -50
  50. data/test/ct_3_couchdb_views.rb +0 -106
  51. data/test/ct_4_attachments.rb +0 -126
  52. data/test/ct_5_couchdb_continuous.rb +0 -92
  53. data/test/cut_0_auth_couch.rb +0 -62
  54. data/test/test.rb +0 -28
  55. data/test/to.sh +0 -25
  56. data/test/tt_0_get_timeout.rb +0 -92
  57. data/test/ut_0_http_get.rb +0 -191
  58. data/test/ut_1_http_post.rb +0 -81
  59. data/test/ut_2_http_delete.rb +0 -42
  60. data/test/ut_3_http_put.rb +0 -105
  61. data/test/ut_4_http_prefix.rb +0 -50
  62. data/test/ut_5_http_misc.rb +0 -65
  63. data/test/ut_6_args.rb +0 -98
  64. data/test/ut_7_parse_uri.rb +0 -79
  65. data/test/ut_8_auth.rb +0 -37
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour --format documentation
@@ -2,6 +2,14 @@
2
2
  = rufus-jig CHANGELOG.txt
3
3
 
4
4
 
5
+ == rufus-jig - 1.0.0 released 2010/12/08
6
+
7
+ - Couch #all, #query, #query_for_docs, #bulk_put and #bulk_delete
8
+ - Rufus::Jig.parse_uri now identifies the #fragment
9
+ - conditional GET on by default
10
+ - switched from test/unit to rspec
11
+
12
+
5
13
  == rufus-jig - 0.1.23 released 2010/10/01
6
14
 
7
15
  - net-http-persistent 1.4 which contains the shutdown_in_all_threads patch
@@ -74,8 +74,6 @@ posting...
74
74
  For the real thing : http://github.com/couchrest/couchrest
75
75
  There is also the excellent : http://github.com/langalex/couch_potato
76
76
 
77
- Warning : rufus-jig >= 0.1.18 is meant for CouchDB >= 0.11.
78
-
79
77
  The class Rufus::Jig::Couch provides a get/put/delete trio that is couch-oriented. Json encoding/decoding is automatically handled as well as
80
78
 
81
79
  put and delete return nil in case of success and true (conflict) or and exception else.
@@ -111,8 +109,32 @@ put and delete return nil in case of success and true (conflict) or and exceptio
111
109
 
112
110
  c.detach('coffee0', '1-x-newrevision-whatever', 'picture')
113
111
 
112
+ there is also
113
+
114
+ c.all(:skip => 100, :limit => 100)
115
+ c.all(:keys => %w[ doc0 doc1 doc3 ])
116
+ # grabbing multiple docs in one go
117
+
118
+ c.query('_design/my_design_doc/_view/my_view')
119
+ c.query('my_design_doc:my_view')
120
+ # 'querying' a view
121
+
122
+ c.query_for_docs('my_design_doc:my_view')
123
+ # querying for documents
124
+
125
+ bulk operations
126
+
127
+ docs = c.all(:keys => %w[ doc0 doc1 doc3 ])
128
+ c.bulk_delete(docs)
129
+ # deleting in one go
114
130
 
115
- === on_change
131
+ docs = c.all(:keys => %w[ doc0 doc1 doc3 ])
132
+ docs.each { |doc| doc['status'] = 'copied' }
133
+ c.bulk_put(docs)
134
+ # updating in one go
135
+
136
+
137
+ === Couch on_change
116
138
 
117
139
  Continuous feed with a 20s heartbeat :
118
140
 
@@ -137,22 +159,29 @@ http://rufus.rubyforge.org/rufus-jig/
137
159
 
138
160
  == testing
139
161
 
140
- At first, make sure to start the tiny sinatra test server :
162
+ rake
163
+
164
+ or
165
+
166
+ rspec spec/
167
+
168
+ tests all (plain jig and CouchDB).
141
169
 
142
- ruby test/server.rb
170
+ rspec spec/jig
143
171
 
144
- then do
172
+ only tests the plain jig stuff.
145
173
 
146
- ruby test/test.rb
174
+ rspec spec/couch
147
175
 
176
+ only tests the CouchDB stuff.
148
177
 
149
- To test the CouchDB helpers, make you have a running Couch on http:/127.0.0.1:5984 then do
178
+ By default net/http is used. To test with another HTTP lib :
150
179
 
151
- ruby test/test.rb --couch
180
+ JIG_LIB=patron rspec spec/
152
181
 
153
- To test the em-http-request HTTP transport, make sure the sinatra server is running and then do:
182
+ You can specify patron, em, netp or net. Netp corresponds to http://seattlerb.rubyforge.org/net-http-persistent/
154
183
 
155
- ruby test/test.rb -- --em
184
+ The specs require the json and sinatra gems. You can spot issues in the file server.log (created when running specs).
156
185
 
157
186
 
158
187
  == known issues
@@ -186,6 +215,7 @@ http://rufus.rubyforge.org
186
215
 
187
216
  * John Mettraux, http://jmettraux.wordpress.com/
188
217
  * Kenneth Kalmer, http://www.opensourcery.co.za/
218
+ * Torsten Schoenebaum, http://github.com/tosch/
189
219
 
190
220
 
191
221
  == license
data/Rakefile CHANGED
@@ -1,19 +1,11 @@
1
1
 
2
-
2
+ $:.unshift('.')
3
3
  require 'lib/rufus/jig/version.rb'
4
4
 
5
5
  require 'rubygems'
6
6
  require 'rake'
7
7
 
8
8
 
9
- #
10
- # CLEAN
11
-
12
- require 'rake/clean'
13
- CLEAN.include('pkg', 'tmp', 'html', 'rdoc')
14
- task :default => [ :clean ]
15
-
16
-
17
9
  #
18
10
  # GEM
19
11
 
@@ -30,18 +22,18 @@ Jeweler::Tasks.new do |gem|
30
22
 
31
23
  An HTTP client, greedy with JSON content, GETting conditionally.
32
24
 
33
- Uses Patron and Yajl-ruby whenever possible.
25
+ Uses Yajl-ruby whenever possible.
34
26
  }
35
27
  gem.email = 'jmettraux@gmail.com'
36
28
  gem.homepage = 'http://github.com/jmettraux/rufus-jig/'
37
29
  gem.authors = [ 'John Mettraux', 'Kenneth Kalmer' ]
38
30
  gem.rubyforge_project = 'rufus'
39
31
 
40
- gem.test_file = 'test/test.rb'
41
-
42
32
  gem.add_dependency 'rufus-lru'
43
33
  gem.add_dependency 'rufus-json', '>= 0.2.5'
34
+
44
35
  gem.add_development_dependency 'rake'
36
+ gem.add_development_dependency 'rspec', '~> 2.2.0'
45
37
  gem.add_development_dependency 'yard'
46
38
  gem.add_development_dependency 'jeweler'
47
39
  gem.add_development_dependency 'patron'
@@ -53,6 +45,39 @@ end
53
45
  Jeweler::GemcutterTasks.new
54
46
 
55
47
 
48
+ #
49
+ # CLEAN
50
+
51
+ require 'rake/clean'
52
+ CLEAN.include('pkg', 'tmp', 'html', 'rdoc', 'server.log')
53
+
54
+ #
55
+ # SPEC / TEST
56
+
57
+ #task :spec => :check_dependencies do
58
+ task :spec do
59
+ sh 'rspec spec/'
60
+ end
61
+ task :test => :spec
62
+
63
+ task :default => :spec
64
+
65
+ desc %{
66
+ runs the specs against net, netp, patron and em
67
+ }
68
+ task :specs do
69
+ puts; puts "-" * 80; puts
70
+ sh 'export JIG_LIB=net; rspec -f p spec/; exit 0'
71
+ puts; puts "-" * 80; puts
72
+ sh 'export JIG_LIB=netp; rspec -f p spec/; exit 0'
73
+ puts; puts "-" * 80; puts
74
+ sh 'export JIG_LIB=patron; rspec -f p spec/; exit 0'
75
+ puts; puts "-" * 80; puts
76
+ sh 'export JIG_LIB=em; rspec -f p spec/; exit 0'
77
+ puts; puts "-" * 80; puts
78
+ end
79
+
80
+
56
81
  #
57
82
  # DOC
58
83
 
data/TODO.txt CHANGED
@@ -19,14 +19,17 @@
19
19
  http://seattlerb.rubyforge.org/net-http-persistent/Net/HTTP/Persistent.html
20
20
  [o] HttpResponse : DRY net and netp
21
21
  [x] patron : http can steal each other's patron session (inside the same thread)
22
+ [o] why not a :force_json ?
23
+ [o] netp : close() impl
24
+ [o] views : couch#query(view, opts) ?
22
25
 
23
26
  [ ] HEAD
27
+ [ ] OPTIONS
24
28
  [ ] redirections ? (Patron seem to understand them)
25
- [ ] why not a :force_json ?
26
29
 
27
30
  [ ] make HttpCore detect do_request
28
-
29
31
  [ ] timeout per request ?
32
+ [ ] caching
30
33
 
31
- [ ] netp : close() impl
34
+ [ ] digest auth (as for rufus-verbs) ?
32
35
 
@@ -25,20 +25,20 @@
25
25
 
26
26
  class Rufus::Jig::HttpResponse
27
27
 
28
- def initialize( em_client )
28
+ def initialize(em_client)
29
29
 
30
30
  @original = [ em_client, em_client.response ]
31
31
 
32
32
  @status = em_client.response_header.status
33
- @headers = response_headers( em_client.response_header )
33
+ @headers = response_headers(em_client.response_header)
34
34
  @body = em_client.response
35
35
  end
36
36
 
37
37
  protected
38
38
 
39
- def response_headers( hash )
39
+ def response_headers(hash)
40
40
 
41
- hash.inject({}) do |headers, ( key, value )|
41
+ hash.inject({}) do |headers, (key, value)|
42
42
  key = key.downcase.split('_').map { |c| c.capitalize }.join( '-' )
43
43
  headers[ key ] = value
44
44
  headers
@@ -50,9 +50,9 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
50
50
 
51
51
  require 'uri'
52
52
 
53
- def initialize( *args )
53
+ def initialize(*args)
54
54
 
55
- super( *args )
55
+ super(*args)
56
56
 
57
57
  @options[:user_agent] ||= "#{self.class} #{Rufus::Jig::VERSION} (em)"
58
58
  end
@@ -68,11 +68,11 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
68
68
 
69
69
  protected
70
70
 
71
- def do_request( method, path, data, opts )
71
+ def do_request(method, path, data, opts)
72
72
 
73
73
  args = {}
74
74
 
75
- args[:head] = request_headers( opts )
75
+ args[:head] = request_headers(opts)
76
76
  args[:body] = data if data
77
77
 
78
78
  if to = (opts[:timeout] || @options[:timeout])
@@ -83,26 +83,23 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
83
83
  end
84
84
 
85
85
  if auth = @options[:basic_auth]
86
- args[:head].merge!( 'authorization' => auth )
86
+ args[:head].merge!('authorization' => auth)
87
87
  end
88
88
 
89
- em_response( em_request( path ).send( method, args ) )
89
+ em_response(em_request(path).send(method, args))
90
90
  end
91
91
 
92
- def em_request( uri = '/' )
92
+ def em_request(uri='/')
93
93
 
94
- uri = Rufus::Jig.parse_uri( uri )
95
- uri = URI::HTTP.build(
96
- :host => uri.host || @host,
97
- :port => uri.port || @port,
98
- :path => uri.path,
99
- :query => uri.query
100
- )
94
+ uri = Rufus::Jig.parse_uri(uri)
95
+ uri.scheme ||= (@port == 443 ? 'https' : 'http')
96
+ uri.host ||= @host
97
+ uri.port ||= @port
101
98
 
102
- EventMachine::HttpRequest.new( uri.to_s )
99
+ EventMachine::HttpRequest.new(uri.to_s)
103
100
  end
104
101
 
105
- def em_response( em_client )
102
+ def em_response(em_client)
106
103
 
107
104
  th = Thread.current
108
105
 
@@ -110,7 +107,7 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
110
107
 
111
108
  em_client.errback {
112
109
 
113
- #th.raise( Rufus::Jig::TimeoutError.new )
110
+ #th.raise(Rufus::Jig::TimeoutError.new)
114
111
  # works with ruby < 1.9.x
115
112
  th.wakeup
116
113
  }
@@ -125,15 +122,15 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
125
122
 
126
123
  raise Rufus::Jig::TimeoutError if em_client.response_header.status == 0
127
124
 
128
- Rufus::Jig::HttpResponse.new( em_client )
125
+ Rufus::Jig::HttpResponse.new(em_client)
129
126
  end
130
127
 
131
- def request_headers( options )
128
+ def request_headers(options)
132
129
 
133
130
  headers = { 'user-agent' => @options[:user_agent] }
134
131
 
135
132
  %w[ Accept If-None-Match Content-Type ].each do |k|
136
- headers[k] = options[k] if options.has_key?( k )
133
+ headers[k] = options[k] if options.has_key?(k)
137
134
  end
138
135
 
139
136
  headers
@@ -23,12 +23,11 @@
23
23
  #++
24
24
 
25
25
  require 'net/http'
26
- require 'rufus/jig/adapters/net_response'
27
26
 
28
27
 
29
28
  class Rufus::Jig::Http < Rufus::Jig::HttpCore
30
29
 
31
- def initialize (*args)
30
+ def initialize(*args)
32
31
 
33
32
  super(*args)
34
33
 
@@ -45,7 +44,7 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
45
44
 
46
45
  protected
47
46
 
48
- def get_http (opts)
47
+ def get_http(opts)
49
48
 
50
49
  http = Net::HTTP.new(@host, @port)
51
50
 
@@ -62,7 +61,7 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
62
61
  http
63
62
  end
64
63
 
65
- def do_request (method, path, data, opts)
64
+ def do_request(method, path, data, opts)
66
65
 
67
66
  path = '/' if path == ''
68
67
 
@@ -23,12 +23,9 @@
23
23
  #++
24
24
 
25
25
 
26
- require 'rufus/jig/adapters/net_response'
27
-
28
-
29
26
  class Rufus::Jig::Http < Rufus::Jig::HttpCore
30
27
 
31
- def initialize (*args)
28
+ def initialize(*args)
32
29
 
33
30
  super(*args)
34
31
 
@@ -38,6 +35,14 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
38
35
  name = [ 'jig', @host, @port.to_s ].join('|')
39
36
 
40
37
  @http = Net::HTTP::Persistent.new(name)
38
+
39
+ @http.open_timeout = 5
40
+ # connection timeout
41
+
42
+ @timeout = @options[:timeout]
43
+ @timeout = @timeout.to_i if @timeout
44
+
45
+ reset_timeout
41
46
  end
42
47
 
43
48
  def variant
@@ -54,7 +59,7 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
54
59
 
55
60
  protected
56
61
 
57
- def do_request (method, path, data, opts)
62
+ def do_request(method, path, data, opts)
58
63
 
59
64
  path = '/' if path == ''
60
65
 
@@ -66,13 +71,27 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
66
71
  if auth = @options[:basic_auth]
67
72
  req.basic_auth(*auth)
68
73
  end
74
+ if to = opts[:timeout]
75
+ @http.read_timeout = to
76
+ end
69
77
 
70
78
  req.body = data ? data : ''
71
79
 
72
80
  begin
73
81
  Rufus::Jig::HttpResponse.new(@http.request(uri, req))
74
- rescue Timeout::Error => te
75
- raise Rufus::Jig::TimeoutError
82
+ rescue Net::HTTP::Persistent::Error => nhpe
83
+ raise Rufus::Jig::TimeoutError if nhpe.message.match(/Timeout::Error/)
84
+ ensure
85
+ reset_timeout
86
+ end
87
+ end
88
+
89
+ def reset_timeout
90
+
91
+ if @timeout
92
+ @http.read_timeout = (@timeout < 1) ? nil : @timeout
93
+ else
94
+ @http.read_timeout = 5 # like Patron
76
95
  end
77
96
  end
78
97
  end
@@ -23,20 +23,31 @@
23
23
  #++
24
24
 
25
25
 
26
+ #
27
+ # Re-opening to adapt to Patron
28
+ #
26
29
  class Rufus::Jig::HttpResponse
27
30
 
28
- def initialize (patron_res)
31
+ NHR = /^Net::HTTP/
32
+
33
+ def initialize(res)
29
34
 
30
- @original = patron_res
31
- @status = patron_res.status
32
- @headers = patron_res.headers
33
- @body = patron_res.body
35
+ if NHR.match(res.class.name)
36
+ # for the couch#attach workaround :-( ...
37
+ net_http_init(res)
38
+ return
39
+ end
40
+
41
+ @original = res
42
+ @status = res.status
43
+ @headers = res.headers
44
+ @body = res.body
34
45
  end
35
46
  end
36
47
 
37
48
  class Rufus::Jig::Http < Rufus::Jig::HttpCore
38
49
 
39
- def initialize (*args)
50
+ def initialize(*args)
40
51
 
41
52
  super(*args)
42
53
 
@@ -54,11 +65,15 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
54
65
 
55
66
  protected
56
67
 
57
- def get_patron (opts)
68
+ def get_patron(opts)
58
69
 
59
70
  to = (opts[:timeout] || @options[:timeout])
60
71
  to = to.to_i if to
61
- to = nil if to && to < 1
72
+ to = if to
73
+ to < 1 ? nil : to
74
+ else
75
+ 5
76
+ end
62
77
 
63
78
  patron = Patron::Session.new
64
79
  patron.base_url = "#{@host}:#{@port}"
@@ -80,7 +95,7 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
80
95
  patron
81
96
  end
82
97
 
83
- def do_request (method, path, data, opts)
98
+ def do_request(method, path, data, opts)
84
99
 
85
100
  opts['Expect'] = '' if (method == :put) && ( ! @options[:expect])
86
101
 
@@ -90,7 +105,7 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
90
105
  end
91
106
 
92
107
  begin
93
- get_patron(opts).send(method, *args)
108
+ Rufus::Jig::HttpResponse.new(get_patron(opts).send(method, *args))
94
109
  rescue Patron::TimeoutError => te
95
110
  raise Rufus::Jig::TimeoutError
96
111
  end