rest-assured 0.3.2 → 1.0.0.rc1
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.
- data/.rspec +1 -0
- data/Gemfile +4 -1
- data/README.markdown +47 -25
- data/bin/rest-assured +3 -3
- data/features/command_line_options.feature +2 -2
- data/features/rest_api/redirects.feature +10 -9
- data/features/ruby_api/create_double.feature +1 -6
- data/features/ruby_api/test_server.feature +42 -0
- data/features/ruby_api/verify_requests.feature +1 -6
- data/features/ruby_api/wait_for_requests.feature +2 -5
- data/features/step_definitions/command_line_options_steps.rb +1 -1
- data/features/step_definitions/doubles_steps.rb +4 -0
- data/features/step_definitions/redirect_rules_steps.rb +2 -6
- data/features/step_definitions/ruby_api_steps.rb +45 -0
- data/features/support/env.rb +9 -14
- data/features/support/world_helpers.rb +1 -1
- data/lib/rest-assured.rb +1 -45
- data/lib/rest-assured/api.rb +3 -0
- data/lib/rest-assured/api/app_runner.rb +18 -0
- data/lib/rest-assured/api/app_session.rb +33 -0
- data/lib/rest-assured/{client → api}/resources.rb +0 -0
- data/lib/rest-assured/api/server.rb +59 -0
- data/lib/rest-assured/application.rb +46 -0
- data/lib/rest-assured/config.rb +16 -3
- data/lib/rest-assured/models/redirect.rb +6 -0
- data/lib/rest-assured/routes/double.rb +1 -1
- data/lib/rest-assured/routes/redirect.rb +1 -1
- data/lib/rest-assured/routes/response.rb +4 -4
- data/lib/rest-assured/utils/drb_sniffer.rb +11 -0
- data/lib/rest-assured/utils/port_explorer.rb +22 -0
- data/lib/rest-assured/utils/subprocess.rb +50 -0
- data/lib/rest-assured/version.rb +1 -1
- data/prof-result.html +79521 -0
- data/rest-assured.gemspec +2 -1
- data/spec/api/app_runner_spec.rb +27 -0
- data/spec/api/app_session_spec.rb +51 -0
- data/spec/{client → api}/resource_double_spec.rb +1 -14
- data/spec/api/server_spec.rb +138 -0
- data/spec/config_spec.rb +111 -93
- data/spec/functional/response_spec.rb +5 -2
- data/spec/models/redirect_spec.rb +22 -0
- data/spec/port_explorer_spec.rb +32 -0
- data/spec/spec_helper.rb +25 -18
- data/spec/subprocess_spec.rb +138 -0
- data/spec/{custom_matchers.rb → support/custom_matchers.rb} +0 -0
- data/spec/support/reset-singleton.rb +15 -0
- metadata +66 -30
- data/lib/rest-assured/client.rb +0 -17
data/rest-assured.gemspec
CHANGED
@@ -21,8 +21,9 @@ Gem::Specification.new do |s|
|
|
21
21
|
s.require_paths = ['lib']
|
22
22
|
|
23
23
|
s.add_dependency 'sinatra', '>= 1.3.1'
|
24
|
-
s.add_dependency 'rack-flash', '>= 0.1.2'
|
25
24
|
s.add_dependency 'rack', '<= 1.3.6'
|
25
|
+
s.add_dependency 'childprocess', '~> 0.2.8'
|
26
|
+
s.add_dependency 'sinatra-flash'
|
26
27
|
s.add_dependency 'haml', '>= 3.1.3'
|
27
28
|
s.add_dependency 'activerecord', '~> 3.1.0'
|
28
29
|
s.add_dependency 'activeresource', '~> 3.1.0'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
require File.expand_path('../../../lib/rest-assured/api/app_runner', __FILE__)
|
3
|
+
|
4
|
+
module RestAssured
|
5
|
+
describe AppRunner do
|
6
|
+
before do
|
7
|
+
Application.stub(:run!)
|
8
|
+
Config.stub(:included)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'requires Application' do
|
12
|
+
Kernel.should_receive(:require).with('rest-assured/application').and_return(true)
|
13
|
+
AppRunner.run!
|
14
|
+
end
|
15
|
+
it 'reloads config if Application has already been loaded' do
|
16
|
+
Kernel.stub(:require).and_return(false)
|
17
|
+
|
18
|
+
Application.should_receive(:send).with(:include, Config)
|
19
|
+
AppRunner.run!
|
20
|
+
end
|
21
|
+
it 'runs Application' do
|
22
|
+
Application.should_receive(:run!)
|
23
|
+
AppRunner.run!
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'childprocess'
|
2
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
3
|
+
require File.expand_path('../../../lib/rest-assured/api/app_session', __FILE__)
|
4
|
+
|
5
|
+
module RestAssured
|
6
|
+
describe AppSession do
|
7
|
+
context 'either without spork or outside prefork block' do
|
8
|
+
before do
|
9
|
+
AppSession.any_instance.stub(:running_in_drb? => false)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'start application in subprocess' do
|
13
|
+
state = ''
|
14
|
+
Utils::Subprocess.should_receive(:new) do |&block|
|
15
|
+
state << 'called from block'
|
16
|
+
block.call
|
17
|
+
state = ''
|
18
|
+
end
|
19
|
+
AppRunner.should_receive(:run!) do
|
20
|
+
state.should == 'called from block'
|
21
|
+
end
|
22
|
+
|
23
|
+
AppSession.new
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'within spork prefork block' do
|
28
|
+
before do
|
29
|
+
AppSession.any_instance.stub(:running_in_drb? => true)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'starts application in childprocess' do
|
33
|
+
cmdargs = %w{-d :memory: -p 6666}
|
34
|
+
Config.stub(:to_cmdargs => cmdargs)
|
35
|
+
|
36
|
+
ChildProcess.should_receive(:build).with('rest-assured', *cmdargs).and_return(child = mock(:io => mock))
|
37
|
+
|
38
|
+
state = ''
|
39
|
+
child.io.should_receive(:inherit!) do
|
40
|
+
state.should_not == 'started'
|
41
|
+
end
|
42
|
+
child.should_receive(:start) do
|
43
|
+
state << 'started'
|
44
|
+
end
|
45
|
+
|
46
|
+
AppSession.new
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -2,22 +2,9 @@ require 'uri'
|
|
2
2
|
require File.expand_path('../../spec_helper', __FILE__)
|
3
3
|
|
4
4
|
module RestAssured
|
5
|
-
describe Double do
|
6
|
-
before do
|
7
|
-
@orig_addr = RestAssured::Client.config.server_address
|
8
|
-
end
|
9
|
-
|
10
|
-
after do
|
11
|
-
RestAssured::Client.config.server_address = @orig_addr
|
12
|
-
end
|
13
|
-
|
5
|
+
describe Double, 'ruby-api' => true do
|
14
6
|
it { should be_kind_of ActiveResource::Base }
|
15
7
|
|
16
|
-
it 'knows where rest-assured server is' do
|
17
|
-
RestAssured::Client.config.server_address = 'http://localhost:1234'
|
18
|
-
Double.site.should == URI.parse('http://localhost:1234')
|
19
|
-
end
|
20
|
-
|
21
8
|
it 'creates new double' do
|
22
9
|
d = Double.create :fullpath => '/some/api', :content => 'content'
|
23
10
|
Models::Double.where(:fullpath => d.fullpath, :content => d.content).should exist
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
require File.expand_path('../../../lib/rest-assured/api/server', __FILE__)
|
3
|
+
|
4
|
+
module RestAssured
|
5
|
+
describe Server do
|
6
|
+
after do
|
7
|
+
Server.reset_instance
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'khows when it is up' do
|
11
|
+
AppSession.stub(:new).and_return(session = stub(:alive? => true).as_null_object)
|
12
|
+
Utils::PortExplorer.stub(:port_free? => false)
|
13
|
+
Server.start
|
14
|
+
|
15
|
+
Server.up?.should == true
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'knows that it is NOT up' do
|
19
|
+
it 'if it has not been started' do
|
20
|
+
Server.up?.should == false
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'if it is starting at the moment' do
|
24
|
+
AppSession.stub(:new).and_return(session = stub(:alive? => true).as_null_object)
|
25
|
+
Utils::PortExplorer.stub(:port_free? => true)
|
26
|
+
Server.start!
|
27
|
+
|
28
|
+
Server.up?.should == false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when starts' do
|
33
|
+
it 'makes sure no previous session is running' do
|
34
|
+
session = mock.as_null_object
|
35
|
+
session.stub(:alive?).and_return(true, false)
|
36
|
+
Utils::PortExplorer.stub(:port_free? => false)
|
37
|
+
AppSession.stub(:new).and_return(session)
|
38
|
+
|
39
|
+
session.should_receive(:stop).once
|
40
|
+
Server.start!
|
41
|
+
Server.start!
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'builds application config' do
|
45
|
+
AppSession.stub(:new).as_null_object
|
46
|
+
|
47
|
+
opts = { :port => 34545, :database => ':memory:' }
|
48
|
+
|
49
|
+
Config.should_receive(:build).with(opts)
|
50
|
+
Server.start!(opts)
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'sets up server address' do
|
54
|
+
before do
|
55
|
+
AppSession.stub(:new).as_null_object
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'uses 127.0.0.1 as hostname' do
|
59
|
+
RestAssured::Double.should_receive(:site=).with(/127\.0\.0\.1/)
|
60
|
+
Server.start!
|
61
|
+
Server.address.should =~ /127\.0\.0\.1/
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'uses port from config' do
|
65
|
+
RestAssured::Double.should_receive(:site=).with(/#{AppConfig.port}/)
|
66
|
+
Server.start!
|
67
|
+
Server.address.should =~ /#{AppConfig.port}/
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'uses http by default' do
|
71
|
+
RestAssured::Double.should_receive(:site=).with(/http[^s]/)
|
72
|
+
Server.start!
|
73
|
+
Server.address.should =~ /http[^s]/
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'uses https if ssl is set in config' do
|
77
|
+
AppConfig.ssl = true
|
78
|
+
RestAssured::Double.should_receive(:site=).with(/https/)
|
79
|
+
Server.start!
|
80
|
+
Server.address.should =~ /https/
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe 'async/sync start' do
|
85
|
+
before do
|
86
|
+
AppSession.stub(:new).and_return(session = stub(:alive? => false).as_null_object)
|
87
|
+
Utils::PortExplorer.stub(:port_free? => true)
|
88
|
+
|
89
|
+
@t = Thread.new do
|
90
|
+
sleep 0.5
|
91
|
+
session.stub(:alive?).and_return(true)
|
92
|
+
Utils::PortExplorer.stub(:port_free? => false)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
after do
|
97
|
+
@t.join
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'does not wait for Application to come up' do
|
101
|
+
Server.start!
|
102
|
+
Server.up?.should == false
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'can wait until Application is up before passing control' do
|
106
|
+
Server.start
|
107
|
+
Server.up?.should == true
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context 'when stopped' do
|
113
|
+
it 'stops application subprocess' do
|
114
|
+
AppSession.stub(:new).and_return(session = stub(:alive? => false))
|
115
|
+
Server.start!
|
116
|
+
|
117
|
+
session.should_receive(:stop)
|
118
|
+
Server.stop
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'stops application subprocess when current process exits' do
|
123
|
+
if not running_in_drb? # drb breaks fork sandbox: at_exits a collected and fired all together on master process exit
|
124
|
+
res_file = Tempfile.new('res')
|
125
|
+
AppSession.stub(:new).and_return(session = mock.as_null_object)
|
126
|
+
session.stub(:stop) do
|
127
|
+
res_file.write "stopped"
|
128
|
+
res_file.rewind
|
129
|
+
end
|
130
|
+
fork do
|
131
|
+
Server.start!
|
132
|
+
end
|
133
|
+
Process.wait
|
134
|
+
res_file.read.should == 'stopped'
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
data/spec/config_spec.rb
CHANGED
@@ -2,131 +2,149 @@ require File.expand_path('../../lib/rest-assured/config', __FILE__)
|
|
2
2
|
require 'rack'
|
3
3
|
require 'openssl'
|
4
4
|
require 'webrick'
|
5
|
+
require 'enumerator'
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
logger = double(:logger).as_null_object
|
12
|
-
AppConfig.stub(:logfile).and_return('test.log')
|
13
|
-
|
14
|
-
Logger.should_receive(:new).with('test.log').and_return(logger)
|
15
|
-
|
16
|
-
RestAssured::Config.init_logger
|
17
|
-
end
|
7
|
+
module RestAssured
|
8
|
+
describe Config do
|
9
|
+
before do
|
10
|
+
Config.build
|
11
|
+
end
|
18
12
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
AppConfig.stub(:db_config).and_return('db_config')
|
13
|
+
context 'builds config from user options' do
|
14
|
+
#this is thoroughly covered in cucumber (since there it also serves documentation purposes)
|
15
|
+
end
|
23
16
|
|
24
|
-
|
17
|
+
context 'when included in Application' do
|
18
|
+
let(:app) { mock(:app).as_null_object }
|
25
19
|
|
26
|
-
|
27
|
-
|
20
|
+
it 'initializes logger' do
|
21
|
+
Config.stub(:setup_db)
|
22
|
+
logger = double(:logger).as_null_object
|
23
|
+
AppConfig.stub(:logfile).and_return('test.log')
|
28
24
|
|
29
|
-
|
30
|
-
let(:logger) { double(:logger).as_null_object }
|
25
|
+
Logger.should_receive(:new).with('test.log').and_return(logger)
|
31
26
|
|
32
|
-
|
33
|
-
RestAssured::Config.stub(:migrate_db)
|
34
|
-
RestAssured::Config.stub(:connect_db)
|
27
|
+
Config.included(app)
|
35
28
|
end
|
36
29
|
|
37
|
-
|
38
|
-
|
39
|
-
|
30
|
+
context 'db setup' do
|
31
|
+
it 'connects db' do
|
32
|
+
Config.stub(:init_logger)
|
33
|
+
Config.stub(:migrate_db) # so it does not complain
|
34
|
+
AppConfig.stub(:db_config).and_return('db_config')
|
40
35
|
|
41
|
-
|
36
|
+
ActiveRecord::Base.should_receive(:establish_connection).with('db_config')
|
42
37
|
|
43
|
-
|
44
|
-
|
38
|
+
Config.included(app)
|
39
|
+
end
|
45
40
|
|
46
|
-
|
47
|
-
|
48
|
-
AppConfig.stub(:logger).and_return(logger)
|
41
|
+
context 'active_record logging' do
|
42
|
+
let(:logger) { double(:logger).as_null_object }
|
49
43
|
|
50
|
-
|
44
|
+
before do
|
45
|
+
Config.stub(:migrate_db)
|
46
|
+
Config.stub(:connect_db)
|
47
|
+
end
|
51
48
|
|
52
|
-
|
53
|
-
|
54
|
-
|
49
|
+
it 'is silenced in production' do
|
50
|
+
AppConfig.stub(:environment).and_return('production')
|
51
|
+
Logger.should_receive(:new).with(Config.dev_null).and_return(logger)
|
55
52
|
|
56
|
-
|
57
|
-
RestAssured::Config.stub(:connect_db) # so it does not complain
|
53
|
+
ActiveRecord::Base.should_receive(:logger=).with(logger)
|
58
54
|
|
59
|
-
|
55
|
+
Config.setup_db
|
56
|
+
end
|
60
57
|
|
61
|
-
|
62
|
-
|
63
|
-
|
58
|
+
it 'is set to app logger for non production' do
|
59
|
+
AppConfig.stub(:environment).and_return('test')
|
60
|
+
AppConfig.stub(:logger).and_return(logger)
|
64
61
|
|
65
|
-
|
66
|
-
let(:app) { mock(:app).as_null_object }
|
62
|
+
ActiveRecord::Base.should_receive(:logger=).with(logger)
|
67
63
|
|
68
|
-
|
69
|
-
|
70
|
-
|
64
|
+
Config.setup_db
|
65
|
+
end
|
66
|
+
end
|
71
67
|
|
72
|
-
|
73
|
-
|
74
|
-
RestAssured::Config.should_receive(:setup_db)
|
68
|
+
it 'runs migrations' do
|
69
|
+
Config.stub(:connect_db) # so it does not complain
|
75
70
|
|
76
|
-
|
77
|
-
end
|
71
|
+
ActiveRecord::Migrator.should_receive(:migrate)
|
78
72
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
end
|
73
|
+
Config.setup_db
|
74
|
+
end
|
75
|
+
end
|
83
76
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
77
|
+
it 'sets up environment' do
|
78
|
+
app.should_receive(:set).with(:environment, AppConfig.environment)
|
79
|
+
Config.included(app)
|
80
|
+
end
|
88
81
|
|
89
|
-
|
90
|
-
|
91
|
-
|
82
|
+
it 'sets up port' do
|
83
|
+
app.should_receive(:set).with(:port, AppConfig.port)
|
84
|
+
Config.included(app)
|
85
|
+
end
|
92
86
|
|
93
|
-
|
94
|
-
|
87
|
+
it 'connects logger to application' do
|
88
|
+
logger = double(:logger).as_null_object
|
89
|
+
AppConfig.stub(:logger).and_return(logger)
|
95
90
|
|
96
|
-
|
97
|
-
|
91
|
+
app.should_receive(:enable).with(:logging)
|
92
|
+
app.should_receive(:use).with(Rack::CommonLogger, logger)
|
98
93
|
|
99
|
-
|
100
|
-
before do
|
101
|
-
AppConfig.stub(:use_ssl).and_return(true)
|
94
|
+
Config.included(app)
|
102
95
|
end
|
103
96
|
|
104
|
-
|
105
|
-
|
106
|
-
|
97
|
+
context 'when ssl true' do
|
98
|
+
before do
|
99
|
+
AppConfig.stub(:ssl).and_return(true)
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'makes sure only webrick can be used' do
|
103
|
+
app.should_receive(:set).with(:server, %[webrick])
|
104
|
+
Config.included(app)
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'sets up webrick ssl' do
|
108
|
+
OpenSSL::X509::Certificate.stub(:new).with( File.read( AppConfig.ssl_cert ) ).and_return('ssl_cert')
|
109
|
+
OpenSSL::PKey::RSA.stub(:new).with( File.read( AppConfig.ssl_key ) ).and_return('ssl_key')
|
110
|
+
|
111
|
+
ssl_config = {
|
112
|
+
:SSLEnable => true,
|
113
|
+
:SSLCertificate => 'ssl_cert',
|
114
|
+
:SSLPrivateKey => 'ssl_key',
|
115
|
+
:SSLCertName => [ ["CN", WEBrick::Utils::getservername] ],
|
116
|
+
:SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE
|
117
|
+
}
|
118
|
+
|
119
|
+
app.should_receive(:set).with(:webrick, hash_including(ssl_config))
|
120
|
+
Config.included(app)
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'does all that only if ssl true' do
|
124
|
+
AppConfig.stub(:ssl).and_return(false)
|
125
|
+
|
126
|
+
app.should_not_receive(:set).with(:webrick, anything)
|
127
|
+
Config.included(app)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context 'cmd args array conversion' do
|
133
|
+
it 'converts true values in form of "value" => ["--#{value}"]' do
|
134
|
+
Config.build(:ssl => true)
|
135
|
+
Config.to_cmdargs.should == ['--ssl']
|
107
136
|
end
|
108
137
|
|
109
|
-
it '
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
ssl_config = {
|
114
|
-
:SSLEnable => true,
|
115
|
-
:SSLCertificate => 'ssl_cert',
|
116
|
-
:SSLPrivateKey => 'ssl_key',
|
117
|
-
:SSLCertName => [ ["CN", WEBrick::Utils::getservername] ],
|
118
|
-
:SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE
|
119
|
-
}
|
120
|
-
|
121
|
-
app.should_receive(:set).with(:webrick, hash_including(ssl_config))
|
122
|
-
RestAssured::Config.included(app)
|
138
|
+
it 'does not include false values' do
|
139
|
+
Config.build(:ssl => false)
|
140
|
+
Config.to_cmdargs.should_not include('--ssl')
|
123
141
|
end
|
124
142
|
|
125
|
-
it '
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
143
|
+
it 'converts key value pairs in form of "key => value" => ["--#{key}", "value"]' do
|
144
|
+
Config.build(:port => 1234, :database => ':memory:')
|
145
|
+
Config.to_cmdargs.each_slice(2) do |a|
|
146
|
+
(a == ['--port', '1234'] || a == ['--database', ':memory:']).should == true
|
147
|
+
end
|
130
148
|
end
|
131
149
|
end
|
132
150
|
end
|