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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fa1f5b2caa1ab2a81b5a1d16ab2c2c42061ca322
4
- data.tar.gz: 593e35231041acbdb78ede30ef3b6d05a84e31d3
3
+ metadata.gz: 982ed4f72ecd493a91d0c53fb4bf960b2850a303
4
+ data.tar.gz: f012454fe35d8abf802a7c32fa138ddfedd21d50
5
5
  SHA512:
6
- metadata.gz: 58f77db673d54bbe9c01a31094cfaebdceaee8bc0c25720d5f0029576f3f8548f9dcc7ad7f7b5850be6a226914c7b73d142b9771cd2837a6d3c2e7c2c2bccd32
7
- data.tar.gz: 5fcc86a1e6aad44874f912987dca182a5784d93589691a90b407a34ab78f07c322879d8c1012ed5ca14d2a4b89838cf453b0c699fa6c7e6829d999f13a1fb19a
6
+ metadata.gz: 28e45afcf7f5d03cf4bc764f737e846012e8d1d5c63e7936eada092c117385d05e7152533bba5e3044fab6c6d1b3a808fc19802f511ff22aca8b3594bda21d13
7
+ data.tar.gz: 5a8239586bf0f19227a2d1606bc4a220c4655864157d1afaa9ed7faa69fc1f4e18aa021380bab99c0f9e84a43ecb09866db484e560348e405d3bb94b5b65642b
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## v0.0.4
2
+ * Add Rack::Spec::Restful, strongly conventional RESTful API Provider
3
+
1
4
  ## v0.0.3
2
5
  * Add a new constraint: required
3
6
  * More DRY way for validator definition
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
- ## Usage
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, spec: YAML.load_file("spec.yml")
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
@@ -7,7 +7,7 @@ module Rack
7
7
 
8
8
  def call(env)
9
9
  @app.call(env)
10
- rescue ValidationError => exception
10
+ rescue Exceptions::ValidationError => exception
11
11
  exception.to_rack_response
12
12
  end
13
13
  end
@@ -0,0 +1,8 @@
1
+ module Rack
2
+ class Spec
3
+ module Exceptions
4
+ class Base < StandardError
5
+ end
6
+ end
7
+ end
8
+ 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
@@ -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?(:[])
@@ -7,7 +7,7 @@ module Rack
7
7
  end
8
8
 
9
9
  def call(env)
10
- parameters_validator.validate!(env)
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
- def error_message
35
- raise NotImplementedError
36
- end
32
+ private
37
33
 
38
34
  def value
39
35
  @value ||= request.params[@key]
@@ -4,8 +4,6 @@ module Rack
4
4
  class MaximumLengthValidator < Base
5
5
  register_as "maximumLength"
6
6
 
7
- private
8
-
9
7
  def valid?
10
8
  value.nil? || value.length <= constraint
11
9
  end
@@ -4,8 +4,6 @@ module Rack
4
4
  class MaximumValidator < Base
5
5
  register_as "maximum"
6
6
 
7
- private
8
-
9
7
  def valid?
10
8
  value.nil? || value.to_f <= constraint
11
9
  end
@@ -4,8 +4,6 @@ module Rack
4
4
  class MinimumLengthValidator < Base
5
5
  register_as "minimumLength"
6
6
 
7
- private
8
-
9
7
  def valid?
10
8
  value.nil? || value.length >= constraint
11
9
  end
@@ -4,8 +4,6 @@ module Rack
4
4
  class MinimumValidator < Base
5
5
  register_as "minimum"
6
6
 
7
- private
8
-
9
7
  def valid?
10
8
  value.nil? || value.to_f >= constraint
11
9
  end
@@ -2,7 +2,8 @@ module Rack
2
2
  class Spec
3
3
  module Validators
4
4
  class NullValidator < Base
5
- def validate!
5
+ def valid?
6
+ true
6
7
  end
7
8
  end
8
9
  end
@@ -4,8 +4,6 @@ module Rack
4
4
  class OnlyValidator < Base
5
5
  register_as "only"
6
6
 
7
- private
8
-
9
7
  def valid?
10
8
  value.nil? || constraint.include?(value)
11
9
  end
@@ -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!(env)
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
@@ -4,8 +4,6 @@ module Rack
4
4
  class RequiredValidator < Base
5
5
  register_as "required"
6
6
 
7
- private
8
-
9
7
  def valid?
10
8
  value.nil? == !constraint
11
9
  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
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class Spec
3
- VERSION = "0.0.3"
3
+ VERSION = "0.0.4"
4
4
  end
5
5
  end
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
@@ -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.load(<<-EOS.strip_heredoc)
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 == 200 }
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
@@ -1,6 +1,8 @@
1
1
  $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
2
2
  require "rack/spec"
3
+ require "rack/test"
3
4
  require "rspec/json_matcher"
5
+ require "yaml"
4
6
 
5
7
  RSpec.configure do |config|
6
8
  config.treat_symbols_as_metadata_keys_with_true_values = true
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.3
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-22 00:00:00.000000000 Z
11
+ date: 2014-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rack
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: activesupport
28
+ name: addressable
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '='
31
+ - - '>='
32
32
  - !ruby/object:Gem::Version
33
- version: 4.0.2
34
- type: :development
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: 4.0.2
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