Skip to content

Commit

Permalink
Merge pull request #1287 from totothink/master
Browse files Browse the repository at this point in the history
clean DSL module
  • Loading branch information
dblock committed Feb 23, 2016
2 parents 84e5ec6 + 6a49d6c commit 4032ea8
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 186 deletions.
2 changes: 2 additions & 0 deletions lib/grape.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ module DSL
autoload :RequestResponse
autoload :Routing
autoload :Validations
autoload :Logger
autoload :Desc
end
end

Expand Down
109 changes: 2 additions & 107 deletions lib/grape/dsl/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,91 +6,9 @@ module Configuration
extend ActiveSupport::Concern

module ClassMethods
attr_writer :logger

include Grape::DSL::Settings

# Set or retrive the configured logger. If none was configured, this
# method will create a new one, logging to stdout.
# @param logger [Object] the new logger to use
def logger(logger = nil)
if logger
global_setting(:logger, logger)
else
global_setting(:logger) || global_setting(:logger, Logger.new($stdout))
end
end

# Add a description to the next namespace or function.
# @param description [String] descriptive string for this endpoint
# or namespace
# @param options [Hash] other properties you can set to describe the
# endpoint or namespace. Optional.
# @option options :detail [String] additional detail about this endpoint
# @option options :params [Hash] param types and info. normally, you set
# these via the `params` dsl method.
# @option options :entity [Grape::Entity] the entity returned upon a
# successful call to this action
# @option options :http_codes [Array[Array]] possible HTTP codes this
# endpoint may return, with their meanings, in a 2d array
# @option options :named [String] a specific name to help find this route
# @option options :headers [Hash] HTTP headers this method can accept
# @yield a block yielding an instance context with methods mapping to
# each of the above, except that :entity is also aliased as #success
# and :http_codes is aliased as #failure.
#
# @example
#
# desc 'create a user'
# post '/users' do
# # ...
# end
#
# desc 'find a user' do
# detail 'locates the user from the given user ID'
# failure [ [404, 'Couldn\'t find the given user' ] ]
# success User::Entity
# end
# get '/user/:id' do
# # ...
# end
#
def desc(description, options = {}, &config_block)
if block_given?
config_class = Grape::DSL::Configuration.desc_container

config_class.configure do
description description
end

config_class.configure(&config_block)
unless options.empty?
warn '[DEPRECATION] Passing a options hash and a block to `desc` is deprecated. Move all hash options to block.'
end
options = config_class.settings
else
options = options.merge(description: description)
end

namespace_setting :description, options
route_setting :description, options
end

def description_field(field, value = nil)
if value
description = route_setting(:description)
description ||= route_setting(:description, {})
description[field] = value
else
description = route_setting(:description)
description[field] if description
end
end

def unset_description_field(field)
description = route_setting(:description)
description.delete(field) if description
end
include Grape::DSL::Logger
include Grape::DSL::Desc
end

module_function
Expand All @@ -100,29 +18,6 @@ def stacked_hash_to_hash(settings)
return if settings.blank?
settings.each_with_object({}) { |value, result| result.deep_merge!(value) }
end

# Returns an object which configures itself via an instance-context DSL.
def desc_container
Module.new do
include Grape::Util::StrictHashConfiguration.module(
:description,
:detail,
:params,
:entity,
:http_codes,
:named,
:headers
)

def config_context.success(*args)
entity(*args)
end

def config_context.failure(*args)
http_codes(*args)
end
end
end
end
end
end
101 changes: 101 additions & 0 deletions lib/grape/dsl/desc.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
module Grape
module DSL
module Desc
include Grape::DSL::Settings

# Add a description to the next namespace or function.
# @param description [String] descriptive string for this endpoint
# or namespace
# @param options [Hash] other properties you can set to describe the
# endpoint or namespace. Optional.
# @option options :detail [String] additional detail about this endpoint
# @option options :params [Hash] param types and info. normally, you set
# these via the `params` dsl method.
# @option options :entity [Grape::Entity] the entity returned upon a
# successful call to this action
# @option options :http_codes [Array[Array]] possible HTTP codes this
# endpoint may return, with their meanings, in a 2d array
# @option options :named [String] a specific name to help find this route
# @option options :headers [Hash] HTTP headers this method can accept
# @yield a block yielding an instance context with methods mapping to
# each of the above, except that :entity is also aliased as #success
# and :http_codes is aliased as #failure.
#
# @example
#
# desc 'create a user'
# post '/users' do
# # ...
# end
#
# desc 'find a user' do
# detail 'locates the user from the given user ID'
# failure [ [404, 'Couldn\'t find the given user' ] ]
# success User::Entity
# end
# get '/user/:id' do
# # ...
# end
#
def desc(description, options = {}, &config_block)
if block_given?
config_class = desc_container

config_class.configure do
description description
end

config_class.configure(&config_block)
unless options.empty?
warn '[DEPRECATION] Passing a options hash and a block to `desc` is deprecated. Move all hash options to block.'
end
options = config_class.settings
else
options = options.merge(description: description)
end

namespace_setting :description, options
route_setting :description, options
end

def description_field(field, value = nil)
if value
description = route_setting(:description)
description ||= route_setting(:description, {})
description[field] = value
else
description = route_setting(:description)
description[field] if description
end
end

def unset_description_field(field)
description = route_setting(:description)
description.delete(field) if description
end

# Returns an object which configures itself via an instance-context DSL.
def desc_container
Module.new do
include Grape::Util::StrictHashConfiguration.module(
:description,
:detail,
:params,
:entity,
:http_codes,
:named,
:headers
)

def config_context.success(*args)
entity(*args)
end

def config_context.failure(*args)
http_codes(*args)
end
end
end
end
end
end
20 changes: 20 additions & 0 deletions lib/grape/dsl/logger.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module Grape
module DSL
module Logger
include Grape::DSL::Settings

attr_writer :logger

# Set or retrive the configured logger. If none was configured, this
# method will create a new one, logging to stdout.
# @param logger [Object] the new logger to use
def logger(logger = nil)
if logger
global_setting(:logger, logger)
else
global_setting(:logger) || global_setting(:logger, ::Logger.new($stdout))
end
end
end
end
end
4 changes: 0 additions & 4 deletions lib/grape/dsl/routing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ def version(*args, &block)
namespace_inheritable(:version, args)
namespace_inheritable(:version_options, options)
end

# reset_validations!
end

@versions.last unless @versions.nil?
Expand Down Expand Up @@ -91,8 +89,6 @@ def mount(mounts)

in_setting = app.top_level_setting

# app.regenerate_endpoints(in_setting)

app.change!
change!
end
Expand Down
75 changes: 0 additions & 75 deletions spec/grape/dsl/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,81 +9,6 @@ class Dummy
end
describe Configuration do
subject { Class.new(ConfigurationSpec::Dummy) }
let(:logger) { double(:logger) }

describe '.logger' do
it 'sets a logger' do
subject.logger logger
expect(subject.logger).to eq logger
end

it 'returns a logger' do
expect(subject.logger logger).to eq logger
end
end

describe '.desc' do
it 'sets a description' do
desc_text = 'The description'
options = { message: 'none' }
subject.desc desc_text, options
expect(subject.namespace_setting(:description)).to eq(options.merge(description: desc_text))
expect(subject.route_setting(:description)).to eq(options.merge(description: desc_text))
end

it 'can be set with a block' do
expected_options = {
description: 'The description',
detail: 'more details',
params: { first: :param },
entity: Object,
http_codes: [[401, 'Unauthorized', 'Entities::Error']],
named: 'My named route',
headers: [XAuthToken: {
description: 'Valdates your identity',
required: true
},
XOptionalHeader: {
description: 'Not really needed',
required: false
}
]
}

subject.desc 'The description' do
detail 'more details'
params(first: :param)
success Object
failure [[401, 'Unauthorized', 'Entities::Error']]
named 'My named route'
headers [XAuthToken: {
description: 'Valdates your identity',
required: true
},
XOptionalHeader: {
description: 'Not really needed',
required: false
}
]
end

expect(subject.namespace_setting(:description)).to eq(expected_options)
expect(subject.route_setting(:description)).to eq(expected_options)
end

it 'can be set with options and a block' do
expect(subject).to receive(:warn).with('[DEPRECATION] Passing a options hash and a block to `desc` is deprecated. Move all hash options to block.')

desc_text = 'The description'
detail_text = 'more details'
options = { message: 'none' }
subject.desc desc_text, options do
detail detail_text
end
expect(subject.namespace_setting(:description)).to eq(description: desc_text, detail: detail_text)
expect(subject.route_setting(:description)).to eq(description: desc_text, detail: detail_text)
end
end
end
end
end
Loading

0 comments on commit 4032ea8

Please sign in to comment.