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.
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
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
- describe RestAssured::Config do
7
- #this is thoroughly covered in cucumber (since there it also serves documentation purposes)
8
- #it 'builds config from user options'
9
-
10
- it 'initializes logger' do
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
- context 'db setup' do
20
- it 'connects db' do
21
- RestAssured::Config.stub(:migrate_db) # so it does not complain
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
- ActiveRecord::Base.should_receive(:establish_connection).with('db_config')
17
+ context 'when included in Application' do
18
+ let(:app) { mock(:app).as_null_object }
25
19
 
26
- RestAssured::Config.setup_db
27
- end
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
- context 'active_record logging' do
30
- let(:logger) { double(:logger).as_null_object }
25
+ Logger.should_receive(:new).with('test.log').and_return(logger)
31
26
 
32
- before do
33
- RestAssured::Config.stub(:migrate_db)
34
- RestAssured::Config.stub(:connect_db)
27
+ Config.included(app)
35
28
  end
36
29
 
37
- it 'is silenced in production' do
38
- AppConfig.stub(:environment).and_return('production')
39
- Logger.should_receive(:new).with(RestAssured::Config.dev_null).and_return(logger)
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
- ActiveRecord::Base.should_receive(:logger=).with(logger)
36
+ ActiveRecord::Base.should_receive(:establish_connection).with('db_config')
42
37
 
43
- RestAssured::Config.setup_db
44
- end
38
+ Config.included(app)
39
+ end
45
40
 
46
- it 'is set to app logger for non production' do
47
- AppConfig.stub(:environment).and_return('test')
48
- AppConfig.stub(:logger).and_return(logger)
41
+ context 'active_record logging' do
42
+ let(:logger) { double(:logger).as_null_object }
49
43
 
50
- ActiveRecord::Base.should_receive(:logger=).with(logger)
44
+ before do
45
+ Config.stub(:migrate_db)
46
+ Config.stub(:connect_db)
47
+ end
51
48
 
52
- RestAssured::Config.setup_db
53
- end
54
- end
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
- it 'runs migrations' do
57
- RestAssured::Config.stub(:connect_db) # so it does not complain
53
+ ActiveRecord::Base.should_receive(:logger=).with(logger)
58
54
 
59
- ActiveRecord::Migrator.should_receive(:migrate)
55
+ Config.setup_db
56
+ end
60
57
 
61
- RestAssured::Config.setup_db
62
- end
63
- end
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
- context 'when included in RestAssured::Application' do
66
- let(:app) { mock(:app).as_null_object }
62
+ ActiveRecord::Base.should_receive(:logger=).with(logger)
67
63
 
68
- before do
69
- RestAssured::Config.build
70
- end
64
+ Config.setup_db
65
+ end
66
+ end
71
67
 
72
- it 'initializes resources' do
73
- RestAssured::Config.should_receive(:init_logger)
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
- RestAssured::Config.included(app)
77
- end
71
+ ActiveRecord::Migrator.should_receive(:migrate)
78
72
 
79
- it 'sets up environment' do
80
- app.should_receive(:set).with(:environment, AppConfig.environment)
81
- RestAssured::Config.included(app)
82
- end
73
+ Config.setup_db
74
+ end
75
+ end
83
76
 
84
- it 'sets up port' do
85
- app.should_receive(:set).with(:port, AppConfig.port)
86
- RestAssured::Config.included(app)
87
- end
77
+ it 'sets up environment' do
78
+ app.should_receive(:set).with(:environment, AppConfig.environment)
79
+ Config.included(app)
80
+ end
88
81
 
89
- it 'connects logger' do
90
- logger = double(:logger).as_null_object
91
- AppConfig.stub(:logger).and_return(logger)
82
+ it 'sets up port' do
83
+ app.should_receive(:set).with(:port, AppConfig.port)
84
+ Config.included(app)
85
+ end
92
86
 
93
- app.should_receive(:enable).with(:logging)
94
- app.should_receive(:use).with(Rack::CommonLogger, logger)
87
+ it 'connects logger to application' do
88
+ logger = double(:logger).as_null_object
89
+ AppConfig.stub(:logger).and_return(logger)
95
90
 
96
- RestAssured::Config.included(app)
97
- end
91
+ app.should_receive(:enable).with(:logging)
92
+ app.should_receive(:use).with(Rack::CommonLogger, logger)
98
93
 
99
- context 'when ssl true' do
100
- before do
101
- AppConfig.stub(:use_ssl).and_return(true)
94
+ Config.included(app)
102
95
  end
103
96
 
104
- it 'makes sure only webrick can be used' do
105
- app.should_receive(:set).with(:server, %[webrick])
106
- RestAssured::Config.included(app)
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 'sets up webrick ssl' do
110
- OpenSSL::X509::Certificate.stub(:new).with( File.read( AppConfig.ssl_cert ) ).and_return('ssl_cert')
111
- OpenSSL::PKey::RSA.stub(:new).with( File.read( AppConfig.ssl_key ) ).and_return('ssl_key')
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 'does all that only if ssl true' do
126
- AppConfig.stub(:use_ssl).and_return(false)
127
-
128
- app.should_not_receive(:set).with(:webrick, anything)
129
- RestAssured::Config.included(app)
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