rest-assured 0.3.2 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/.rspec +1 -0
  2. data/Gemfile +4 -1
  3. data/README.markdown +47 -25
  4. data/bin/rest-assured +3 -3
  5. data/features/command_line_options.feature +2 -2
  6. data/features/rest_api/redirects.feature +10 -9
  7. data/features/ruby_api/create_double.feature +1 -6
  8. data/features/ruby_api/test_server.feature +42 -0
  9. data/features/ruby_api/verify_requests.feature +1 -6
  10. data/features/ruby_api/wait_for_requests.feature +2 -5
  11. data/features/step_definitions/command_line_options_steps.rb +1 -1
  12. data/features/step_definitions/doubles_steps.rb +4 -0
  13. data/features/step_definitions/redirect_rules_steps.rb +2 -6
  14. data/features/step_definitions/ruby_api_steps.rb +45 -0
  15. data/features/support/env.rb +9 -14
  16. data/features/support/world_helpers.rb +1 -1
  17. data/lib/rest-assured.rb +1 -45
  18. data/lib/rest-assured/api.rb +3 -0
  19. data/lib/rest-assured/api/app_runner.rb +18 -0
  20. data/lib/rest-assured/api/app_session.rb +33 -0
  21. data/lib/rest-assured/{client → api}/resources.rb +0 -0
  22. data/lib/rest-assured/api/server.rb +59 -0
  23. data/lib/rest-assured/application.rb +46 -0
  24. data/lib/rest-assured/config.rb +16 -3
  25. data/lib/rest-assured/models/redirect.rb +6 -0
  26. data/lib/rest-assured/routes/double.rb +1 -1
  27. data/lib/rest-assured/routes/redirect.rb +1 -1
  28. data/lib/rest-assured/routes/response.rb +4 -4
  29. data/lib/rest-assured/utils/drb_sniffer.rb +11 -0
  30. data/lib/rest-assured/utils/port_explorer.rb +22 -0
  31. data/lib/rest-assured/utils/subprocess.rb +50 -0
  32. data/lib/rest-assured/version.rb +1 -1
  33. data/prof-result.html +79521 -0
  34. data/rest-assured.gemspec +2 -1
  35. data/spec/api/app_runner_spec.rb +27 -0
  36. data/spec/api/app_session_spec.rb +51 -0
  37. data/spec/{client → api}/resource_double_spec.rb +1 -14
  38. data/spec/api/server_spec.rb +138 -0
  39. data/spec/config_spec.rb +111 -93
  40. data/spec/functional/response_spec.rb +5 -2
  41. data/spec/models/redirect_spec.rb +22 -0
  42. data/spec/port_explorer_spec.rb +32 -0
  43. data/spec/spec_helper.rb +25 -18
  44. data/spec/subprocess_spec.rb +138 -0
  45. data/spec/{custom_matchers.rb → support/custom_matchers.rb} +0 -0
  46. data/spec/support/reset-singleton.rb +15 -0
  47. metadata +66 -30
  48. data/lib/rest-assured/client.rb +0 -17
@@ -63,11 +63,13 @@ module RestAssured
63
63
  end
64
64
 
65
65
  it "redirects if double not hit but there is redirect that matches request" do
66
- r = Models::Redirect.create :to => 'http://exmple.com/api', :pattern => '.*'
66
+ #r = Models::Redirect.create :to => 'http://exmple.com/api', :pattern => '.*'
67
+ #
67
68
  fullpath = '/some/other/path'
68
69
  request.stub(:fullpath).and_return(fullpath)
70
+ Models::Redirect.stub(:find_redirect_url_for).with(fullpath).and_return('new_url')
69
71
 
70
- rest_assured_app.should_receive(:redirect).with(r.to + fullpath)
72
+ rest_assured_app.should_receive(:redirect).with('new_url')
71
73
 
72
74
  Response.perform(rest_assured_app)
73
75
  end
@@ -78,6 +80,7 @@ module RestAssured
78
80
  Response.perform(rest_assured_app)
79
81
  end
80
82
 
83
+ # TODO change to instead exclude anything that does not respond_to?(:to_s)
81
84
  it 'excludes "rack.input" and "rack.errors" as they break with "IOError - not opened for reading:" on consequent #to_json (as they are IO and StringIO)' do
82
85
  requests = double.as_null_object
83
86
  Models::Double.stub_chain('where.first').and_return(double(:requests => requests).as_null_object)
@@ -37,5 +37,27 @@ module RestAssured::Models
37
37
 
38
38
  Redirect.update_order([nil, 34]).should == false
39
39
  end
40
+
41
+ context 'redirect url' do
42
+ it 'constructs url to redirect to' do
43
+ path = rand(1000)
44
+ r = Redirect.create :pattern => '/api/(.*)\?.*', :to => 'http://external.com/some/url/\1?p=5'
45
+ Redirect.find_redirect_url_for("/api/#{path}?param=1").should == "http://external.com/some/url/#{path}?p=5"
46
+ end
47
+
48
+ it 'returns the one that matches the substring' do
49
+ r1 = Redirect.create :pattern => '/ai/path', :to => 'someurl'
50
+ r2 = Redirect.create :pattern => '/api/path', :to => 'someurl'
51
+
52
+ Redirect.find_redirect_url_for('/api/path').should == 'someurl'
53
+ end
54
+
55
+ it 'returns the oldest one that match' do
56
+ r1 = Redirect.create :pattern => '/api', :to => 'someurl'
57
+ r2 = Redirect.create :pattern => '/api/path', :to => 'otherurl'
58
+
59
+ Redirect.find_redirect_url_for('/api/path').should == 'someurl/path'
60
+ end
61
+ end
40
62
  end
41
63
  end
@@ -0,0 +1,32 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+ require File.expand_path('../../lib/rest-assured/utils/port_explorer', __FILE__)
3
+
4
+ module RestAssured::Utils
5
+ describe PortExplorer do
6
+ it 'finds free tcp port' do
7
+ free_port = PortExplorer.free_port
8
+ lambda { Net::HTTP.get('127.0.0.1', '/', free_port) }.should raise_error(Errno::ECONNREFUSED)
9
+ end
10
+
11
+ it 'knows if port is in use' do
12
+ port = PortExplorer.free_port
13
+
14
+ Thread.new do
15
+ TCPServer.open('127.0.0.1', port) do |serv|
16
+ s = serv.accept
17
+ s.puts 'Hello from test'
18
+ s.close
19
+ end
20
+ end
21
+ sleep 0.5
22
+
23
+ PortExplorer.port_free?(port).should == false
24
+ end
25
+
26
+ it 'knows that port is free' do
27
+ port = PortExplorer.free_port
28
+
29
+ PortExplorer.port_free?(port).should == true
30
+ end
31
+ end
32
+ end
data/spec/spec_helper.rb CHANGED
@@ -4,10 +4,14 @@ require 'spork'
4
4
  $:.unshift(File.expand_path('../../lib'), __FILE__)
5
5
 
6
6
  Spork.prefork do
7
+ require 'rspec'
7
8
  require 'capybara/rspec'
8
9
  require 'rack/test'
9
10
  require 'database_cleaner'
10
- require File.expand_path('../custom_matchers', __FILE__)
11
+ require 'awesome_print'
12
+ require File.expand_path('../support/custom_matchers', __FILE__)
13
+ require File.expand_path('../support/reset-singleton', __FILE__)
14
+ require 'rest-assured/utils/drb_sniffer'
11
15
 
12
16
  ENV['RACK_ENV'] = 'test'
13
17
 
@@ -23,6 +27,7 @@ Spork.prefork do
23
27
  c.include Capybara::DSL
24
28
  c.include Rack::Test::Methods
25
29
  c.include XhrHelpers
30
+ c.include RestAssured::Utils::DrbSniffer
26
31
 
27
32
  c.before(:each) do
28
33
  DatabaseCleaner.start
@@ -40,29 +45,31 @@ Spork.prefork do
40
45
  header 'User-Agent', nil
41
46
  end
42
47
  end
43
- end
44
-
45
- Spork.each_run do
46
48
  require 'rest-assured/config'
47
- RestAssured::Config.build(:adapter => 'mysql')
49
+ db_opts = { :dbuser => ENV['TRAVIS'] ? "''" : "root", :adapter => 'mysql' }
50
+ RestAssured::Config.build(db_opts)
48
51
 
49
52
  require 'rest-assured'
50
- require 'rest-assured/client'
53
+ require 'rest-assured/application'
51
54
  require 'shoulda-matchers'
52
- require File.expand_path('../../features/support/test-server', __FILE__)
53
-
54
- at_exit do
55
- TestServer.stop
56
- end
57
55
 
58
- TestServer.start(:port => 9876, :db_user => ENV['TRAVIS'] ? "''" : "root")
59
-
60
- while not TestServer.up?
61
- puts 'Waiting for TestServer to come up...'
62
- sleep 1
63
- end
56
+ RestAssured::Server.start(db_opts.merge(:port => 9876))
57
+ end
64
58
 
65
- RestAssured::Client.config.server_address = 'http://localhost:9876'
59
+ Spork.each_run do
60
+ #require 'rest-assured/config'
61
+ #db_opts = { :dbuser => ENV['TRAVIS'] ? "''" : "root", :adapter => 'mysql' }
62
+ #RestAssured::Config.build(db_opts)
63
+
64
+ #require 'rest-assured'
65
+ #require 'rest-assured/application'
66
+ #require 'shoulda-matchers'
67
+
68
+ #RSpec.configure do |c|
69
+ #c.before(:each, "ruby-api" => true) do
70
+ #RestAssured::Server.start(db_opts.merge(:port => 9876))
71
+ #end
72
+ #end
66
73
 
67
74
  Capybara.app = RestAssured::Application
68
75
 
@@ -0,0 +1,138 @@
1
+ require 'tempfile'
2
+ require File.expand_path('../spec_helper', __FILE__)
3
+ require File.expand_path('../../lib/rest-assured/utils/subprocess', __FILE__)
4
+
5
+ module RestAssured::Utils
6
+ describe Subprocess do
7
+
8
+ it 'forks passed block' do
9
+ ppid_file = Tempfile.new('ppidfile')
10
+ pid_file = Tempfile.new('pidfile')
11
+
12
+ fork do
13
+ pid_file.write(Process.pid)
14
+ pid_file.rewind
15
+ at_exit { exit! }
16
+ Subprocess.new do
17
+ ppid_file.write(Process.ppid)
18
+ ppid_file.rewind
19
+ sleep 2
20
+ end
21
+ sleep 0.5
22
+ end
23
+ Process.wait
24
+ ppid_file.read.should == pid_file.read
25
+ end
26
+
27
+ it 'ensures no zombies' do
28
+ Kernel.stub(:fork).and_return(pid = 1)
29
+ Process.should_receive(:detach).with(pid)
30
+
31
+ Subprocess.new {1}
32
+ end
33
+
34
+ it 'knows when it is running' do
35
+ res_file = Tempfile.new('res')
36
+ fork do
37
+ at_exit { exit! }
38
+ child = Subprocess.new { sleep 0.5 }
39
+ res_file.write(child.alive?)
40
+ res_file.rewind
41
+ end
42
+ Process.wait
43
+ res_file.read.should == 'true'
44
+ end
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
+ context 'shuts down child process' do
76
+ let(:child_pid) do
77
+ Tempfile.new('child_pid')
78
+ end
79
+
80
+ let(:child_alive?) do
81
+ begin
82
+ Process.kill(0, child_pid.read.to_i)
83
+ true
84
+ rescue Errno::ESRCH
85
+ false
86
+ end
87
+ end
88
+
89
+ it 'when stopped' do
90
+ res_file = Tempfile.new('res')
91
+ fork do
92
+ at_exit { exit! }
93
+ child = Subprocess.new { sleep 2 }
94
+ child.stop
95
+ sleep 1
96
+ res_file.write(child.alive?)
97
+ res_file.rewind
98
+ end
99
+ Process.wait
100
+ res_file.read.should == 'false'
101
+ end
102
+
103
+ it 'when exits normally' do
104
+ if not running_in_drb? # drb breaks fork sandbox: at_exits a collected and fired all together on master process exit
105
+ child_pid # Magic touch. Literally. Else Tempfile gets created in fork and that messes things up
106
+
107
+ fork do
108
+ at_exit { exit! }
109
+ child = Subprocess.new { sleep 2 }
110
+ child_pid.write(child.pid)
111
+ child_pid.rewind
112
+ end
113
+
114
+ sleep 0.5
115
+ child_alive?.should == false
116
+ end
117
+ end
118
+
119
+ it 'when killed violently' do
120
+ if not running_in_drb?
121
+ child_pid
122
+
123
+ fork do
124
+ at_exit { exit! }
125
+ child = Subprocess.new { sleep 2 }
126
+ child_pid.write(child.pid)
127
+ child_pid.rewind
128
+
129
+ Process.kill('TERM', Process.pid)
130
+ end
131
+
132
+ sleep 0.5
133
+ child_alive?.should == false
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,15 @@
1
+ require 'singleton'
2
+
3
+ class <<Singleton
4
+ def included_with_reset(klass)
5
+ included_without_reset(klass)
6
+ class <<klass
7
+ def reset_instance
8
+ Singleton.send :__init__, self
9
+ self
10
+ end
11
+ end
12
+ end
13
+ alias_method :included_without_reset, :included
14
+ alias_method :included, :included_with_reset
15
+ end
metadata CHANGED
@@ -1,19 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rest-assured
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
5
- prerelease:
4
+ version: 1.0.0.rc1
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Artem Avetisyan
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-23 00:00:00.000000000 Z
12
+ date: 2012-02-10 00:00:00.000000000 +00:00
13
+ default_executable:
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: sinatra
16
- requirement: &2156381020 !ruby/object:Gem::Requirement
17
+ requirement: &2157171280 !ruby/object:Gem::Requirement
17
18
  none: false
18
19
  requirements:
19
20
  - - ! '>='
@@ -21,32 +22,43 @@ dependencies:
21
22
  version: 1.3.1
22
23
  type: :runtime
23
24
  prerelease: false
24
- version_requirements: *2156381020
25
+ version_requirements: *2157171280
25
26
  - !ruby/object:Gem::Dependency
26
- name: rack-flash
27
- requirement: &2156380560 !ruby/object:Gem::Requirement
27
+ name: rack
28
+ requirement: &2157166140 !ruby/object:Gem::Requirement
28
29
  none: false
29
30
  requirements:
30
- - - ! '>='
31
+ - - <=
31
32
  - !ruby/object:Gem::Version
32
- version: 0.1.2
33
+ version: 1.3.6
33
34
  type: :runtime
34
35
  prerelease: false
35
- version_requirements: *2156380560
36
+ version_requirements: *2157166140
36
37
  - !ruby/object:Gem::Dependency
37
- name: rack
38
- requirement: &2156380100 !ruby/object:Gem::Requirement
38
+ name: childprocess
39
+ requirement: &2157165680 !ruby/object:Gem::Requirement
39
40
  none: false
40
41
  requirements:
41
- - - <=
42
+ - - ~>
42
43
  - !ruby/object:Gem::Version
43
- version: 1.3.6
44
+ version: 0.2.8
44
45
  type: :runtime
45
46
  prerelease: false
46
- version_requirements: *2156380100
47
+ version_requirements: *2157165680
48
+ - !ruby/object:Gem::Dependency
49
+ name: sinatra-flash
50
+ requirement: &2157165300 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: *2157165300
47
59
  - !ruby/object:Gem::Dependency
48
60
  name: haml
49
- requirement: &2156379640 !ruby/object:Gem::Requirement
61
+ requirement: &2157164700 !ruby/object:Gem::Requirement
50
62
  none: false
51
63
  requirements:
52
64
  - - ! '>='
@@ -54,10 +66,10 @@ dependencies:
54
66
  version: 3.1.3
55
67
  type: :runtime
56
68
  prerelease: false
57
- version_requirements: *2156379640
69
+ version_requirements: *2157164700
58
70
  - !ruby/object:Gem::Dependency
59
71
  name: activerecord
60
- requirement: &2156379180 !ruby/object:Gem::Requirement
72
+ requirement: &2157164060 !ruby/object:Gem::Requirement
61
73
  none: false
62
74
  requirements:
63
75
  - - ~>
@@ -65,10 +77,10 @@ dependencies:
65
77
  version: 3.1.0
66
78
  type: :runtime
67
79
  prerelease: false
68
- version_requirements: *2156379180
80
+ version_requirements: *2157164060
69
81
  - !ruby/object:Gem::Dependency
70
82
  name: activeresource
71
- requirement: &2156356520 !ruby/object:Gem::Requirement
83
+ requirement: &2157163540 !ruby/object:Gem::Requirement
72
84
  none: false
73
85
  requirements:
74
86
  - - ~>
@@ -76,7 +88,7 @@ dependencies:
76
88
  version: 3.1.0
77
89
  type: :runtime
78
90
  prerelease: false
79
- version_requirements: *2156356520
91
+ version_requirements: *2157163540
80
92
  description:
81
93
  email:
82
94
  - artem.avetisyan@bbc.co.uk
@@ -86,6 +98,7 @@ extensions: []
86
98
  extra_rdoc_files: []
87
99
  files:
88
100
  - .gitignore
101
+ - .rspec
89
102
  - .travis.yml
90
103
  - Gemfile
91
104
  - Guardfile
@@ -111,6 +124,7 @@ files:
111
124
  - features/rest_api/doubles.feature
112
125
  - features/rest_api/redirects.feature
113
126
  - features/ruby_api/create_double.feature
127
+ - features/ruby_api/test_server.feature
114
128
  - features/ruby_api/verify_requests.feature
115
129
  - features/ruby_api/wait_for_requests.feature
116
130
  - features/step_definitions/command_line_options_steps.rb
@@ -126,8 +140,12 @@ files:
126
140
  - features/web_ui/redirects.feature
127
141
  - lib/active_record/leaky_connections_patch.rb
128
142
  - lib/rest-assured.rb
129
- - lib/rest-assured/client.rb
130
- - lib/rest-assured/client/resources.rb
143
+ - lib/rest-assured/api.rb
144
+ - lib/rest-assured/api/app_runner.rb
145
+ - lib/rest-assured/api/app_session.rb
146
+ - lib/rest-assured/api/resources.rb
147
+ - lib/rest-assured/api/server.rb
148
+ - lib/rest-assured/application.rb
131
149
  - lib/rest-assured/config.rb
132
150
  - lib/rest-assured/models/double.rb
133
151
  - lib/rest-assured/models/redirect.rb
@@ -135,9 +153,13 @@ files:
135
153
  - lib/rest-assured/routes/double.rb
136
154
  - lib/rest-assured/routes/redirect.rb
137
155
  - lib/rest-assured/routes/response.rb
156
+ - lib/rest-assured/utils/drb_sniffer.rb
157
+ - lib/rest-assured/utils/port_explorer.rb
158
+ - lib/rest-assured/utils/subprocess.rb
138
159
  - lib/rest-assured/version.rb
139
160
  - lib/sinatra/handler_options_patch.rb
140
161
  - lib/sinatra/partials.rb
162
+ - prof-result.html
141
163
  - public/css/base.css
142
164
  - public/css/grid.inuit.css
143
165
  - public/css/inuit.css
@@ -155,16 +177,22 @@ files:
155
177
  - public/javascript/application.js
156
178
  - public/javascript/jquery.jgrowl_minimized.js
157
179
  - rest-assured.gemspec
158
- - spec/client/resource_double_spec.rb
180
+ - spec/api/app_runner_spec.rb
181
+ - spec/api/app_session_spec.rb
182
+ - spec/api/resource_double_spec.rb
183
+ - spec/api/server_spec.rb
159
184
  - spec/config_spec.rb
160
- - spec/custom_matchers.rb
161
185
  - spec/functional/double_routes_spec.rb
162
186
  - spec/functional/redirect_routes_spec.rb
163
187
  - spec/functional/response_spec.rb
164
188
  - spec/models/double_spec.rb
165
189
  - spec/models/redirect_spec.rb
166
190
  - spec/models/request_spec.rb
191
+ - spec/port_explorer_spec.rb
167
192
  - spec/spec_helper.rb
193
+ - spec/subprocess_spec.rb
194
+ - spec/support/custom_matchers.rb
195
+ - spec/support/reset-singleton.rb
168
196
  - ssl/localhost.crt
169
197
  - ssl/localhost.key
170
198
  - views/doubles/_form.haml
@@ -176,6 +204,7 @@ files:
176
204
  - views/redirects/edit.haml
177
205
  - views/redirects/index.haml
178
206
  - views/redirects/new.haml
207
+ has_rdoc: true
179
208
  homepage: https://github.com/BBC/rest-assured
180
209
  licenses: []
181
210
  post_install_message:
@@ -191,12 +220,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
191
220
  required_rubygems_version: !ruby/object:Gem::Requirement
192
221
  none: false
193
222
  requirements:
194
- - - ! '>='
223
+ - - ! '>'
195
224
  - !ruby/object:Gem::Version
196
- version: '0'
225
+ version: 1.3.1
197
226
  requirements: []
198
227
  rubyforge_project: rest-assured
199
- rubygems_version: 1.8.10
228
+ rubygems_version: 1.6.2
200
229
  signing_key:
201
230
  specification_version: 3
202
231
  summary: A tool for high level mocking/stubbing HTTP based REST services
@@ -205,6 +234,7 @@ test_files:
205
234
  - features/rest_api/doubles.feature
206
235
  - features/rest_api/redirects.feature
207
236
  - features/ruby_api/create_double.feature
237
+ - features/ruby_api/test_server.feature
208
238
  - features/ruby_api/verify_requests.feature
209
239
  - features/ruby_api/wait_for_requests.feature
210
240
  - features/step_definitions/command_line_options_steps.rb
@@ -218,13 +248,19 @@ test_files:
218
248
  - features/support/world_helpers.rb
219
249
  - features/web_ui/doubles.feature
220
250
  - features/web_ui/redirects.feature
221
- - spec/client/resource_double_spec.rb
251
+ - spec/api/app_runner_spec.rb
252
+ - spec/api/app_session_spec.rb
253
+ - spec/api/resource_double_spec.rb
254
+ - spec/api/server_spec.rb
222
255
  - spec/config_spec.rb
223
- - spec/custom_matchers.rb
224
256
  - spec/functional/double_routes_spec.rb
225
257
  - spec/functional/redirect_routes_spec.rb
226
258
  - spec/functional/response_spec.rb
227
259
  - spec/models/double_spec.rb
228
260
  - spec/models/redirect_spec.rb
229
261
  - spec/models/request_spec.rb
262
+ - spec/port_explorer_spec.rb
230
263
  - spec/spec_helper.rb
264
+ - spec/subprocess_spec.rb
265
+ - spec/support/custom_matchers.rb
266
+ - spec/support/reset-singleton.rb