grape 0.1.1 → 2.4.0
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 +7 -0
- data/CHANGELOG.md +1167 -0
- data/CONTRIBUTING.md +156 -0
- data/LICENSE +1 -1
- data/README.md +4192 -0
- data/UPGRADING.md +1697 -0
- data/grape.gemspec +28 -105
- data/grape.png +0 -0
- data/lib/grape/api/helpers.rb +9 -0
- data/lib/grape/api/instance.rb +247 -0
- data/lib/grape/api.rb +158 -194
- data/lib/grape/content_types.rb +31 -0
- data/lib/grape/cookies.rb +50 -0
- data/lib/grape/dry_types.rb +10 -0
- data/lib/grape/dsl/api.rb +17 -0
- data/lib/grape/dsl/callbacks.rb +69 -0
- data/lib/grape/dsl/configuration.rb +15 -0
- data/lib/grape/dsl/desc.rb +124 -0
- data/lib/grape/dsl/headers.rb +21 -0
- data/lib/grape/dsl/helpers.rb +108 -0
- data/lib/grape/dsl/inside_route.rb +454 -0
- data/lib/grape/dsl/logger.rb +22 -0
- data/lib/grape/dsl/middleware.rb +54 -0
- data/lib/grape/dsl/parameters.rb +266 -0
- data/lib/grape/dsl/request_response.rb +171 -0
- data/lib/grape/dsl/routing.rb +248 -0
- data/lib/grape/dsl/settings.rb +179 -0
- data/lib/grape/dsl/validations.rb +57 -0
- data/lib/grape/endpoint.rb +398 -68
- data/lib/grape/env.rb +20 -0
- data/lib/grape/error_formatter/base.rb +68 -0
- data/lib/grape/error_formatter/json.rb +28 -0
- data/lib/grape/error_formatter/serializable_hash.rb +7 -0
- data/lib/grape/error_formatter/txt.rb +21 -0
- data/lib/grape/error_formatter/xml.rb +11 -0
- data/lib/grape/error_formatter.rb +15 -0
- data/lib/grape/exceptions/base.rb +76 -0
- data/lib/grape/exceptions/conflicting_types.rb +11 -0
- data/lib/grape/exceptions/empty_message_body.rb +11 -0
- data/lib/grape/exceptions/incompatible_option_values.rb +11 -0
- data/lib/grape/exceptions/invalid_accept_header.rb +11 -0
- data/lib/grape/exceptions/invalid_formatter.rb +11 -0
- data/lib/grape/exceptions/invalid_message_body.rb +11 -0
- data/lib/grape/exceptions/invalid_parameters.rb +11 -0
- data/lib/grape/exceptions/invalid_response.rb +11 -0
- data/lib/grape/exceptions/invalid_version_header.rb +11 -0
- data/lib/grape/exceptions/invalid_versioner_option.rb +11 -0
- data/lib/grape/exceptions/invalid_with_option_for_represent.rb +11 -0
- data/lib/grape/exceptions/method_not_allowed.rb +11 -0
- data/lib/grape/exceptions/missing_group_type.rb +13 -0
- data/lib/grape/exceptions/missing_mime_type.rb +11 -0
- data/lib/grape/exceptions/missing_option.rb +11 -0
- data/lib/grape/exceptions/missing_vendor_option.rb +11 -0
- data/lib/grape/exceptions/too_deep_parameters.rb +11 -0
- data/lib/grape/exceptions/too_many_multipart_files.rb +11 -0
- data/lib/grape/exceptions/unknown_auth_strategy.rb +11 -0
- data/lib/grape/exceptions/unknown_options.rb +11 -0
- data/lib/grape/exceptions/unknown_parameter.rb +11 -0
- data/lib/grape/exceptions/unknown_params_builder.rb +11 -0
- data/lib/grape/exceptions/unknown_validator.rb +11 -0
- data/lib/grape/exceptions/unsupported_group_type.rb +13 -0
- data/lib/grape/exceptions/validation.rb +25 -0
- data/lib/grape/exceptions/validation_array_errors.rb +14 -0
- data/lib/grape/exceptions/validation_errors.rb +53 -0
- data/lib/grape/extensions/active_support/hash_with_indifferent_access.rb +24 -0
- data/lib/grape/extensions/hash.rb +27 -0
- data/lib/grape/extensions/hashie/mash.rb +24 -0
- data/lib/grape/formatter/base.rb +16 -0
- data/lib/grape/formatter/json.rb +13 -0
- data/lib/grape/formatter/serializable_hash.rb +39 -0
- data/lib/grape/formatter/txt.rb +11 -0
- data/lib/grape/formatter/xml.rb +13 -0
- data/lib/grape/formatter.rb +17 -0
- data/lib/grape/json.rb +10 -0
- data/lib/grape/locale/en.yml +59 -0
- data/lib/grape/middleware/auth/base.rb +23 -0
- data/lib/grape/middleware/auth/dsl.rb +39 -0
- data/lib/grape/middleware/auth/strategies.rb +25 -0
- data/lib/grape/middleware/auth/strategy_info.rb +15 -0
- data/lib/grape/middleware/base.rb +89 -18
- data/lib/grape/middleware/error.rb +129 -10
- data/lib/grape/middleware/filter.rb +19 -0
- data/lib/grape/middleware/formatter.rb +124 -82
- data/lib/grape/middleware/globals.rb +14 -0
- data/lib/grape/middleware/stack.rb +109 -0
- data/lib/grape/middleware/versioner/accept_version_header.rb +38 -0
- data/lib/grape/middleware/versioner/base.rb +74 -0
- data/lib/grape/middleware/versioner/header.rb +127 -0
- data/lib/grape/middleware/versioner/param.rb +32 -0
- data/lib/grape/middleware/versioner/path.rb +40 -0
- data/lib/grape/middleware/versioner.rb +21 -21
- data/lib/grape/namespace.rb +46 -0
- data/lib/grape/params_builder/base.rb +18 -0
- data/lib/grape/params_builder/hash.rb +11 -0
- data/lib/grape/params_builder/hash_with_indifferent_access.rb +11 -0
- data/lib/grape/params_builder/hashie_mash.rb +11 -0
- data/lib/grape/params_builder.rb +32 -0
- data/lib/grape/parser/base.rb +16 -0
- data/lib/grape/parser/json.rb +14 -0
- data/lib/grape/parser/xml.rb +14 -0
- data/lib/grape/parser.rb +15 -0
- data/lib/grape/path.rb +76 -0
- data/lib/grape/presenters/presenter.rb +11 -0
- data/lib/grape/railtie.rb +9 -0
- data/lib/grape/request.rb +190 -0
- data/lib/grape/router/base_route.rb +39 -0
- data/lib/grape/router/greedy_route.rb +20 -0
- data/lib/grape/router/pattern.rb +81 -0
- data/lib/grape/router/route.rb +62 -0
- data/lib/grape/router.rb +190 -0
- data/lib/grape/serve_stream/file_body.rb +36 -0
- data/lib/grape/serve_stream/sendfile_response.rb +21 -0
- data/lib/grape/serve_stream/stream_response.rb +23 -0
- data/lib/grape/types/invalid_value.rb +8 -0
- data/lib/grape/util/base_inheritable.rb +43 -0
- data/lib/grape/util/cache.rb +17 -0
- data/lib/grape/util/endpoint_configuration.rb +8 -0
- data/lib/grape/util/header.rb +13 -0
- data/lib/grape/util/inheritable_setting.rb +100 -0
- data/lib/grape/util/inheritable_values.rb +29 -0
- data/lib/grape/util/lazy/block.rb +29 -0
- data/lib/grape/util/lazy/value.rb +38 -0
- data/lib/grape/util/lazy/value_array.rb +21 -0
- data/lib/grape/util/lazy/value_enumerable.rb +34 -0
- data/lib/grape/util/lazy/value_hash.rb +21 -0
- data/lib/grape/util/media_type.rb +70 -0
- data/lib/grape/util/registry.rb +27 -0
- data/lib/grape/util/reverse_stackable_values.rb +15 -0
- data/lib/grape/util/stackable_values.rb +36 -0
- data/lib/grape/util/strict_hash_configuration.rb +108 -0
- data/lib/grape/validations/attributes_doc.rb +60 -0
- data/lib/grape/validations/attributes_iterator.rb +62 -0
- data/lib/grape/validations/contract_scope.rb +34 -0
- data/lib/grape/validations/multiple_attributes_iterator.rb +13 -0
- data/lib/grape/validations/params_scope.rb +538 -0
- data/lib/grape/validations/single_attribute_iterator.rb +26 -0
- data/lib/grape/validations/types/array_coercer.rb +61 -0
- data/lib/grape/validations/types/custom_type_coercer.rb +164 -0
- data/lib/grape/validations/types/custom_type_collection_coercer.rb +56 -0
- data/lib/grape/validations/types/dry_type_coercer.rb +66 -0
- data/lib/grape/validations/types/file.rb +31 -0
- data/lib/grape/validations/types/invalid_value.rb +17 -0
- data/lib/grape/validations/types/json.rb +71 -0
- data/lib/grape/validations/types/multiple_type_coercer.rb +57 -0
- data/lib/grape/validations/types/primitive_coercer.rb +73 -0
- data/lib/grape/validations/types/set_coercer.rb +35 -0
- data/lib/grape/validations/types/variant_collection_coercer.rb +51 -0
- data/lib/grape/validations/types.rb +213 -0
- data/lib/grape/validations/validator_factory.rb +15 -0
- data/lib/grape/validations/validators/all_or_none_of_validator.rb +16 -0
- data/lib/grape/validations/validators/allow_blank_validator.rb +20 -0
- data/lib/grape/validations/validators/as_validator.rb +14 -0
- data/lib/grape/validations/validators/at_least_one_of_validator.rb +15 -0
- data/lib/grape/validations/validators/base.rb +88 -0
- data/lib/grape/validations/validators/coerce_validator.rb +75 -0
- data/lib/grape/validations/validators/contract_scope_validator.rb +41 -0
- data/lib/grape/validations/validators/default_validator.rb +37 -0
- data/lib/grape/validations/validators/exactly_one_of_validator.rb +17 -0
- data/lib/grape/validations/validators/except_values_validator.rb +24 -0
- data/lib/grape/validations/validators/length_validator.rb +49 -0
- data/lib/grape/validations/validators/multiple_params_base.rb +34 -0
- data/lib/grape/validations/validators/mutual_exclusion_validator.rb +16 -0
- data/lib/grape/validations/validators/presence_validator.rb +15 -0
- data/lib/grape/validations/validators/regexp_validator.rb +16 -0
- data/lib/grape/validations/validators/same_as_validator.rb +29 -0
- data/lib/grape/validations/validators/values_validator.rb +60 -0
- data/lib/grape/validations.rb +21 -0
- data/lib/grape/version.rb +6 -0
- data/lib/grape/xml.rb +10 -0
- data/lib/grape.rb +81 -17
- metadata +250 -192
- data/.document +0 -5
- data/.gitignore +0 -23
- data/.rspec +0 -2
- data/.rvmrc +0 -1
- data/Gemfile +0 -21
- data/Gemfile.lock +0 -58
- data/README.markdown +0 -75
- data/Rakefile +0 -70
- data/VERSION +0 -1
- data/autotest/discover.rb +0 -1
- data/lib/grape/middleware/auth/basic.rb +0 -30
- data/lib/grape/middleware/auth/oauth2.rb +0 -55
- data/lib/grape/middleware/prefixer.rb +0 -21
- data/lib/grape/middleware_stack.rb +0 -35
- data/spec/grape/api_spec.rb +0 -343
- data/spec/grape/endpoint_spec.rb +0 -104
- data/spec/grape/middleware/auth/basic_spec.rb +0 -31
- data/spec/grape/middleware/auth/oauth2_spec.rb +0 -88
- data/spec/grape/middleware/base_spec.rb +0 -63
- data/spec/grape/middleware/error_spec.rb +0 -49
- data/spec/grape/middleware/formatter_spec.rb +0 -87
- data/spec/grape/middleware/prefixer_spec.rb +0 -30
- data/spec/grape/middleware/versioner_spec.rb +0 -40
- data/spec/grape/middleware_stack_spec.rb +0 -47
- data/spec/grape_spec.rb +0 -1
- data/spec/spec_helper.rb +0 -20
data/Rakefile
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
require 'rubygems'
|
|
2
|
-
require 'bundler'
|
|
3
|
-
|
|
4
|
-
Bundler.setup :default, :test, :development
|
|
5
|
-
|
|
6
|
-
def version
|
|
7
|
-
@version ||= open('VERSION').read.trim
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
begin
|
|
11
|
-
require 'jeweler'
|
|
12
|
-
Jeweler::Tasks.new do |gem|
|
|
13
|
-
gem.name = "grape"
|
|
14
|
-
gem.summary = %Q{A Ruby framework for rapid API development.}
|
|
15
|
-
gem.description = %Q{A Ruby framework for rapid API development with great conventions.}
|
|
16
|
-
gem.email = "michael@intridea.com"
|
|
17
|
-
gem.homepage = "http://github.com/intridea/grape"
|
|
18
|
-
gem.authors = ["Michael Bleigh"]
|
|
19
|
-
gem.add_bundler_dependencies
|
|
20
|
-
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
|
21
|
-
end
|
|
22
|
-
Jeweler::GemcutterTasks.new
|
|
23
|
-
rescue LoadError
|
|
24
|
-
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
require 'rspec/core/rake_task'
|
|
28
|
-
RSpec::Core::RakeTask.new(:spec) do |spec|
|
|
29
|
-
spec.pattern = 'spec/**/*_spec.rb'
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
|
33
|
-
spec.pattern = 'spec/**/*_spec.rb'
|
|
34
|
-
spec.rcov = true
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
task :spec => :check_dependencies
|
|
38
|
-
task :default => :spec
|
|
39
|
-
|
|
40
|
-
begin
|
|
41
|
-
require 'yard'
|
|
42
|
-
YARD_OPTS = ['-m', 'markdown', '-M', 'maruku']
|
|
43
|
-
DOC_FILES = ['lib/**/*.rb', 'README.markdown']
|
|
44
|
-
|
|
45
|
-
YARD::Rake::YardocTask.new(:doc) do |t|
|
|
46
|
-
t.files = DOC_FILES
|
|
47
|
-
t.options = YARD_OPTS
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
namespace :doc do
|
|
51
|
-
YARD::Rake::YardocTask.new(:pages) do |t|
|
|
52
|
-
t.files = DOC_FILES
|
|
53
|
-
t.options = YARD_OPTS + ['-o', '../grape.doc']
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
namespace :pages do
|
|
57
|
-
desc 'Generate and publish YARD docs to GitHub pages.'
|
|
58
|
-
task :publish => ['doc:pages'] do
|
|
59
|
-
Dir.chdir(File.dirname(__FILE__) + '/../grape.doc') do
|
|
60
|
-
system("git add .")
|
|
61
|
-
system("git add -u")
|
|
62
|
-
system("git commit -m 'Generating docs for version #{version}.'")
|
|
63
|
-
system("git push origin gh-pages")
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
rescue LoadError
|
|
69
|
-
puts "You need to install YARD."
|
|
70
|
-
end
|
data/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.1.1
|
data/autotest/discover.rb
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
Autotest.add_discovery { "rspec2" }
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
require 'rack/auth/basic'
|
|
2
|
-
|
|
3
|
-
module Grape
|
|
4
|
-
module Middleware
|
|
5
|
-
module Auth
|
|
6
|
-
class Basic < Grape::Middleware::Base
|
|
7
|
-
attr_reader :authenticator
|
|
8
|
-
|
|
9
|
-
def initialize(app, options = {}, &authenticator)
|
|
10
|
-
super(app, options)
|
|
11
|
-
@authenticator = authenticator
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def basic_request
|
|
15
|
-
Rack::Auth::Basic::Request.new(env)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def credentials
|
|
19
|
-
basic_request.provided?? basic_request.credentials : [nil, nil]
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def before
|
|
23
|
-
unless authenticator.call(*credentials)
|
|
24
|
-
throw :error, :status => 401, :message => "API Authorization Failed."
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
module Grape::Middleware::Auth
|
|
2
|
-
class OAuth2 < Grape::Middleware::Base
|
|
3
|
-
def default_options
|
|
4
|
-
{
|
|
5
|
-
:token_class => 'AccessToken',
|
|
6
|
-
:realm => 'OAuth API'
|
|
7
|
-
}
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def before
|
|
11
|
-
if request['oauth_token']
|
|
12
|
-
verify_token(request['oauth_token'])
|
|
13
|
-
elsif env['Authorization'] && t = parse_authorization_header
|
|
14
|
-
verify_token(t)
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def token_class
|
|
19
|
-
@klass ||= eval(options[:token_class])
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def verify_token(token)
|
|
23
|
-
if token = token_class.verify(token)
|
|
24
|
-
if token.expired?
|
|
25
|
-
error_out(401, 'expired_token')
|
|
26
|
-
else
|
|
27
|
-
if token.permission_for?(env)
|
|
28
|
-
env['api.token'] = token
|
|
29
|
-
else
|
|
30
|
-
error_out(403, 'insufficient_scope')
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
else
|
|
34
|
-
error_out(401, 'invalid_token')
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def parse_authorization_header
|
|
39
|
-
if env['Authorization'] =~ /oauth (.*)/i
|
|
40
|
-
$1
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def error_out(status, error)
|
|
45
|
-
throw :error, {
|
|
46
|
-
:message => 'The token provided has expired.',
|
|
47
|
-
:status => status,
|
|
48
|
-
:headers => {
|
|
49
|
-
'WWW-Authenticate' => "OAuth realm='#{options[:realm]}', error='#{error}'"
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
require 'rack/mount/utils'
|
|
2
|
-
require 'grape'
|
|
3
|
-
|
|
4
|
-
module Grape
|
|
5
|
-
module Middleware
|
|
6
|
-
class Prefixer < Base
|
|
7
|
-
def prefix
|
|
8
|
-
prefix = options[:prefix] || ""
|
|
9
|
-
prefix = Rack::Mount::Utils.normalize_path(prefix)
|
|
10
|
-
prefix
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def before
|
|
14
|
-
if env['PATH_INFO'].index(prefix) == 0
|
|
15
|
-
env['PATH_INFO'].sub!(prefix, '')
|
|
16
|
-
env['PATH_INFO'] = Rack::Mount::Utils.normalize_path(env['PATH_INFO'])
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
require 'grape'
|
|
2
|
-
|
|
3
|
-
module Grape
|
|
4
|
-
class MiddlewareStack
|
|
5
|
-
attr_reader :stack
|
|
6
|
-
|
|
7
|
-
def initialize
|
|
8
|
-
@stack = []
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
# Add a new middleware to the stack. Syntax
|
|
12
|
-
# is identical to normal middleware <tt>#use</tt>
|
|
13
|
-
# functionality.
|
|
14
|
-
#
|
|
15
|
-
# @param [Class] klass The middleware class.
|
|
16
|
-
def use(klass, *args)
|
|
17
|
-
if index = @stack.index(@stack.find{|a| a.first == klass})
|
|
18
|
-
@stack[index] = [klass, *args]
|
|
19
|
-
else
|
|
20
|
-
@stack << [klass, *args]
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
# Apply this middleware stack to a
|
|
25
|
-
# Rack application.
|
|
26
|
-
def to_app(app)
|
|
27
|
-
b = Rack::Builder.new
|
|
28
|
-
for middleware in stack
|
|
29
|
-
b.use *middleware
|
|
30
|
-
end
|
|
31
|
-
b.run app
|
|
32
|
-
b.to_app
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
data/spec/grape/api_spec.rb
DELETED
|
@@ -1,343 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe Grape::API do
|
|
4
|
-
subject { Class.new(Grape::API) }
|
|
5
|
-
before { subject.default_format :txt }
|
|
6
|
-
|
|
7
|
-
def app; subject end
|
|
8
|
-
|
|
9
|
-
describe '.prefix' do
|
|
10
|
-
it 'should route through with the prefix' do
|
|
11
|
-
subject.prefix 'awesome/sauce'
|
|
12
|
-
subject.get :hello do
|
|
13
|
-
"Hello there."
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
get 'awesome/sauce/hello'
|
|
17
|
-
last_response.body.should == "Hello there."
|
|
18
|
-
|
|
19
|
-
get '/hello'
|
|
20
|
-
last_response.status.should == 404
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
describe '.version' do
|
|
25
|
-
it 'should set the API version' do
|
|
26
|
-
subject.version 'v1'
|
|
27
|
-
subject.get :hello do
|
|
28
|
-
"Version: #{request.env['api.version']}"
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
get '/v1/hello'
|
|
32
|
-
last_response.body.should == "Version: v1"
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
it 'should add the prefix before the API version' do
|
|
36
|
-
subject.prefix 'api'
|
|
37
|
-
subject.version 'v1'
|
|
38
|
-
subject.get :hello do
|
|
39
|
-
"Version: #{request.env['api.version']}"
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
get '/api/v1/hello'
|
|
43
|
-
last_response.body.should == "Version: v1"
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
it 'should be able to specify version as a nesting' do
|
|
47
|
-
subject.version 'v2'
|
|
48
|
-
subject.get '/awesome' do
|
|
49
|
-
"Radical"
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
subject.version 'v1' do
|
|
53
|
-
get '/legacy' do
|
|
54
|
-
"Totally"
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
get '/v1/awesome'
|
|
59
|
-
last_response.status.should == 404
|
|
60
|
-
get '/v2/awesome'
|
|
61
|
-
last_response.status.should == 200
|
|
62
|
-
get '/v1/legacy'
|
|
63
|
-
last_response.status.should == 200
|
|
64
|
-
get '/v2/legacy'
|
|
65
|
-
last_response.status.should == 404
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
it 'should be able to specify multiple versions' do
|
|
69
|
-
subject.version 'v1', 'v2'
|
|
70
|
-
subject.get 'awesome' do
|
|
71
|
-
"I exist"
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
get '/v1/awesome'
|
|
75
|
-
last_response.status.should == 200
|
|
76
|
-
get '/v2/awesome'
|
|
77
|
-
last_response.status.should == 200
|
|
78
|
-
get '/v3/awesome'
|
|
79
|
-
last_response.status.should == 404
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
describe '.namespace' do
|
|
84
|
-
it 'should be retrievable and converted to a path' do
|
|
85
|
-
subject.namespace :awesome do
|
|
86
|
-
namespace.should == '/awesome'
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
it 'should come after the prefix and version' do
|
|
91
|
-
subject.prefix :rad
|
|
92
|
-
subject.version :v1
|
|
93
|
-
|
|
94
|
-
subject.namespace :awesome do
|
|
95
|
-
compile_path('hello').should == '/rad/:version/awesome/hello'
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
it 'should cancel itself after the block is over' do
|
|
100
|
-
subject.namespace :awesome do
|
|
101
|
-
namespace.should == '/awesome'
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
subject.namespace.should == '/'
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
it 'should be stackable' do
|
|
108
|
-
subject.namespace :awesome do
|
|
109
|
-
namespace :rad do
|
|
110
|
-
namespace.should == '/awesome/rad'
|
|
111
|
-
end
|
|
112
|
-
namespace.should == '/awesome'
|
|
113
|
-
end
|
|
114
|
-
subject.namespace.should == '/'
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
it 'should be callable with nil just to push onto the stack' do
|
|
118
|
-
subject.namespace do
|
|
119
|
-
version 'v2'
|
|
120
|
-
compile_path('hello').should == '/:version/hello'
|
|
121
|
-
end
|
|
122
|
-
subject.send(:compile_path, 'hello').should == '/hello'
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
%w(group resource resources).each do |als|
|
|
126
|
-
it "`.#{als}` should be an alias" do
|
|
127
|
-
subject.send(als, :awesome) do
|
|
128
|
-
namespace.should == "/awesome"
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
describe '.route' do
|
|
135
|
-
it 'should allow for no path' do
|
|
136
|
-
subject.namespace :votes do
|
|
137
|
-
get do
|
|
138
|
-
"Votes"
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
post do
|
|
142
|
-
"Created a Vote"
|
|
143
|
-
end
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
get '/votes'
|
|
147
|
-
last_response.body.should == 'Votes'
|
|
148
|
-
post '/votes'
|
|
149
|
-
last_response.body.should == 'Created a Vote'
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
it 'should allow for multiple paths' do
|
|
153
|
-
subject.get("/abc", "/def") do
|
|
154
|
-
"foo"
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
get '/abc'
|
|
158
|
-
last_response.body.should == 'foo'
|
|
159
|
-
get '/def'
|
|
160
|
-
last_response.body.should == 'foo'
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
it 'should allow for multiple verbs' do
|
|
164
|
-
subject.route([:get, :post], '/abc') do
|
|
165
|
-
"hiya"
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
get '/abc'
|
|
169
|
-
last_response.body.should == 'hiya'
|
|
170
|
-
post '/abc'
|
|
171
|
-
last_response.body.should == 'hiya'
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
it 'should allow for :any as a verb' do
|
|
175
|
-
subject.route(:any, '/abc') do
|
|
176
|
-
"lol"
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
%w(get post put delete).each do |m|
|
|
180
|
-
send(m, '/abc')
|
|
181
|
-
last_response.body.should == 'lol'
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
verbs = %w(post get head delete put)
|
|
186
|
-
verbs.each do |verb|
|
|
187
|
-
it "should allow and properly constrain a #{verb.upcase} method" do
|
|
188
|
-
subject.send(verb, '/example') do
|
|
189
|
-
verb
|
|
190
|
-
end
|
|
191
|
-
send(verb, '/example')
|
|
192
|
-
last_response.body.should == verb
|
|
193
|
-
# Call it with a method other than the properly constrained one.
|
|
194
|
-
send(verbs[(verbs.index(verb) + 1) % verbs.size], '/example')
|
|
195
|
-
last_response.status.should == 404
|
|
196
|
-
end
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
it 'should return a 201 response code for POST by default' do
|
|
200
|
-
subject.post('example') do
|
|
201
|
-
"Created"
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
post '/example'
|
|
205
|
-
last_response.status.should == 201
|
|
206
|
-
last_response.body.should == 'Created'
|
|
207
|
-
end
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
describe '.basic' do
|
|
211
|
-
it 'should protect any resources on the same scope' do
|
|
212
|
-
subject.http_basic do |u,p|
|
|
213
|
-
u == 'allow'
|
|
214
|
-
end
|
|
215
|
-
subject.get(:hello){ "Hello, world."}
|
|
216
|
-
get '/hello'
|
|
217
|
-
last_response.status.should == 401
|
|
218
|
-
get '/hello', {}, 'HTTP_AUTHORIZATION' => encode_basic('allow','whatever')
|
|
219
|
-
last_response.status.should == 200
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
it 'should be scopable' do
|
|
223
|
-
subject.get(:hello){ "Hello, world."}
|
|
224
|
-
subject.namespace :admin do
|
|
225
|
-
http_basic do |u,p|
|
|
226
|
-
u == 'allow'
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
get(:hello){ "Hello, world." }
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
get '/hello'
|
|
233
|
-
last_response.status.should == 200
|
|
234
|
-
get '/admin/hello'
|
|
235
|
-
last_response.status.should == 401
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
it 'should be callable via .auth as well' do
|
|
239
|
-
subject.auth :http_basic do |u,p|
|
|
240
|
-
u == 'allow'
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
subject.get(:hello){ "Hello, world."}
|
|
244
|
-
get '/hello'
|
|
245
|
-
last_response.status.should == 401
|
|
246
|
-
get '/hello', {}, 'HTTP_AUTHORIZATION' => encode_basic('allow','whatever')
|
|
247
|
-
last_response.status.should == 200
|
|
248
|
-
end
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
describe '.helpers' do
|
|
252
|
-
it 'should be accessible from the endpoint' do
|
|
253
|
-
subject.helpers do
|
|
254
|
-
def hello
|
|
255
|
-
"Hello, world."
|
|
256
|
-
end
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
subject.get '/howdy' do
|
|
260
|
-
hello
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
get '/howdy'
|
|
264
|
-
last_response.body.should == 'Hello, world.'
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
it 'should be scopable' do
|
|
268
|
-
subject.helpers do
|
|
269
|
-
def generic
|
|
270
|
-
'always there'
|
|
271
|
-
end
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
subject.namespace :admin do
|
|
275
|
-
helpers do
|
|
276
|
-
def secret
|
|
277
|
-
'only in admin'
|
|
278
|
-
end
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
get '/secret' do
|
|
282
|
-
[generic, secret].join ':'
|
|
283
|
-
end
|
|
284
|
-
end
|
|
285
|
-
|
|
286
|
-
subject.get '/generic' do
|
|
287
|
-
[generic, respond_to?(:secret)].join ':'
|
|
288
|
-
end
|
|
289
|
-
|
|
290
|
-
get '/generic'
|
|
291
|
-
last_response.body.should == 'always there:false'
|
|
292
|
-
get '/admin/secret'
|
|
293
|
-
last_response.body.should == 'always there:only in admin'
|
|
294
|
-
end
|
|
295
|
-
|
|
296
|
-
it 'should be reopenable' do
|
|
297
|
-
subject.helpers do
|
|
298
|
-
def one
|
|
299
|
-
1
|
|
300
|
-
end
|
|
301
|
-
end
|
|
302
|
-
|
|
303
|
-
subject.helpers do
|
|
304
|
-
def two
|
|
305
|
-
2
|
|
306
|
-
end
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
subject.get 'howdy' do
|
|
310
|
-
[one, two]
|
|
311
|
-
end
|
|
312
|
-
|
|
313
|
-
lambda{get '/howdy'}.should_not raise_error
|
|
314
|
-
end
|
|
315
|
-
end
|
|
316
|
-
|
|
317
|
-
describe '.scope' do
|
|
318
|
-
it 'should scope the various settings' do
|
|
319
|
-
subject.version 'v2'
|
|
320
|
-
|
|
321
|
-
subject.scope :legacy do
|
|
322
|
-
version 'v1'
|
|
323
|
-
|
|
324
|
-
get '/abc' do
|
|
325
|
-
version
|
|
326
|
-
end
|
|
327
|
-
end
|
|
328
|
-
|
|
329
|
-
subject.get '/def' do
|
|
330
|
-
version
|
|
331
|
-
end
|
|
332
|
-
|
|
333
|
-
get '/v2/abc'
|
|
334
|
-
last_response.status.should == 404
|
|
335
|
-
get '/v1/abc'
|
|
336
|
-
last_response.status.should == 200
|
|
337
|
-
get '/v1/def'
|
|
338
|
-
last_response.status.should == 404
|
|
339
|
-
get '/v2/def'
|
|
340
|
-
last_response.status.should == 200
|
|
341
|
-
end
|
|
342
|
-
end
|
|
343
|
-
end
|
data/spec/grape/endpoint_spec.rb
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe Grape::Endpoint do
|
|
4
|
-
subject { Class.new(Grape::API) }
|
|
5
|
-
before { subject.default_format :txt }
|
|
6
|
-
def app; subject end
|
|
7
|
-
|
|
8
|
-
describe '#status' do
|
|
9
|
-
it 'should be callable from within a block' do
|
|
10
|
-
subject.get('/home') do
|
|
11
|
-
status 206
|
|
12
|
-
"Hello"
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
get '/home'
|
|
16
|
-
last_response.status.should == 206
|
|
17
|
-
last_response.body.should == "Hello"
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
describe '#header' do
|
|
22
|
-
it 'should be callable from within a block' do
|
|
23
|
-
subject.get('/hey') do
|
|
24
|
-
header 'X-Awesome', 'true'
|
|
25
|
-
"Awesome"
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
get '/hey'
|
|
29
|
-
last_response.headers['X-Awesome'].should == 'true'
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
describe '#params' do
|
|
34
|
-
it 'should be available to the caller' do
|
|
35
|
-
subject.get('/hey') do
|
|
36
|
-
params[:howdy]
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
get '/hey?howdy=hey'
|
|
40
|
-
last_response.body.should == 'hey'
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
it 'should parse from path segments' do
|
|
44
|
-
subject.get('/hey/:id') do
|
|
45
|
-
params[:id]
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
get '/hey/12'
|
|
49
|
-
last_response.body.should == '12'
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
describe '#error!' do
|
|
54
|
-
it 'should accept a message' do
|
|
55
|
-
subject.get('/hey') do
|
|
56
|
-
error! "This is not valid."
|
|
57
|
-
"This is valid."
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
get '/hey'
|
|
61
|
-
last_response.status.should == 403
|
|
62
|
-
last_response.body.should == "This is not valid."
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
it 'should accept a code' do
|
|
66
|
-
subject.get('/hey') do
|
|
67
|
-
error! "Unauthorized.", 401
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
get '/hey'
|
|
71
|
-
last_response.status.should == 401
|
|
72
|
-
last_response.body.should == "Unauthorized."
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
it 'should not persist params between calls' do
|
|
77
|
-
subject.post('/new') do
|
|
78
|
-
params[:text]
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
post '/new', :text => 'abc'
|
|
82
|
-
last_response.body.should == 'abc'
|
|
83
|
-
|
|
84
|
-
post '/new', :text => 'def'
|
|
85
|
-
last_response.body.should == 'def'
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
it 'should reset all instance variables (except block) between calls' do
|
|
89
|
-
subject.helpers do
|
|
90
|
-
def memoized
|
|
91
|
-
@memoized ||= params[:howdy]
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
subject.get('/hello') do
|
|
96
|
-
memoized
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
get '/hello?howdy=hey'
|
|
100
|
-
last_response.body.should == 'hey'
|
|
101
|
-
get '/hello?howdy=yo'
|
|
102
|
-
last_response.body.should == 'yo'
|
|
103
|
-
end
|
|
104
|
-
end
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
require 'base64'
|
|
4
|
-
|
|
5
|
-
describe Grape::Middleware::Auth::Basic do
|
|
6
|
-
def app
|
|
7
|
-
Rack::Builder.new do |b|
|
|
8
|
-
b.use Grape::Middleware::Error
|
|
9
|
-
b.use(Grape::Middleware::Auth::Basic) do |u,p|
|
|
10
|
-
u && p && u == p
|
|
11
|
-
end
|
|
12
|
-
b.run lambda{|env| [200, {}, "Hello there."]}
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it 'should throw a 401 if no auth is given' do
|
|
17
|
-
@proc = lambda{ false }
|
|
18
|
-
get '/whatever'
|
|
19
|
-
last_response.status.should == 401
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
it 'should authenticate if given valid creds' do
|
|
23
|
-
get '/whatever', {}, 'HTTP_AUTHORIZATION' => encode_basic('admin','admin')
|
|
24
|
-
last_response.status.should == 200
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it 'should throw a 401 is wrong auth is given' do
|
|
28
|
-
get '/whatever', {}, 'HTTP_AUTHORIZATION' => encode_basic('admin','wrong')
|
|
29
|
-
last_response.status.should == 401
|
|
30
|
-
end
|
|
31
|
-
end
|