rufus-jig 0.1.23 → 1.0.0

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 (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