rest-assured 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -4,3 +4,6 @@ pkg/*
4
4
  bundle_bin
5
5
  *.db
6
6
  .sass-cache
7
+ test.log
8
+ Gemfile.lock
9
+ coverage
data/Gemfile CHANGED
@@ -32,4 +32,6 @@ group :local do
32
32
  gem 'rb-readline'
33
33
  end
34
34
  gem 'sinatra-activerecord'
35
+ gem 'simplecov', :platforms => :ruby_19
35
36
  end
37
+
@@ -27,8 +27,8 @@ It is also recommended to have thin installed. This improves startup time (over
27
27
 
28
28
  Then install gem and run:
29
29
 
30
- bash$ gem install rest-assured --pre
31
- bash$ rest-assured -a mysql &
30
+ bash$ gem install rest-assured
31
+ bash$ rest-assured &
32
32
 
33
33
  Or clone from github and run:
34
34
 
@@ -40,8 +40,6 @@ This starts up an instance of rest-assured on port 4578. It is accessible via RE
40
40
 
41
41
  Various options (such as ssl, port, db credentials, etc.) are available through command line options. Check out `rest-assured -h` to see what they are.
42
42
 
43
- NOTE that although sqlite is an extremely handy option (especially with `-d :memory:`), I found it sometimes locking tables under non-trivial load. Hence there is a Plan B - mysql. But may be that is just me sqliting it wrong.
44
-
45
43
  ## Doubles
46
44
 
47
45
  Double is a stub/spy of HTTP request. Create a double that has the same request fullpath and method as the one your app is sending to a dependant service and then convience your app that rest-assured is that dependency (hint: by making endpoints configurable).
@@ -171,7 +169,7 @@ For those using rest-assured from non-ruby environments.
171
169
 
172
170
  It is sometimes desirable to only double certain calls while letting others through to the "real" services. Meet Redirects. Kind of "rewrite rules" for requests that didn't match any double.
173
171
 
174
- Another potential use for redirects is setting up a "default" double that matches multiple fullpaths. This is of course given your app does not mind an extra redirect. Also note that such "default" double still only covers single http verb so requests with different methods won't match (hint: need an extra double).
172
+ Another use for redirects is setting up a "default" double that matches multiple fullpaths. If a redirect pattern matches a defined double then it will act like a double and respond directly. If it does not match a double then it will return HTTP 303 redirect instead. Note that HTTP redirects are usually converted to GET requests by HTTP clients.
175
173
 
176
174
  Here is the rest API for managing redirects:
177
175
 
@@ -200,7 +198,11 @@ Here is the rest API for managing redirects:
200
198
 
201
199
  ## Changelog
202
200
 
203
- #### 1.0.0.rc1 (13 Feb 2012)
201
+ #### 1.1.0 (17 Feb 2012)
202
+
203
+ * Redirects supports 'real' (without http redirect) rewrite to local double
204
+
205
+ #### 1.0.0 (14 Feb 2012)
204
206
 
205
207
  * start/stop rest-assured via api
206
208
  * redirects support pattern/replacement
@@ -211,8 +213,7 @@ Here is the rest API for managing redirects:
211
213
 
212
214
  #### 0.3.1 (09 Jan 2012)
213
215
 
214
- * lock rack version to <= 1.3.6 until they release fix for
215
- https://github.com/rack/rack/issues/299
216
+ * lock rack version to <= 1.3.6 until they release fix for https://github.com/rack/rack/issues/299
216
217
 
217
218
  #### 0.3 (12 Dec 2011)
218
219
 
@@ -15,6 +15,7 @@ Feature: use doubles via api
15
15
  | /api/some | text content | GET | GET | 303 | 303 |
16
16
  | /api/some?a=3&b=dd | more content | | GET | | 200 |
17
17
  | /api/empty | | POST | POST | | 200 |
18
+ | /api/file | | HEAD | HEAD | | 200 |
18
19
 
19
20
  Scenario: view created double details
20
21
  When I create a double
@@ -55,7 +55,7 @@ Then /^it should wait for (#{CAPTURE_A_NUMBER}) seconds(?: \(default timeout\))?
55
55
  wait_time = Time.now - @wait_start
56
56
  #(timeout..(timeout+1)).should cover(wait_time) # cover() only avilable in 1.9
57
57
  wait_time.should >= timeout
58
- wait_time.should < timeout + 1
58
+ wait_time.should < timeout + 1.5
59
59
  end
60
60
 
61
61
  Then /^it should raise MoreRequestsExpected error after with the following message:$/ do |string|
@@ -7,7 +7,7 @@ module RestAssured
7
7
 
8
8
  serialize :response_headers, Hash
9
9
 
10
- VERBS = %w{GET POST PUT DELETE}
10
+ VERBS = %w{GET POST PUT DELETE HEAD}
11
11
  STATUSES = Net::HTTPResponse::CODE_TO_OBJ.keys.map(&:to_i)
12
12
 
13
13
  validates_presence_of :fullpath
@@ -1,23 +1,33 @@
1
1
  module RestAssured
2
2
  class Response
3
+
3
4
  def self.perform(app)
4
5
  request = app.request
5
-
6
6
  if d = Models::Double.where(:fullpath => request.fullpath, :active => true, :verb => request.request_method).first
7
- request.body.rewind
8
- body = request.body.read #without temp variable ':body = > body' is always nil. mistery
9
- env = request.env.except('rack.input', 'rack.errors', 'rack.logger')
10
-
11
- d.requests.create!(:rack_env => env.to_json, :body => body, :params => request.params.to_json)
12
-
13
- app.headers d.response_headers
14
- app.body d.content
15
- app.status d.status
7
+ return_double app, d
16
8
  elsif redirect_url = Models::Redirect.find_redirect_url_for(request.fullpath)
17
- app.redirect redirect_url
9
+ if d = Models::Double.where(:fullpath => redirect_url, :active => true, :verb => request.request_method).first
10
+ return_double app, d
11
+ else
12
+ app.redirect redirect_url
13
+ end
18
14
  else
19
15
  app.status 404
20
16
  end
21
17
  end
18
+
19
+ def self.return_double(app, d)
20
+ request = app.request
21
+ request.body.rewind
22
+ body = request.body.read #without temp variable ':body = > body' is always nil. mistery
23
+ env = request.env.except('rack.input', 'rack.errors', 'rack.logger')
24
+
25
+ d.requests.create!(:rack_env => env.to_json, :body => body, :params => request.params.to_json)
26
+
27
+ app.headers d.response_headers
28
+ app.body d.content
29
+ app.status d.status
30
+ end
31
+
22
32
  end
23
33
  end
@@ -6,19 +6,10 @@ module RestAssured
6
6
  def initialize
7
7
  @pid = Kernel.fork do
8
8
  trap('USR1') do
9
- $stopped = true
10
9
  Process.kill('TERM', Process.pid) # unlike 'exit' this one is NOT being intercepted by Webrick
11
10
  end
12
11
 
13
- at_exit do
14
- if $stopped
15
- puts "Being stopped from parent..."
16
- #else
17
- #puts "Shutting down parent..."
18
- #Process.kill('TERM', Process.ppid)
19
- end
20
- exit!
21
- end
12
+ at_exit { exit! }
22
13
 
23
14
  begin
24
15
  yield
@@ -1,3 +1,3 @@
1
1
  module RestAssured
2
- VERSION = '1.0.0'
2
+ VERSION = '1.1.0'
3
3
  end
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
9
9
  s.authors = ['Artem Avetisyan']
10
10
  s.email = ['artem.avetisyan@bbc.co.uk']
11
11
  s.homepage = "https://github.com/BBC/rest-assured"
12
- s.summary = %q{A tool for high level mocking/stubbing HTTP based REST services}
12
+ s.summary = %q{Real stubs and spies for HTTP(S) services}
13
13
  #s.description = %q{TODO: Write a gem description}
14
14
 
15
15
  s.rubyforge_project = "rest-assured"
@@ -20,9 +20,8 @@ Gem::Specification.new do |s|
20
20
  s.executables = ['rest-assured']
21
21
  s.require_paths = ['lib']
22
22
 
23
- s.add_dependency 'sinatra', '>= 1.3.1'
24
- s.add_dependency 'rack', '<= 1.3.6'
25
- s.add_dependency 'childprocess', '~> 0.2.8'
23
+ s.add_dependency 'sinatra', '>= 1.3.2'
24
+ s.add_dependency 'childprocess', '~> 0.3.0'
26
25
  s.add_dependency 'sinatra-flash'
27
26
  s.add_dependency 'haml', '>= 3.1.3'
28
27
  s.add_dependency 'activerecord', '~> 3.1.0'
@@ -60,6 +60,19 @@ module RestAssured
60
60
 
61
61
  Response.perform(rest_assured_app)
62
62
  end
63
+
64
+ it "returns double when redirect matches double" do
65
+ fullpath = '/some/other/path'
66
+ request.stub(:fullpath).and_return(fullpath)
67
+ Models::Redirect.stub(:find_redirect_url_for).with(fullpath).and_return('/some/path')
68
+
69
+ rest_assured_app.should_receive(:body).with(@double.content)
70
+ rest_assured_app.should_receive(:status).with(@double.status)
71
+ rest_assured_app.should_receive(:headers).with(@double.response_headers)
72
+
73
+ Response.perform(rest_assured_app)
74
+ end
75
+
63
76
  end
64
77
 
65
78
  it "redirects if double not hit but there is redirect that matches request" do
@@ -1,4 +1,17 @@
1
1
  require 'rubygems'
2
+
3
+ if RUBY_VERSION =~ /^1.9/
4
+ begin
5
+ require 'simplecov'
6
+ SimpleCov.start do
7
+ at_exit {} # reset built in at_exit or else it gets triggered when RestAssured::Server.stop is called from tests
8
+ add_filter "/spec/"
9
+ add_filter "/sinatra/"
10
+ end
11
+ rescue LoadError
12
+ end
13
+ end
14
+
2
15
  require 'spork'
3
16
 
4
17
  $:.unshift(File.expand_path('../../lib'), __FILE__)
@@ -44,6 +57,12 @@ Spork.prefork do
44
57
  c.before(:each, :ui => false) do
45
58
  header 'User-Agent', nil
46
59
  end
60
+
61
+ if defined?(SimpleCov)
62
+ c.after(:suite) do
63
+ SimpleCov.result.format!
64
+ end
65
+ end
47
66
  end
48
67
  require 'rest-assured/config'
49
68
  db_opts = { :dbuser => ENV['TRAVIS'] ? "''" : "root", :adapter => 'mysql' }
@@ -43,35 +43,6 @@ module RestAssured::Utils
43
43
  res_file.read.should == 'true'
44
44
  end
45
45
 
46
- # I am not sure this is actually useful
47
- #describe 'commits seppuku' do
48
- #it 'if child raises exception' do
49
- #res_file = Tempfile.new('res')
50
- #fork do
51
- #at_exit { exit! }
52
- #Subprocess.new { raise "!!NO PANIC!! This exception is part of test"; sleep 1 }
53
- #sleep 0.5
54
- #res_file.write('should not exist because this process should be killed by now')
55
- #res_file.rewind
56
- #end
57
- #Process.wait
58
- #res_file.read.should == ''
59
- #end
60
-
61
- #it 'if child just quits' do
62
- #res_file = Tempfile.new('res')
63
- #fork do
64
- #at_exit { exit! }
65
- #Subprocess.new { 1 }
66
- #sleep 0.5
67
- #res_file.write('should not exist because this process should be killed by now')
68
- #res_file.rewind
69
- #end
70
- #Process.wait
71
- #res_file.read.should == ''
72
- #end
73
- #end
74
-
75
46
  context 'shuts down child process' do
76
47
  let(:child_pid) do
77
48
  Tempfile.new('child_pid')
@@ -97,6 +68,7 @@ module RestAssured::Utils
97
68
  res_file.rewind
98
69
  end
99
70
  Process.wait
71
+ sleep 0.5
100
72
  res_file.read.should == 'false'
101
73
  end
102
74
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rest-assured
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,44 +9,33 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-14 00:00:00.000000000 Z
12
+ date: 2012-02-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sinatra
16
- requirement: &2154191820 !ruby/object:Gem::Requirement
16
+ requirement: &2168491020 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: 1.3.1
21
+ version: 1.3.2
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2154191820
25
- - !ruby/object:Gem::Dependency
26
- name: rack
27
- requirement: &2154191300 !ruby/object:Gem::Requirement
28
- none: false
29
- requirements:
30
- - - <=
31
- - !ruby/object:Gem::Version
32
- version: 1.3.6
33
- type: :runtime
34
- prerelease: false
35
- version_requirements: *2154191300
24
+ version_requirements: *2168491020
36
25
  - !ruby/object:Gem::Dependency
37
26
  name: childprocess
38
- requirement: &2154207160 !ruby/object:Gem::Requirement
27
+ requirement: &2168528060 !ruby/object:Gem::Requirement
39
28
  none: false
40
29
  requirements:
41
30
  - - ~>
42
31
  - !ruby/object:Gem::Version
43
- version: 0.2.8
32
+ version: 0.3.0
44
33
  type: :runtime
45
34
  prerelease: false
46
- version_requirements: *2154207160
35
+ version_requirements: *2168528060
47
36
  - !ruby/object:Gem::Dependency
48
37
  name: sinatra-flash
49
- requirement: &2154206740 !ruby/object:Gem::Requirement
38
+ requirement: &2168523560 !ruby/object:Gem::Requirement
50
39
  none: false
51
40
  requirements:
52
41
  - - ! '>='
@@ -54,10 +43,10 @@ dependencies:
54
43
  version: '0'
55
44
  type: :runtime
56
45
  prerelease: false
57
- version_requirements: *2154206740
46
+ version_requirements: *2168523560
58
47
  - !ruby/object:Gem::Dependency
59
48
  name: haml
60
- requirement: &2154206160 !ruby/object:Gem::Requirement
49
+ requirement: &2168565440 !ruby/object:Gem::Requirement
61
50
  none: false
62
51
  requirements:
63
52
  - - ! '>='
@@ -65,10 +54,10 @@ dependencies:
65
54
  version: 3.1.3
66
55
  type: :runtime
67
56
  prerelease: false
68
- version_requirements: *2154206160
57
+ version_requirements: *2168565440
69
58
  - !ruby/object:Gem::Dependency
70
59
  name: activerecord
71
- requirement: &2154205600 !ruby/object:Gem::Requirement
60
+ requirement: &2168564340 !ruby/object:Gem::Requirement
72
61
  none: false
73
62
  requirements:
74
63
  - - ~>
@@ -76,10 +65,10 @@ dependencies:
76
65
  version: 3.1.0
77
66
  type: :runtime
78
67
  prerelease: false
79
- version_requirements: *2154205600
68
+ version_requirements: *2168564340
80
69
  - !ruby/object:Gem::Dependency
81
70
  name: activeresource
82
- requirement: &2154205100 !ruby/object:Gem::Requirement
71
+ requirement: &2168563340 !ruby/object:Gem::Requirement
83
72
  none: false
84
73
  requirements:
85
74
  - - ~>
@@ -87,7 +76,7 @@ dependencies:
87
76
  version: 3.1.0
88
77
  type: :runtime
89
78
  prerelease: false
90
- version_requirements: *2154205100
79
+ version_requirements: *2168563340
91
80
  description:
92
81
  email:
93
82
  - artem.avetisyan@bbc.co.uk
@@ -137,7 +126,6 @@ files:
137
126
  - features/support/world_helpers.rb
138
127
  - features/web_ui/doubles.feature
139
128
  - features/web_ui/redirects.feature
140
- - lib/active_record/leaky_connections_patch.rb
141
129
  - lib/rest-assured.rb
142
130
  - lib/rest-assured/api.rb
143
131
  - lib/rest-assured/api/app_runner.rb
@@ -223,13 +211,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
223
211
  version: '0'
224
212
  segments:
225
213
  - 0
226
- hash: -1385633666069364310
214
+ hash: 1944321672567783063
227
215
  requirements: []
228
216
  rubyforge_project: rest-assured
229
217
  rubygems_version: 1.8.10
230
218
  signing_key:
231
219
  specification_version: 3
232
- summary: A tool for high level mocking/stubbing HTTP based REST services
220
+ summary: Real stubs and spies for HTTP(S) services
233
221
  test_files:
234
222
  - features/command_line_options.feature
235
223
  - features/rest_api/doubles.feature
@@ -1,55 +0,0 @@
1
- # fix leaking db connections https://github.com/rails/rails/commit/ea341b8e043160a7ddaba9e6b2bb6044f73c31a8
2
- # TODO remove with the next ActiveRecord update as this patch will be there
3
- module ActiveRecord
4
- class ConnectionAdapters::ConnectionPool
5
- def current_connection_id #:nodoc:
6
- ActiveRecord::Base.connection_id ||= Thread.current.object_id
7
- end
8
- end
9
-
10
- class Base::ConnectionSpecification
11
- class << self
12
- def connection_id
13
- Thread.current['ActiveRecord::Base.connection_id']
14
- end
15
-
16
- def connection_id=(connection_id)
17
- Thread.current['ActiveRecord::Base.connection_id'] = connection_id
18
- end
19
- end
20
- end
21
-
22
- class QueryCache
23
- class BodyProxy
24
- def initialize(original_cache_value, target, connection_id)
25
- @original_cache_value = original_cache_value
26
- @target = target
27
- @connection_id = connection_id
28
- end
29
-
30
- def close
31
- @target.close if @target.respond_to?(:close)
32
- ensure
33
- ActiveRecord::Base.connection_id = @connection_id
34
- ActiveRecord::Base.connection.clear_query_cache
35
- unless @original_cache_value
36
- ActiveRecord::Base.connection.disable_query_cache!
37
- end
38
- end
39
- end
40
-
41
- def call(env)
42
- old = ActiveRecord::Base.connection.query_cache_enabled
43
- ActiveRecord::Base.connection.enable_query_cache!
44
-
45
- status, headers, body = @app.call(env)
46
- [status, headers, BodyProxy.new(old, body, ActiveRecord::Base.connection_id)]
47
- rescue Exception => e
48
- ActiveRecord::Base.connection.clear_query_cache
49
- unless old
50
- ActiveRecord::Base.connection.disable_query_cache!
51
- end
52
- raise e
53
- end
54
- end
55
- end