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