rack-spec 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|