rack-spec 0.0.3 → 0.0.4
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/README.md +62 -2
- data/lib/rack/spec.rb +4 -1
- data/lib/rack/spec/exception_handler.rb +1 -1
- data/lib/rack/spec/exceptions/base.rb +8 -0
- data/lib/rack/spec/exceptions/validation_error.rb +43 -0
- data/lib/rack/spec/restful.rb +116 -0
- data/lib/rack/spec/spec.rb +12 -0
- data/lib/rack/spec/validation.rb +1 -5
- data/lib/rack/spec/validators/base.rb +2 -6
- data/lib/rack/spec/validators/maximum_length_validator.rb +0 -2
- data/lib/rack/spec/validators/maximum_validator.rb +0 -2
- data/lib/rack/spec/validators/minimum_length_validator.rb +0 -2
- data/lib/rack/spec/validators/minimum_validator.rb +0 -2
- data/lib/rack/spec/validators/null_validator.rb +2 -1
- data/lib/rack/spec/validators/only_validator.rb +0 -2
- data/lib/rack/spec/validators/parameters_validator.rb +10 -4
- data/lib/rack/spec/validators/required_validator.rb +0 -2
- data/lib/rack/spec/validators/type_validator.rb +2 -2
- data/lib/rack/spec/version.rb +1 -1
- data/rack-spec.gemspec +2 -1
- data/spec/fixtures/spec.yml +36 -0
- data/spec/rack/spec_spec.rb +93 -37
- data/spec/spec_helper.rb +2 -0
- metadata +28 -10
- data/lib/rack/spec/validation_error.rb +0 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 982ed4f72ecd493a91d0c53fb4bf960b2850a303
|
4
|
+
data.tar.gz: f012454fe35d8abf802a7c32fa138ddfedd21d50
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 28e45afcf7f5d03cf4bc764f737e846012e8d1d5c63e7936eada092c117385d05e7152533bba5e3044fab6c6d1b3a808fc19802f511ff22aca8b3594bda21d13
|
7
|
+
data.tar.gz: 5a8239586bf0f19227a2d1606bc4a220c4655864157d1afaa9ed7faa69fc1f4e18aa021380bab99c0f9e84a43ecb09866db484e560348e405d3bb94b5b65642b
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -6,13 +6,19 @@ Define specifications of your Rack application.
|
|
6
6
|
gem install rack-spec
|
7
7
|
```
|
8
8
|
|
9
|
-
##
|
9
|
+
## Rack::Spec::Validation
|
10
|
+
Rack::Spec::Validation is a rack-middleware and works as a validation layer for your rack-application.
|
11
|
+
It loads spec definition (= a pure Hash object in specific format) to validate each request.
|
12
|
+
If the request is not valid on your definition, it will raise Rack::Spec::Exceptions::ValidationError.
|
13
|
+
Rack::Spec::ExceptionHandler is a utility rack-middleware to rescue validation error and return 400.
|
14
|
+
|
10
15
|
```ruby
|
11
16
|
require "rack"
|
12
17
|
require "rack/spec"
|
13
18
|
require "yaml"
|
14
19
|
|
15
|
-
use Rack::Spec
|
20
|
+
use Rack::Spec::ExceptionHandler
|
21
|
+
use Rack::Spec::Validation, spec: YAML.load_file("spec.yml")
|
16
22
|
|
17
23
|
run ->(env) do
|
18
24
|
[200, {}, ["OK"]]
|
@@ -50,6 +56,60 @@ endpoints:
|
|
50
56
|
type: string
|
51
57
|
minimumLength: 3
|
52
58
|
maximumLength: 10
|
59
|
+
required: true
|
60
|
+
```
|
61
|
+
|
62
|
+
## Custom Validator
|
63
|
+
Custom validator can be defined by inheriting Rack::Spec::Validators::Base.
|
64
|
+
The following FwordValidator rejects any parameter starting with "F".
|
65
|
+
See [lib/rack/spec/validators](https://github.com/r7kamura/rack-spec/tree/master/lib/rack/spec/validators) for more examples.
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
# Example:
|
69
|
+
#
|
70
|
+
# parameters:
|
71
|
+
# title:
|
72
|
+
# fword: false
|
73
|
+
#
|
74
|
+
class FwordValidator < Rack::Spec::Validators::Base
|
75
|
+
register_as "fword"
|
76
|
+
|
77
|
+
def valid?
|
78
|
+
value.nil? || !value.start_with?("F")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
```
|
82
|
+
|
83
|
+
## Exception Handling
|
84
|
+
Replace Rack::Spec::ExceptionHandler to customize error behavior.
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
use MyExceptionHandler # Rack::Spec::ValidationError must be rescued
|
88
|
+
use Rack::Spec::Validation, spec: YAML.load_file("spec.yml")
|
89
|
+
```
|
90
|
+
|
91
|
+
## Rack::Spec::Restful
|
92
|
+
Rack::Spec::Restful provides strongly conventional RESTful APIs as a rack-middleware.
|
93
|
+
It recognizes a preferred instruction from the request method & path, then tries to call it.
|
94
|
+
|
95
|
+
| verb | path | instruction |
|
96
|
+
| ---- | ---- | ---- |
|
97
|
+
| GET | /recipes/ | Recipe.index(id) |
|
98
|
+
| GET | /recipes/{id} | Recipe.show(id, params) |
|
99
|
+
| POST | /recipes/ | Recipe.create(id) |
|
100
|
+
| PUT | /recipes/{id} | Recipe.update(id, params) |
|
101
|
+
| DELETE | /recipes/{id} | Recipe.destroy(id, params) |
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
class Recipe
|
105
|
+
def self.index(params)
|
106
|
+
order(params[:order]).page(params[:page])
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.show(id, params)
|
110
|
+
find(id)
|
111
|
+
end
|
112
|
+
end
|
53
113
|
```
|
54
114
|
|
55
115
|
## Development
|
data/lib/rack/spec.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
require "rack/builder"
|
2
2
|
require "rack/spec/exception_handler"
|
3
|
+
require "rack/spec/exceptions/base"
|
4
|
+
require "rack/spec/exceptions/validation_error"
|
5
|
+
require "rack/spec/restful"
|
3
6
|
require "rack/spec/spec"
|
4
7
|
require "rack/spec/validation"
|
5
|
-
require "rack/spec/validation_error"
|
6
8
|
require "rack/spec/validators/base"
|
7
9
|
require "rack/spec/validators/null_validator"
|
8
10
|
require "rack/spec/validator_factory"
|
@@ -23,6 +25,7 @@ module Rack
|
|
23
25
|
@app = Rack::Builder.app do
|
24
26
|
use Rack::Spec::ExceptionHandler
|
25
27
|
use Rack::Spec::Validation, options
|
28
|
+
use Rack::Spec::Restful, options
|
26
29
|
run app
|
27
30
|
end
|
28
31
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
class Spec
|
5
|
+
module Exceptions
|
6
|
+
class ValidationError < Base
|
7
|
+
def initialize(validator)
|
8
|
+
@validator = validator
|
9
|
+
end
|
10
|
+
|
11
|
+
def message
|
12
|
+
"Invalid #{key} on `#{constraint_name}` constraint"
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_rack_response
|
16
|
+
[status, header, body]
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def constraint_name
|
22
|
+
@validator.class.registered_name
|
23
|
+
end
|
24
|
+
|
25
|
+
def key
|
26
|
+
@validator.key
|
27
|
+
end
|
28
|
+
|
29
|
+
def status
|
30
|
+
400
|
31
|
+
end
|
32
|
+
|
33
|
+
def header
|
34
|
+
{ "Content-Type" => "application/json" }
|
35
|
+
end
|
36
|
+
|
37
|
+
def body
|
38
|
+
{ message: message }.to_json
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require "active_support/core_ext/object/try"
|
2
|
+
require "active_support/core_ext/string/inflections"
|
3
|
+
|
4
|
+
module Rack
|
5
|
+
class Spec
|
6
|
+
class Restful
|
7
|
+
def initialize(app, options = {})
|
8
|
+
@app = app
|
9
|
+
@options = options
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
Proxy.new(@app, spec, env).call
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def spec
|
19
|
+
Spec.new(@options[:spec])
|
20
|
+
end
|
21
|
+
|
22
|
+
class Proxy
|
23
|
+
def initialize(app, spec, env)
|
24
|
+
@app = app
|
25
|
+
@spec = spec
|
26
|
+
@env = env
|
27
|
+
end
|
28
|
+
|
29
|
+
def call
|
30
|
+
if endpoint
|
31
|
+
response = handler_class.send(handler_method_name, *handler_args)
|
32
|
+
[
|
33
|
+
response.try(:status) || default_status,
|
34
|
+
default_header.merge(response.try(:header) || {}),
|
35
|
+
[(response.try(:body) || response).to_json]
|
36
|
+
]
|
37
|
+
else
|
38
|
+
@app.call(@env)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def endpoint
|
45
|
+
@endpoint ||= @spec.find_endpoint(@env)
|
46
|
+
end
|
47
|
+
|
48
|
+
def handler_args
|
49
|
+
if id
|
50
|
+
[id, params]
|
51
|
+
else
|
52
|
+
[params]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def handler_class
|
57
|
+
path_segments[1].singularize.camelize.constantize
|
58
|
+
end
|
59
|
+
|
60
|
+
def id
|
61
|
+
path_segments[2]
|
62
|
+
end
|
63
|
+
|
64
|
+
def path_segments
|
65
|
+
@path_segments ||= path.split("/")
|
66
|
+
end
|
67
|
+
|
68
|
+
def handler_method_name
|
69
|
+
case request_method
|
70
|
+
when "GET"
|
71
|
+
if id
|
72
|
+
:show
|
73
|
+
else
|
74
|
+
:index
|
75
|
+
end
|
76
|
+
when "POST"
|
77
|
+
:create
|
78
|
+
when "PUT"
|
79
|
+
:update
|
80
|
+
when "DELETE"
|
81
|
+
:destroy
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def path
|
86
|
+
request.path
|
87
|
+
end
|
88
|
+
|
89
|
+
def request
|
90
|
+
@env["rack-spec.request"] ||= Rack::Request.new(@env)
|
91
|
+
end
|
92
|
+
|
93
|
+
def request_method
|
94
|
+
@env["REQUEST_METHOD"]
|
95
|
+
end
|
96
|
+
|
97
|
+
def params
|
98
|
+
request.params
|
99
|
+
end
|
100
|
+
|
101
|
+
def default_status
|
102
|
+
{
|
103
|
+
"GET" => 200,
|
104
|
+
"POST" => 201,
|
105
|
+
"PUT" => 204,
|
106
|
+
"DELETE" => 204,
|
107
|
+
}[request_method]
|
108
|
+
end
|
109
|
+
|
110
|
+
def default_header
|
111
|
+
{ "Content-tYpe" => "application/json" }
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
data/lib/rack/spec/spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require "addressable/template"
|
2
|
+
|
1
3
|
module Rack
|
2
4
|
class Spec
|
3
5
|
class Spec < Hash
|
@@ -7,6 +9,16 @@ module Rack
|
|
7
9
|
end
|
8
10
|
end
|
9
11
|
|
12
|
+
def find_endpoint(env)
|
13
|
+
self["endpoints"].find do |path, source|
|
14
|
+
if Addressable::Template.new(path).extract(env["PATH_INFO"])
|
15
|
+
if endpoint = source[env["REQUEST_METHOD"]]
|
16
|
+
break endpoint
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
10
22
|
def reach(*keys)
|
11
23
|
keys.inject(self) do |hash, key|
|
12
24
|
hash[key] if hash.respond_to?(:[])
|
data/lib/rack/spec/validation.rb
CHANGED
@@ -7,7 +7,7 @@ module Rack
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def call(env)
|
10
|
-
|
10
|
+
Validators::ParametersValidator.new(spec, env).validate!
|
11
11
|
@app.call(env)
|
12
12
|
end
|
13
13
|
|
@@ -16,10 +16,6 @@ module Rack
|
|
16
16
|
def spec
|
17
17
|
Spec.new(@options[:spec])
|
18
18
|
end
|
19
|
-
|
20
|
-
def parameters_validator
|
21
|
-
@parameters_validator ||= Validators::ParametersValidator.new(spec)
|
22
|
-
end
|
23
19
|
end
|
24
20
|
end
|
25
21
|
end
|
@@ -21,19 +21,15 @@ module Rack
|
|
21
21
|
|
22
22
|
def validate!
|
23
23
|
unless valid?
|
24
|
-
raise ValidationError, self
|
24
|
+
raise Exceptions::ValidationError, self
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
private
|
29
|
-
|
30
28
|
def valid?
|
31
29
|
raise NotImplementedError
|
32
30
|
end
|
33
31
|
|
34
|
-
|
35
|
-
raise NotImplementedError
|
36
|
-
end
|
32
|
+
private
|
37
33
|
|
38
34
|
def value
|
39
35
|
@value ||= request.params[@key]
|
@@ -2,18 +2,24 @@ module Rack
|
|
2
2
|
class Spec
|
3
3
|
module Validators
|
4
4
|
class ParametersValidator
|
5
|
-
def initialize(spec)
|
5
|
+
def initialize(spec, env)
|
6
6
|
@spec = spec
|
7
|
+
@env = env
|
7
8
|
end
|
8
9
|
|
9
|
-
def validate!
|
10
|
-
parameters = @spec.reach("endpoints", env["PATH_INFO"], env["REQUEST_METHOD"], "parameters") || {}
|
10
|
+
def validate!
|
11
11
|
parameters.each do |key, hash|
|
12
12
|
hash.each do |type, constraint|
|
13
|
-
ValidatorFactory.build(key, type, constraint, env).validate!
|
13
|
+
ValidatorFactory.build(key, type, constraint, @env).validate!
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def parameters
|
21
|
+
@spec.find_endpoint(@env).try(:[], "parameters") || []
|
22
|
+
end
|
17
23
|
end
|
18
24
|
end
|
19
25
|
end
|
@@ -21,12 +21,12 @@ module Rack
|
|
21
21
|
pattern "integer", /\A-?\d+\z/
|
22
22
|
pattern "iso8601", ->(value) { Time.iso8601(value) rescue false }
|
23
23
|
|
24
|
-
private
|
25
|
-
|
26
24
|
def valid?
|
27
25
|
value.nil? || pattern === value
|
28
26
|
end
|
29
27
|
|
28
|
+
private
|
29
|
+
|
30
30
|
def pattern
|
31
31
|
self.class.patterns[constraint]
|
32
32
|
end
|
data/lib/rack/spec/version.rb
CHANGED
data/rack-spec.gemspec
CHANGED
@@ -18,8 +18,9 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
+
spec.add_dependency "activesupport"
|
22
|
+
spec.add_dependency "addressable"
|
21
23
|
spec.add_dependency "rack"
|
22
|
-
spec.add_development_dependency "activesupport", "4.0.2"
|
23
24
|
spec.add_development_dependency "bundler", "~> 1.5"
|
24
25
|
spec.add_development_dependency "pry"
|
25
26
|
spec.add_development_dependency "rack-test"
|
@@ -0,0 +1,36 @@
|
|
1
|
+
meta:
|
2
|
+
baseUri: http://api.example.com/
|
3
|
+
endpoints:
|
4
|
+
/recipes:
|
5
|
+
GET:
|
6
|
+
parameters:
|
7
|
+
page:
|
8
|
+
type: integer
|
9
|
+
minimum: 1
|
10
|
+
maximum: 10
|
11
|
+
private:
|
12
|
+
type: boolean
|
13
|
+
rank:
|
14
|
+
type: float
|
15
|
+
time:
|
16
|
+
type: iso8601
|
17
|
+
kind:
|
18
|
+
type: string
|
19
|
+
only:
|
20
|
+
- mono
|
21
|
+
- di
|
22
|
+
- tri
|
23
|
+
POST:
|
24
|
+
parameters:
|
25
|
+
title:
|
26
|
+
type: string
|
27
|
+
minimumLength: 3
|
28
|
+
maximumLength: 10
|
29
|
+
required: true
|
30
|
+
/recipes/{id}:
|
31
|
+
GET:
|
32
|
+
description: Get the recipe
|
33
|
+
PUT:
|
34
|
+
description: Update the recipe
|
35
|
+
DELETE:
|
36
|
+
description: Delete the recipe
|
data/spec/rack/spec_spec.rb
CHANGED
@@ -1,44 +1,40 @@
|
|
1
1
|
require "spec_helper"
|
2
|
-
require "active_support/core_ext/string/strip"
|
3
|
-
require "rack/test"
|
4
|
-
require "yaml"
|
5
2
|
|
6
3
|
describe Rack::Spec do
|
7
4
|
include Rack::Test::Methods
|
8
5
|
|
6
|
+
before do
|
7
|
+
stub_const(
|
8
|
+
"Recipe",
|
9
|
+
Class.new do
|
10
|
+
class << self
|
11
|
+
def index(params)
|
12
|
+
[
|
13
|
+
{ name: "test" }
|
14
|
+
]
|
15
|
+
end
|
16
|
+
|
17
|
+
def show(id, params)
|
18
|
+
{ name: "test#{id}" }
|
19
|
+
end
|
20
|
+
|
21
|
+
def create(params)
|
22
|
+
{ name: "test" }
|
23
|
+
end
|
24
|
+
|
25
|
+
def update(id, params)
|
26
|
+
end
|
27
|
+
|
28
|
+
def destroy(id, params)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
9
35
|
let(:app) do
|
10
36
|
Rack::Builder.app do
|
11
|
-
use Rack::Spec, spec: YAML.
|
12
|
-
meta:
|
13
|
-
baseUri: http://api.example.com/
|
14
|
-
endpoints:
|
15
|
-
/recipes:
|
16
|
-
GET:
|
17
|
-
parameters:
|
18
|
-
page:
|
19
|
-
type: integer
|
20
|
-
minimum: 1
|
21
|
-
maximum: 10
|
22
|
-
private:
|
23
|
-
type: boolean
|
24
|
-
rank:
|
25
|
-
type: float
|
26
|
-
time:
|
27
|
-
type: iso8601
|
28
|
-
kind:
|
29
|
-
type: string
|
30
|
-
only:
|
31
|
-
- mono
|
32
|
-
- di
|
33
|
-
- tri
|
34
|
-
POST:
|
35
|
-
parameters:
|
36
|
-
title:
|
37
|
-
type: string
|
38
|
-
minimumLength: 3
|
39
|
-
maximumLength: 10
|
40
|
-
required: true
|
41
|
-
EOS
|
37
|
+
use Rack::Spec, spec: YAML.load_file("spec/fixtures/spec.yml")
|
42
38
|
run ->(env) do
|
43
39
|
[200, {}, ["OK"]]
|
44
40
|
end
|
@@ -57,12 +53,16 @@ describe Rack::Spec do
|
|
57
53
|
{}
|
58
54
|
end
|
59
55
|
|
56
|
+
let(:response) do
|
57
|
+
last_response
|
58
|
+
end
|
59
|
+
|
60
60
|
subject do
|
61
61
|
send verb, path, params, env
|
62
62
|
last_response.status
|
63
63
|
end
|
64
64
|
|
65
|
-
describe "GET" do
|
65
|
+
describe "Validation on GET" do
|
66
66
|
let(:verb) do
|
67
67
|
:get
|
68
68
|
end
|
@@ -128,7 +128,7 @@ describe Rack::Spec do
|
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
131
|
-
describe "POST" do
|
131
|
+
describe "Validation on POST" do
|
132
132
|
before do
|
133
133
|
params[:title] = "test"
|
134
134
|
end
|
@@ -138,7 +138,7 @@ describe Rack::Spec do
|
|
138
138
|
end
|
139
139
|
|
140
140
|
context "with valid request" do
|
141
|
-
it { should ==
|
141
|
+
it { should == 201 }
|
142
142
|
end
|
143
143
|
|
144
144
|
context "with request body parameter invalid on minimumLength" do
|
@@ -162,4 +162,60 @@ describe Rack::Spec do
|
|
162
162
|
it { should == 400 }
|
163
163
|
end
|
164
164
|
end
|
165
|
+
|
166
|
+
describe "Restful" do
|
167
|
+
context "with GET /recipes" do
|
168
|
+
it "calls Recipe.index(params)" do
|
169
|
+
get "/recipes"
|
170
|
+
response.status.should == 200
|
171
|
+
response.body.should be_json_as(
|
172
|
+
[
|
173
|
+
{ name: "test" },
|
174
|
+
]
|
175
|
+
)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context "with GET /recipes/{id}" do
|
180
|
+
it "calls Recipe.show(id, params)" do
|
181
|
+
get "/recipes/1"
|
182
|
+
response.status.should == 200
|
183
|
+
response.body.should be_json_as(name: "test1")
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
context "with POST /recipes" do
|
188
|
+
before do
|
189
|
+
params[:title] = "test"
|
190
|
+
end
|
191
|
+
|
192
|
+
it "calls Recipe.create(params)" do
|
193
|
+
post "/recipes", params
|
194
|
+
response.status.should == 201
|
195
|
+
response.body.should be_json_as(name: "test")
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
context "with PUT /recipes/{id}" do
|
200
|
+
it "calls Recipe.update(id, params)" do
|
201
|
+
put "/recipes/1"
|
202
|
+
response.status.should == 204
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context "with DELETE /recipes/{id}" do
|
207
|
+
it "calls Recipe.update(id, params)" do
|
208
|
+
delete "/recipes/1"
|
209
|
+
response.status.should == 204
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
context "with undefined endpoint" do
|
214
|
+
it "falls back to the inner rack app" do
|
215
|
+
get "/undefined"
|
216
|
+
response.status.should == 200
|
217
|
+
response.body.should == "OK"
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
165
221
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-spec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryo Nakamura
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - '>='
|
@@ -25,19 +25,33 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: addressable
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - '
|
31
|
+
- - '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
34
|
-
type: :
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - '
|
38
|
+
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rack
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bundler
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -138,9 +152,11 @@ files:
|
|
138
152
|
- lib/rack-spec.rb
|
139
153
|
- lib/rack/spec.rb
|
140
154
|
- lib/rack/spec/exception_handler.rb
|
155
|
+
- lib/rack/spec/exceptions/base.rb
|
156
|
+
- lib/rack/spec/exceptions/validation_error.rb
|
157
|
+
- lib/rack/spec/restful.rb
|
141
158
|
- lib/rack/spec/spec.rb
|
142
159
|
- lib/rack/spec/validation.rb
|
143
|
-
- lib/rack/spec/validation_error.rb
|
144
160
|
- lib/rack/spec/validator_factory.rb
|
145
161
|
- lib/rack/spec/validators/base.rb
|
146
162
|
- lib/rack/spec/validators/maximum_length_validator.rb
|
@@ -154,6 +170,7 @@ files:
|
|
154
170
|
- lib/rack/spec/validators/type_validator.rb
|
155
171
|
- lib/rack/spec/version.rb
|
156
172
|
- rack-spec.gemspec
|
173
|
+
- spec/fixtures/spec.yml
|
157
174
|
- spec/rack/spec_spec.rb
|
158
175
|
- spec/spec_helper.rb
|
159
176
|
homepage: https://github.com/r7kamura/rack-spec
|
@@ -181,6 +198,7 @@ signing_key:
|
|
181
198
|
specification_version: 4
|
182
199
|
summary: Define specifications of your Rack application.
|
183
200
|
test_files:
|
201
|
+
- spec/fixtures/spec.yml
|
184
202
|
- spec/rack/spec_spec.rb
|
185
203
|
- spec/spec_helper.rb
|
186
204
|
has_rdoc:
|
@@ -1,41 +0,0 @@
|
|
1
|
-
require "json"
|
2
|
-
|
3
|
-
module Rack
|
4
|
-
class Spec
|
5
|
-
class ValidationError < StandardError
|
6
|
-
def initialize(validator)
|
7
|
-
@validator = validator
|
8
|
-
end
|
9
|
-
|
10
|
-
def message
|
11
|
-
"Invalid #{key} on `#{constraint_name}` constraint"
|
12
|
-
end
|
13
|
-
|
14
|
-
def to_rack_response
|
15
|
-
[status, header, body]
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def constraint_name
|
21
|
-
@validator.class.registered_name
|
22
|
-
end
|
23
|
-
|
24
|
-
def key
|
25
|
-
@validator.key
|
26
|
-
end
|
27
|
-
|
28
|
-
def status
|
29
|
-
400
|
30
|
-
end
|
31
|
-
|
32
|
-
def header
|
33
|
-
{ "Content-Type" => "application/json" }
|
34
|
-
end
|
35
|
-
|
36
|
-
def body
|
37
|
-
{ message: message }.to_json
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|