rack-test-rest 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +20 -0
- data/LICENSE.txt +22 -0
- data/README.md +127 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/lib/rack-test-rest.rb +134 -0
- data/test/helper.rb +18 -0
- data/test/test_rack-test-rest.rb +7 -0
- metadata +137 -0
data/.document
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "shoulda", ">= 0"
|
10
|
+
gem "bundler", "~> 1.0.0"
|
11
|
+
gem "jeweler", "~> 1.5.2"
|
12
|
+
gem "rcov", ">= 0"
|
13
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
git (1.2.5)
|
5
|
+
jeweler (1.5.2)
|
6
|
+
bundler (~> 1.0.0)
|
7
|
+
git (>= 1.2.5)
|
8
|
+
rake
|
9
|
+
rake (0.8.7)
|
10
|
+
rcov (0.9.9)
|
11
|
+
shoulda (2.11.3)
|
12
|
+
|
13
|
+
PLATFORMS
|
14
|
+
ruby
|
15
|
+
|
16
|
+
DEPENDENCIES
|
17
|
+
bundler (~> 1.0.0)
|
18
|
+
jeweler (~> 1.5.2)
|
19
|
+
rcov
|
20
|
+
shoulda
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2011 Joseph Ruscio
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
`rack-test-rest` is an extension to `rack-test` that when combined with
|
2
|
+
`Test::Unit` simplifies the process of unit testing properly
|
3
|
+
designed RESTful API's.
|
4
|
+
|
5
|
+
# Installation
|
6
|
+
$ gem install rack-test-rest
|
7
|
+
|
8
|
+
# Use
|
9
|
+
|
10
|
+
`rack-test-rest` extends `rack-test` with a set of higher-level methods that
|
11
|
+
perform _CRUD_ operations against resources through a RESTful API that conforms
|
12
|
+
to best practices and validates that they respond correctly.
|
13
|
+
It's designed to be mixed into a subclass of `Test::Unit::Testcase`
|
14
|
+
that is testing a specific resource e.g.:
|
15
|
+
|
16
|
+
class GaugeTest < Test::Unit::TestCase
|
17
|
+
include Rack::Test::Methods
|
18
|
+
include Rack::Test::Rest
|
19
|
+
|
20
|
+
def setup
|
21
|
+
@rack_test_rest = {
|
22
|
+
#:debug => true,
|
23
|
+
:root_uri => "/v1/metrics",
|
24
|
+
:resource => "gauges"
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_create
|
29
|
+
create_resource(:name => "foo")
|
30
|
+
create_resource(:code => 422, :name => "foo")
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_read
|
34
|
+
create_resource(:name => "foo")
|
35
|
+
|
36
|
+
gauge = read_resource(:id => name)
|
37
|
+
assert gauge['name'] == name
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_update
|
41
|
+
create_resource(:name => "foo", :description => "bar")
|
42
|
+
|
43
|
+
update_resource(:id => "foo", :description => "baz")
|
44
|
+
|
45
|
+
gauge = read_resource(:id => name)
|
46
|
+
assert gauge['description'] == "baz"
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_delete
|
50
|
+
create_resource(:name => "foo")
|
51
|
+
delete_resource(:id => "foo")
|
52
|
+
read_resource(:code => 404, :id => name)
|
53
|
+
end
|
54
|
+
|
55
|
+
`rack-test-rest` exploits _convention over configuration_ to minimize the amount of work
|
56
|
+
required to test any particular resource. You need only specify `:root_uri` and `:resource`
|
57
|
+
in your test setup (through the `@rack_test_rest` instance variable). These are combined
|
58
|
+
to create either the URI for creating/indexing resources or the URI for a particular resource:
|
59
|
+
|
60
|
+
:root_uri + '/' + :resource + '.json'
|
61
|
+
:root_uri + '/' + :resource + '/' + params[:id].to_s + '.json'
|
62
|
+
|
63
|
+
## `create_resource(params={})`
|
64
|
+
|
65
|
+
Performs a POST to with any specified parameters to `:root_uri/:resource.json`
|
66
|
+
and ensures that it returns `201`. Returns the string value found in the response's
|
67
|
+
`Location` header.
|
68
|
+
|
69
|
+
## `read_resource(params={})`
|
70
|
+
|
71
|
+
Performs a GET with any specified parameters and validates that it returns `200`.
|
72
|
+
If `:id` is specified the GET is performed against a singular resource i.e.
|
73
|
+
`:root_uri/:resource/:id.json`. In the absence of `:id` the GET is performed
|
74
|
+
as an index operation against `:root_uri/:resource.json`. Returns parsed
|
75
|
+
JSON of the response body on a `200`.
|
76
|
+
|
77
|
+
## `update_resource(params={})`
|
78
|
+
|
79
|
+
Requires an :id parameter. Performs a PUT against `:root_uri/:resource/:id.json`
|
80
|
+
with any other specified parameters and asserts that it returns `204`.
|
81
|
+
|
82
|
+
## `delete_resource(params={})`
|
83
|
+
|
84
|
+
Requires an :id parameter. Performs a DELETE against `:root_uri/:resource/:id.json`
|
85
|
+
and asserts that it returns `204`.
|
86
|
+
|
87
|
+
## Testing invalid input
|
88
|
+
|
89
|
+
Any of the CRUD operations can be altered to check that invalid input is properly
|
90
|
+
detected and returns the correct error code by specifying `:code` as a parameter
|
91
|
+
e.g.
|
92
|
+
create_resource(:code => 422, :name => duplicate_name)
|
93
|
+
read_resource(:code => 404, :id => invalid_id)
|
94
|
+
|
95
|
+
## Debugging
|
96
|
+
The point of unit tests is to surface and fix defects and/or regressions in your code
|
97
|
+
in the lab rather than than in production. When your tests fail you can include
|
98
|
+
:debug => true` to instruct `rack-rest-test` to verbosely log to STDOUT the individual
|
99
|
+
HTTP requests it's performing and the results of each.
|
100
|
+
|
101
|
+
## Pagination
|
102
|
+
`rack-test-rest` also supports randomized tests for paginated resources assuming you follow
|
103
|
+
the [standard pagination scheme](http://dev.librato.com/v1/pagination). All you need supply it
|
104
|
+
with is a block it can use to generate unique parameters for populating the resources prior
|
105
|
+
to pagination tests. You can specify `:count` to control how many records are created and
|
106
|
+
paginated through (defaults to 512) and `:length` to specify the maximum number of resources
|
107
|
+
that a single index operation may return (defaults to 100).
|
108
|
+
|
109
|
+
def test_gauge_pagination
|
110
|
+
@db.run("DELETE FROM gauges")
|
111
|
+
paginate_resource(){ |id| {:name => "foo_#{id}", :description => "gauge #{id}"} }
|
112
|
+
end
|
113
|
+
|
114
|
+
# Contributions
|
115
|
+
|
116
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
117
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
118
|
+
* Fork the project
|
119
|
+
* Start a feature/bugfix branch
|
120
|
+
* Commit and push until you are happy with your contribution
|
121
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
122
|
+
* Submit a pull request!
|
123
|
+
|
124
|
+
# Copyright
|
125
|
+
|
126
|
+
Copyright (c) 2011 Joseph Ruscio. See LICENSE.txt for
|
127
|
+
further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "rack-test-rest"
|
16
|
+
gem.homepage = "http://github.com/josephruscio/rack-test-rest"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{Abstractions for testing RESTful API's with rack-test and Test::Unit.}
|
19
|
+
gem.description = %Q{rack-test-rest is an extension to rack-test that when combined with Test::Unit simplifies the process of unit testing properly designed RESTful API's.}
|
20
|
+
gem.email = "joe@ruscio.org"
|
21
|
+
gem.authors = ["Joseph Ruscio"]
|
22
|
+
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
23
|
+
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
24
|
+
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
25
|
+
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
26
|
+
end
|
27
|
+
Jeweler::RubygemsDotOrgTasks.new
|
28
|
+
|
29
|
+
require 'rake/testtask'
|
30
|
+
Rake::TestTask.new(:test) do |test|
|
31
|
+
test.libs << 'lib' << 'test'
|
32
|
+
test.pattern = 'test/**/test_*.rb'
|
33
|
+
test.verbose = true
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'rcov/rcovtask'
|
37
|
+
Rcov::RcovTask.new do |test|
|
38
|
+
test.libs << 'test'
|
39
|
+
test.pattern = 'test/**/test_*.rb'
|
40
|
+
test.verbose = true
|
41
|
+
end
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
48
|
+
|
49
|
+
rdoc.rdoc_dir = 'rdoc'
|
50
|
+
rdoc.title = "rack-test-rest #{version}"
|
51
|
+
rdoc.rdoc_files.include('README*')
|
52
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,134 @@
|
|
1
|
+
module Rack
|
2
|
+
module Test
|
3
|
+
module Rest
|
4
|
+
|
5
|
+
def resource_uri
|
6
|
+
"#{@rack_test_rest[:root_uri]}/#{@rack_test_rest[:resource]}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_resource(params={})
|
10
|
+
expected_code = params[:code]
|
11
|
+
params.delete :code
|
12
|
+
|
13
|
+
puts "Posting to: '#{resource_uri}.json'" if @rack_test_rest[:debug]
|
14
|
+
post "#{resource_uri}.json", params
|
15
|
+
|
16
|
+
if expected_code
|
17
|
+
assert last_response.status == expected_code
|
18
|
+
else
|
19
|
+
if @rack_test_rest[:debug]
|
20
|
+
puts "#{last_response.status}: #{last_response.body}"
|
21
|
+
puts last_response.original_headers["Location"]
|
22
|
+
end
|
23
|
+
assert last_response.status == 201
|
24
|
+
if @rack_test_rest[:location]
|
25
|
+
assert last_response.original_headers["Location"] =~ @rack_test_rest[:location]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
last_response.original_headers["Location"]
|
30
|
+
end
|
31
|
+
|
32
|
+
def read_resource(params={})
|
33
|
+
expected_code = params[:code]
|
34
|
+
params.delete :code
|
35
|
+
|
36
|
+
if params[:id]
|
37
|
+
id = params[:id]
|
38
|
+
params.delete(:id)
|
39
|
+
uri = resource_uri + "/#{id}.json"
|
40
|
+
else
|
41
|
+
uri = resource_uri + ".json"
|
42
|
+
end
|
43
|
+
|
44
|
+
puts "GET #{uri} #{params}" if @rack_test_rest[:debug]
|
45
|
+
get uri, params
|
46
|
+
|
47
|
+
if @rack_test_rest[:debug]
|
48
|
+
puts "Code: #{last_response.status}"
|
49
|
+
puts "Body: #{last_response.body}"
|
50
|
+
end
|
51
|
+
|
52
|
+
if expected_code
|
53
|
+
assert last_response.status == expected_code
|
54
|
+
return nil
|
55
|
+
else
|
56
|
+
assert last_response.status == 200
|
57
|
+
return JSON.parse(last_response.body)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def update_resource(params={})
|
62
|
+
expected_code = params[:code]
|
63
|
+
params.delete :code
|
64
|
+
|
65
|
+
id = params[:id]
|
66
|
+
params.delete(:id)
|
67
|
+
|
68
|
+
puts "Attempting to update #{id} with #{params}" if @rack_test_rest[:debug]
|
69
|
+
|
70
|
+
put "#{resource_uri}/#{id}.json", params
|
71
|
+
|
72
|
+
puts "#{last_response.status}: #{last_response.body}" if @rack_test_rest[:debug]
|
73
|
+
|
74
|
+
if expected_code
|
75
|
+
assert last_response.status == expected_code
|
76
|
+
else
|
77
|
+
assert last_response.status == 204
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def delete_resource(params={})
|
82
|
+
delete "#{resource_uri}/#{params[:id]}.json"
|
83
|
+
|
84
|
+
if params[:code]
|
85
|
+
assert last_response.status == params[:code]
|
86
|
+
else
|
87
|
+
assert last_response.status == 204
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def paginate_resource(params={})
|
92
|
+
|
93
|
+
count = params[:count] ? params[:count] : 512
|
94
|
+
max = params[:max_length] ? params[:max_length] : 100
|
95
|
+
|
96
|
+
#populate the DB
|
97
|
+
0.upto(count - 1) do |id|
|
98
|
+
create_resource(yield(id))
|
99
|
+
end
|
100
|
+
|
101
|
+
retrieved = 0
|
102
|
+
offset = 0
|
103
|
+
|
104
|
+
while retrieved < count
|
105
|
+
# Get a random number from 1-100
|
106
|
+
length = rand(max - 1) + 1
|
107
|
+
|
108
|
+
expected_length = (length > (count - retrieved)) ? (count - retrieved) : length
|
109
|
+
|
110
|
+
if @rack_test_rest[:debug]
|
111
|
+
puts "Requesting offset='#{offset}', length='#{length}'"
|
112
|
+
puts "Expecting '#{expected_length}'"
|
113
|
+
end
|
114
|
+
|
115
|
+
pg_resp = read_resource(:offset => offset, :length => length)
|
116
|
+
|
117
|
+
puts "Received #{pg_resp[@rack_test_rest[:resource]].count} records" if @rack_test_rest[:debug]
|
118
|
+
assert pg_resp[@rack_test_rest[:resource]].count == expected_length
|
119
|
+
|
120
|
+
puts "Found #{pg_resp["query"]["found"]} records" if @rack_test_rest[:debug]
|
121
|
+
assert pg_resp["query"]["found"] == count
|
122
|
+
|
123
|
+
assert pg_resp["query"]["total"] == count
|
124
|
+
assert pg_resp["query"]["length"] == expected_length
|
125
|
+
assert pg_resp["query"]["offset"] == offset
|
126
|
+
|
127
|
+
retrieved += expected_length
|
128
|
+
offset = retrieved
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'test/unit'
|
11
|
+
require 'shoulda'
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
|
+
require 'rack-test-rest'
|
16
|
+
|
17
|
+
class Test::Unit::TestCase
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-test-rest
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Joseph Ruscio
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-04-10 00:00:00 -07:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
type: :development
|
23
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
requirement: *id001
|
33
|
+
prerelease: false
|
34
|
+
name: shoulda
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
type: :development
|
37
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ~>
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 23
|
43
|
+
segments:
|
44
|
+
- 1
|
45
|
+
- 0
|
46
|
+
- 0
|
47
|
+
version: 1.0.0
|
48
|
+
requirement: *id002
|
49
|
+
prerelease: false
|
50
|
+
name: bundler
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
type: :development
|
53
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ~>
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
hash: 7
|
59
|
+
segments:
|
60
|
+
- 1
|
61
|
+
- 5
|
62
|
+
- 2
|
63
|
+
version: 1.5.2
|
64
|
+
requirement: *id003
|
65
|
+
prerelease: false
|
66
|
+
name: jeweler
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
type: :development
|
69
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
hash: 3
|
75
|
+
segments:
|
76
|
+
- 0
|
77
|
+
version: "0"
|
78
|
+
requirement: *id004
|
79
|
+
prerelease: false
|
80
|
+
name: rcov
|
81
|
+
description: rack-test-rest is an extension to rack-test that when combined with Test::Unit simplifies the process of unit testing properly designed RESTful API's.
|
82
|
+
email: joe@ruscio.org
|
83
|
+
executables: []
|
84
|
+
|
85
|
+
extensions: []
|
86
|
+
|
87
|
+
extra_rdoc_files:
|
88
|
+
- LICENSE.txt
|
89
|
+
- README.md
|
90
|
+
files:
|
91
|
+
- .document
|
92
|
+
- Gemfile
|
93
|
+
- Gemfile.lock
|
94
|
+
- LICENSE.txt
|
95
|
+
- README.md
|
96
|
+
- Rakefile
|
97
|
+
- VERSION
|
98
|
+
- lib/rack-test-rest.rb
|
99
|
+
- test/helper.rb
|
100
|
+
- test/test_rack-test-rest.rb
|
101
|
+
has_rdoc: true
|
102
|
+
homepage: http://github.com/josephruscio/rack-test-rest
|
103
|
+
licenses:
|
104
|
+
- MIT
|
105
|
+
post_install_message:
|
106
|
+
rdoc_options: []
|
107
|
+
|
108
|
+
require_paths:
|
109
|
+
- lib
|
110
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
111
|
+
none: false
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
hash: 3
|
116
|
+
segments:
|
117
|
+
- 0
|
118
|
+
version: "0"
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
none: false
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
hash: 3
|
125
|
+
segments:
|
126
|
+
- 0
|
127
|
+
version: "0"
|
128
|
+
requirements: []
|
129
|
+
|
130
|
+
rubyforge_project:
|
131
|
+
rubygems_version: 1.4.2
|
132
|
+
signing_key:
|
133
|
+
specification_version: 3
|
134
|
+
summary: Abstractions for testing RESTful API's with rack-test and Test::Unit.
|
135
|
+
test_files:
|
136
|
+
- test/helper.rb
|
137
|
+
- test/test_rack-test-rest.rb
|