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
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile CHANGED
@@ -3,6 +3,7 @@ source "http://rubygems.org"
3
3
  # Specify your gem's dependencies in rest-assured.gemspec
4
4
  gemspec
5
5
 
6
+ gem 'awesome_print'
6
7
  gem 'cucumber'
7
8
  gem 'database_cleaner'
8
9
  gem 'rspec'
@@ -12,6 +13,7 @@ gem 'capybara'
12
13
  gem 'capybara-firebug'
13
14
  gem 'rake'
14
15
  gem 'mysql2'
16
+ gem 'sqlite3'
15
17
  gem 'thin'
16
18
  gem 'relish'
17
19
  gem "spork", "> 0.9.0.rc"
@@ -25,8 +27,9 @@ group :local do
25
27
  gem 'launchy'
26
28
  gem "guard-spork"
27
29
  if RUBY_PLATFORM =~ /darwin/
28
- gem 'growl_notify'
30
+ gem 'growl'
29
31
  gem 'rb-fsevent'
32
+ gem 'rb-readline'
30
33
  end
31
34
  gem 'sinatra-activerecord'
32
35
  end
data/README.markdown CHANGED
@@ -19,7 +19,7 @@ Rest-assured requires a database to run. Either sqlite or mysql. So, make sure t
19
19
 
20
20
  bash$ gem install sqlite3 # or mysql2
21
21
 
22
- If using mysql, rest-assured expects database 'rest\_assured' to be accessible by user 'root' with no password. Those are defaults and can be changed with cli options.
22
+ If using mysql, rest-assured expects database `rest_assured` to be accessible by user `root` with no password. Those are defaults and can be changed with cli options.
23
23
 
24
24
  It is also recommended to have thin installed. This improves startup time (over default webrick) and also it works with in-memory sqlite (which webrick does not):
25
25
 
@@ -36,11 +36,11 @@ Or clone from github and run:
36
36
  bash$ cd rest-assured && bundle install
37
37
  bash$ ./bin/rest-assured -d :memory: & # in-memory sqlite db
38
38
 
39
- This starts up an instance of rest-assured on port 4578. It is accessible via REST or web interfaces on 'http://localhost:4578'
39
+ This starts up an instance of rest-assured on port 4578. It is accessible via REST or web interfaces on `http://localhost:4578`
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 :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.
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
44
 
45
45
  ## Doubles
46
46
 
@@ -50,21 +50,29 @@ Double is a stub/spy of HTTP request. Create a double that has the same request
50
50
 
51
51
  Rest-assured provides client library to work with doubles. Check out 'Ruby API' section in [documentation](https://www.relishapp.com/artemave/rest-assured) for full reference.
52
52
 
53
- Set it up first in env.rb/spec_helper.rb:
53
+ Start up the server:
54
54
 
55
55
  ```ruby
56
- require 'rest-assured/client'
56
+ # env.rb/spec_helper.rb
57
+ require 'rest-assured'
57
58
 
58
- RestAssured::Client.config.server_address = 'http://localhost:4578' # or wherever your rest-assured is
59
+ RestAssured::Server.start(database: ':memory:', port: 7899) # or any other option available on command line
59
60
  ```
61
+ This server will be automatically shut down when your tests are done.
60
62
 
61
- You can then create doubles in your tests:
63
+ Alternatively, if you want to use existing server instance:
64
+
65
+ ```ruby
66
+ RestAssured::Server.address = 'http://localhost:4578' # or wherever it is
67
+ ```
68
+
69
+ You can now create doubles in your tests:
62
70
 
63
71
  ```ruby
64
72
  RestAssured::Double.create(fullpath: '/products', content: 'this is content')
65
73
  ```
66
74
 
67
- Now GET 'http://localhost:4578/products' will be returning 'this is content'.
75
+ Now GET `http://localhost:4578/products` will be returning `this is content`.
68
76
 
69
77
  You can also verify what requests happen on a double, or, in other words, spy on a double. Say this is a Given part of a test:
70
78
 
@@ -72,7 +80,7 @@ You can also verify what requests happen on a double, or, in other words, spy on
72
80
  @double = RestAssured::Double.create(fullpath: '/products', verb: 'POST')
73
81
  ```
74
82
 
75
- Then let us assume that 'http://localhost:4578/products' got POSTed as a result of some actions in When part. Now we can examine requests happened on that double in Then part:
83
+ Then let us assume that `http://localhost:4578/products` got POSTed as a result of some actions in When part. Now we can examine requests happened on that double in Then part:
76
84
 
77
85
  ```ruby
78
86
  @double.wait_for_requests(1, timeout: 10) # defaults to 5 seconds
@@ -87,8 +95,8 @@ JSON.parse(req.rack_env)['ACCEPT'].should == 'text/html'
87
95
  Use plain rest api to clear doubles/redirects between tests:
88
96
 
89
97
  ```ruby
90
- RestClient.delete "#{RestAssured::Client.config.server_address}/redirects/all"
91
- RestClient.delete "#{RestAssured::Client.config.server_address}/doubles/all"
98
+ RestClient.delete "#{RestAssured::Server.address}/redirects/all"
99
+ RestClient.delete "#{RestAssured::Server.address}/doubles/all"
92
100
  ```
93
101
 
94
102
  ### Plain REST API
@@ -97,13 +105,13 @@ For those using rest-assured from non-ruby environments.
97
105
 
98
106
  #### Create double
99
107
 
100
- HTTP POST to '/doubles' creates a double and returns its json representation.
108
+ HTTP POST to `/doubles` creates a double and returns its json representation.
101
109
  The following options can be passed as request parameters:
102
110
 
103
- - __fullpath__ - e.g., '/some/api/object', or with parameters in query string (useful for doubling GETs) - '/some/other/api/object?a=2&b=c'. Mandatory.
111
+ - __fullpath__ - e.g., `/some/api/object`, or with parameters in query string (useful for doubling GETs) - `/some/other/api/object?a=2&b=c`. Mandatory.
104
112
  - __content__ - whatever you want this double to respond with. Optional.
105
- - __verb__ - one of http the following http verbs: GET, POST, PUT, DELETE. Optional. GET is default.
106
- - __status__ - status returned when double is requested. Optional. 200 is default.
113
+ - __verb__ - one of http the following http verbs: `GET`, `POST`, `PUT`, `DELETE`. Optional. `GET` is default.
114
+ - __status__ - status returned when double is requested. Optional. `200` is default.
107
115
  - __response_headers__ - key/value map of headers. Optional.
108
116
 
109
117
  Example:
@@ -118,7 +126,7 @@ For those using rest-assured from non-ruby environments.
118
126
 
119
127
  #### Get double state
120
128
 
121
- HTTP GET to '/doubles/:id.json' returns json with double current state. Use id from create json as :id.
129
+ HTTP GET to `/doubles/:id.json` returns json with double current state. Use id from create json as `:id`.
122
130
 
123
131
  Example:
124
132
 
@@ -148,7 +156,7 @@ For those using rest-assured from non-ruby environments.
148
156
  }
149
157
  }
150
158
 
151
- The above assumes that that double has been requested once. Request history is in "requests" array (in chronological order). Each element contains the following data (keys):
159
+ The above assumes that that double has been requested once. Request history is in `requests` array (in chronological order). Each element contains the following data (keys):
152
160
 
153
161
  - __body__ - request payload
154
162
  - __params__ - request parameters. json
@@ -157,34 +165,34 @@ For those using rest-assured from non-ruby environments.
157
165
 
158
166
  #### Delete all doubles
159
167
 
160
- HTTP DELETE to '/doubles/all' deletes all doubles. Useful for cleaning up between tests.
168
+ HTTP DELETE to `/doubles/all` deletes all doubles. Useful for cleaning up between tests.
161
169
 
162
170
  ## Redirects
163
171
 
164
- 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.
172
+ 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.
165
173
 
166
- 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 'default' double still covers only one http verb so requests with different methods won't match.
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).
167
175
 
168
176
  Here is the rest API for managing redirects:
169
177
 
170
178
  ### Create redirect
171
179
 
172
- HTTP POST to '/redirects' creates redirect.
180
+ HTTP POST to `/redirects` creates redirect.
173
181
  The following options can be passed as request parameters:
174
182
 
175
- - __pattern__ - regex (perl5 style) tested against request fullpath. Mandatory
176
- - __to__ - url base e.g., 'https://myserver:8787/api'. Mandatory
183
+ - __pattern__ - regex (perl5 style) tested against request fullpath. e.g, `^/auth/(.*)`. Mandatory
184
+ - __to__ - url base e.g, `http://example.com/api/\1?p=1` where `\1` is a reference to captured group from the pattern. Mandatory
177
185
 
178
186
  Example:
179
187
 
180
188
  bash$ curl -d 'pattern=^/auth&to=https://myserver.com/api' http://localhost:4578/redirects
181
189
 
182
- Now request (any verb) to 'http://localhost:4578/auth/services/1' will get redirected to 'https://myserver.com/api/auth/services/1.' Provided of course there is no double matched for that fullpath and verb.
190
+ Now request (any verb) to `http://localhost:4578/auth/services/1` will get redirected to `https://myserver.com/api/`. Provided of course there is no double matched for that fullpath and verb. Captured group in pattern can be referenced from replacement e.g. `\1`, `\2`, etc.
183
191
  Much like rewrite rules, redirects are evaluated in order (of creation). In UI you can manually rearrange the order.
184
192
 
185
193
  ### Delete all redirects
186
194
 
187
- HTTP DELETE to '/redirects/all' deletes all redirects. Useful for cleaning up between tests.
195
+ HTTP DELETE to `/redirects/all` deletes all redirects. Useful for cleaning up between tests.
188
196
 
189
197
  ## Author
190
198
 
@@ -192,6 +200,20 @@ Here is the rest API for managing redirects:
192
200
 
193
201
  ## Changelog
194
202
 
203
+ #### 1.0.0.rc1 (13 Feb 2012)
204
+
205
+ * start/stop rest-assured via api
206
+ * redirects support pattern/replacement
207
+
208
+ #### 0.3.2 (23 Jan 2012)
209
+
210
+ * double 'activeness' does not take verb into account (bugfix)
211
+
212
+ #### 0.3.1 (09 Jan 2012)
213
+
214
+ * lock rack version to <= 1.3.6 until they release fix for
215
+ https://github.com/rack/rack/issues/299
216
+
195
217
  #### 0.3 (12 Dec 2011)
196
218
 
197
219
  * you can now specify response headers for double to respond with
data/bin/rest-assured CHANGED
@@ -51,8 +51,8 @@ OptionParser.new do |opts|
51
51
  user_opts[:logfile] = logfile
52
52
  end
53
53
 
54
- opts.on('--ssl', "Whether or not to run on https. Defaults to false (http)") do |use_ssl|
55
- user_opts[:use_ssl] = true
54
+ opts.on('--ssl', "Whether or not to run on https. Defaults to false (http)") do
55
+ user_opts[:ssl] = true
56
56
  end
57
57
 
58
58
  opts.on('-c', '--ssl_cert FILENAME', "Path to ssl_cert. Defaults to self signed certificate shipped with rest-assured") do |ssl_cert|
@@ -71,5 +71,5 @@ end.parse!
71
71
 
72
72
  RestAssured::Config.build(user_opts)
73
73
 
74
- require 'rest-assured'
74
+ require 'rest-assured/application'
75
75
  RestAssured::Application.run!
@@ -54,10 +54,10 @@ Feature: command line options
54
54
 
55
55
  Scenario Outline: use ssl option
56
56
  When I start rest-assured with <option>
57
- Then rest-assured should "<use_ssl>"
57
+ Then rest-assured should "<ssl>"
58
58
 
59
59
  Examples:
60
- | option | use_ssl |
60
+ | option | ssl |
61
61
  | | false |
62
62
  | --ssl | true |
63
63
 
@@ -1,3 +1,4 @@
1
+ @now
1
2
  Feature: manage redirect rules
2
3
  In order to be able to mock only part of api
3
4
  As a developer
@@ -10,21 +11,21 @@ Feature: manage redirect rules
10
11
 
11
12
  Scenario: add redirect rule
12
13
  Given blank slate
13
- When I register redirect with pattern "^/api" and uri "http://real.api.co.uk"
14
+ When I create redirect from "^/api/(.*)" to "http://example.com/\1"
14
15
  And I request "/api/something"
15
- Then it should redirect to "http://real.api.co.uk/api/something"
16
+ Then it should redirect to "http://example.com/something"
16
17
 
17
18
  Scenario: add second redirect that match the same request
18
- Given there is redirect with pattern "/api/something" and uri "http://real.api.co.uk"
19
- When I register redirect with pattern "/api/some.*" and uri "http://real.com"
19
+ Given there is redirect from "/api/something" to "http://example.com"
20
+ When I create redirect from "/api/some.*" to "http://real.com"
20
21
  And I request "/api/something"
21
- Then it should redirect to "http://real.api.co.uk/api/something"
22
+ Then it should redirect to "http://example.com/"
22
23
 
23
24
  Scenario: add second redirect that does not match the same request
24
- Given there is redirect with pattern "/api/something" and uri "http://real.api.co.uk"
25
- When I register redirect with pattern "/api/some" and uri "http://real.com"
26
- And I request "/api/someth"
27
- Then it should redirect to "http://real.com/api/someth"
25
+ Given there is redirect from "/api/thing" to "http://real.com"
26
+ When I create redirect from "/api/some.*" to "http://example.com"
27
+ And I request "/api/something"
28
+ Then it should redirect to "http://example.com/"
28
29
 
29
30
  Scenario: clear redirects
30
31
  Given there are some redirects
@@ -1,14 +1,9 @@
1
+ @ruby_api
1
2
  Feature: create double
2
3
  As ruby developer
3
4
  I want to be able to create doubles via client api
4
5
  So that interactions with rest-assured server are completely hidden from me
5
6
 
6
- Background:
7
- Given rest-assured is running locally:
8
- """
9
- RestAssured::Client.config.server_address = 'http://localhost:9876'
10
- """
11
-
12
7
  Scenario: default options
13
8
  When I create a double:
14
9
  """
@@ -0,0 +1,42 @@
1
+ Feature: test server
2
+ In order to have easy integration with my test code
3
+ As a ruby developer
4
+ I want to have a client library take care of starting/stopping an instance of rest-assured appropriately
5
+
6
+ Scenario: start rest-assured server
7
+ Given there is free tcp port
8
+ When I start rest-assured server via client library:
9
+ """
10
+ RestAssured::Server.start(:port => @free_tcp_port)
11
+ """
12
+ Then rest-assured server should be running:
13
+ """
14
+ RestAssured::Server.should be_up
15
+ """
16
+
17
+ Scenario: start asyncronously (so that other heavy setup - e.g. firefox startup - can be done in parallel)
18
+ Given there is free tcp port
19
+ When I start rest-assured asyncronously:
20
+ """
21
+ RestAssured::Server.start!(:port => @free_tcp_port)
22
+ """
23
+ Then rest-assured server should not be running:
24
+ """
25
+ RestAssured::Server.should_not be_up
26
+ """
27
+ When it finally comes up
28
+ Then rest-assured server should be running:
29
+ """
30
+ RestAssured::Server.should be_up
31
+ """
32
+
33
+ Scenario: stop rest-assured server
34
+ Given rest-assured has been started via client library
35
+ When I stop it:
36
+ """
37
+ RestAssured::Server.stop
38
+ """
39
+ Then it should be stopped:
40
+ """
41
+ RestAssured::Server.should_not be_up
42
+ """
@@ -1,14 +1,9 @@
1
+ @ruby_api
1
2
  Feature: verify requests that happened on double
2
3
  In order to check that my app is performing correct requests
3
4
  As test developer
4
5
  I want to be able to get double 'call history'
5
6
 
6
- Background:
7
- Given rest-assured is running locally:
8
- """
9
- RestAssured::Client.config.server_address = 'http://localhost:9876'
10
- """
11
-
12
7
  Scenario: no calls made to double
13
8
  Given I created a double:
14
9
  """
@@ -1,14 +1,11 @@
1
+ @ruby_api
1
2
  Feature: wait for requests on double to happen
2
3
  In order to know when it is a good time to verify requests on a double
3
4
  As test developer
4
5
  I want to be able to wait until specified number of requests happen
5
6
 
6
7
  Background:
7
- Given rest-assured is running locally:
8
- """
9
- RestAssured::Client.config.server_address = 'http://localhost:9876'
10
- """
11
- And I created a double:
8
+ Given I created a double:
12
9
  """
13
10
  @double = RestAssured::Double.create(:fullpath => '/some/api')
14
11
  """
@@ -41,5 +41,5 @@ Then /^ssl certificate used should be "([^"]*)" and ssl key should be "([^"]*)"$
41
41
  end
42
42
 
43
43
  Then /^rest\-assured should "([^"]*)"$/ do |use|
44
- @app_config[:use_ssl].to_s.should == use
44
+ @app_config[:ssl].to_s.should == use
45
45
  end
@@ -39,6 +39,10 @@ When /^I request "([^"]*)"$/ do |fullpath|
39
39
  get fullpath
40
40
  end
41
41
 
42
+ When /sleep (\d+)/ do |n|
43
+ sleep n
44
+ end
45
+
42
46
  When /^I "([^"]*)" "([^"]*)"$/ do |verb, fullpath|
43
47
  send(verb.downcase, fullpath)
44
48
  end
@@ -2,18 +2,14 @@ Then /^I should get (\d+)$/ do |code|
2
2
  last_response.status.should.to_s == code
3
3
  end
4
4
 
5
- Given /^there is redirect with pattern "([^"]*)" and uri "([^"]*)"$/ do |pattern, url|
5
+ When /^(?:I create|there is) redirect from "([^"]*)" to "([^"]*)"$/ do |pattern, url|
6
6
  post '/redirects', { :pattern => pattern, :to => url }
7
7
  last_response.should be_ok
8
8
  end
9
9
 
10
- When /^I register redirect with pattern "([^"]*)" and uri "([^"]*)"$/ do |pattern, url|
11
- step %{there is redirect with pattern "#{pattern}" and uri "#{url}"}
12
- end
13
-
14
10
  Then /^it should redirect to "([^"]*)"$/ do |real_api_url|
15
11
  follow_redirect!
16
- last_response.header['Location'].should == real_api_url
12
+ last_request.url.should == real_api_url
17
13
  end
18
14
 
19
15
  Given /^the following redirects exist:$/ do |redirects|
@@ -66,3 +66,48 @@ end
66
66
  Then /^the following should be true:$/ do |code|
67
67
  eval code
68
68
  end
69
+
70
+ Given /^there is free tcp port$/ do
71
+ @free_tcp_port = RestAssured::Utils::PortExplorer.free_port
72
+ end
73
+
74
+ When /^I start rest-assured server via client library:$/ do |code|
75
+ eval code
76
+ end
77
+
78
+ Then /^rest\-assured server should be running:$/ do |code|
79
+ eval code
80
+ end
81
+
82
+ When /^I start rest\-assured asyncronously:$/ do |code|
83
+ eval code
84
+ end
85
+
86
+ Then /^rest\-assured server should not be running:$/ do |code|
87
+ eval code
88
+ end
89
+
90
+ When /^it finally comes up$/ do
91
+ timeout(5) do
92
+ loop do
93
+ begin
94
+ Net::HTTP.new('localhost', @free_tcp_port).head('/')
95
+ break
96
+ rescue Errno::ECONNREFUSED
97
+ sleep 1
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ Given /^rest\-assured has been started via client library$/ do
104
+ RestAssured::Server.start(:port => RestAssured::Utils::PortExplorer.free_port)
105
+ end
106
+
107
+ When /^I stop it:$/ do |code|
108
+ eval code
109
+ end
110
+
111
+ Then /^it should be stopped:$/ do |code|
112
+ eval code
113
+ end