From 6a49d6c2086884770f9a322fa01d4fb3fd14c256 Mon Sep 17 00:00:00 2001 From: aaron Date: Tue, 23 Feb 2016 12:51:50 +0800 Subject: [PATCH] clean DSL module --- lib/grape.rb | 2 + lib/grape/dsl/configuration.rb | 109 +-------------------------- lib/grape/dsl/desc.rb | 101 +++++++++++++++++++++++++ lib/grape/dsl/logger.rb | 20 +++++ lib/grape/dsl/routing.rb | 4 - spec/grape/dsl/configuration_spec.rb | 75 ------------------ spec/grape/dsl/desc_spec.rb | 77 +++++++++++++++++++ spec/grape/dsl/logger_spec.rb | 26 +++++++ 8 files changed, 228 insertions(+), 186 deletions(-) create mode 100644 lib/grape/dsl/desc.rb create mode 100644 lib/grape/dsl/logger.rb create mode 100644 spec/grape/dsl/desc_spec.rb create mode 100644 spec/grape/dsl/logger_spec.rb diff --git a/lib/grape.rb b/lib/grape.rb index 78dc98c154..4224dec0de 100644 --- a/lib/grape.rb +++ b/lib/grape.rb @@ -145,6 +145,8 @@ module DSL autoload :RequestResponse autoload :Routing autoload :Validations + autoload :Logger + autoload :Desc end end diff --git a/lib/grape/dsl/configuration.rb b/lib/grape/dsl/configuration.rb index 69e2c13495..d5ad363339 100644 --- a/lib/grape/dsl/configuration.rb +++ b/lib/grape/dsl/configuration.rb @@ -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 @@ -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 diff --git a/lib/grape/dsl/desc.rb b/lib/grape/dsl/desc.rb new file mode 100644 index 0000000000..e758bf2c97 --- /dev/null +++ b/lib/grape/dsl/desc.rb @@ -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 diff --git a/lib/grape/dsl/logger.rb b/lib/grape/dsl/logger.rb new file mode 100644 index 0000000000..40cccdaac5 --- /dev/null +++ b/lib/grape/dsl/logger.rb @@ -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 diff --git a/lib/grape/dsl/routing.rb b/lib/grape/dsl/routing.rb index ac9ff1fdd0..513089fd4d 100644 --- a/lib/grape/dsl/routing.rb +++ b/lib/grape/dsl/routing.rb @@ -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? @@ -91,8 +89,6 @@ def mount(mounts) in_setting = app.top_level_setting - # app.regenerate_endpoints(in_setting) - app.change! change! end diff --git a/spec/grape/dsl/configuration_spec.rb b/spec/grape/dsl/configuration_spec.rb index 32212811ed..6216b007ca 100644 --- a/spec/grape/dsl/configuration_spec.rb +++ b/spec/grape/dsl/configuration_spec.rb @@ -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 diff --git a/spec/grape/dsl/desc_spec.rb b/spec/grape/dsl/desc_spec.rb new file mode 100644 index 0000000000..9bc57fe086 --- /dev/null +++ b/spec/grape/dsl/desc_spec.rb @@ -0,0 +1,77 @@ +require 'spec_helper' + +module Grape + module DSL + module DescSpec + class Dummy + extend Grape::DSL::Desc + end + end + describe Desc do + subject { Class.new(DescSpec::Dummy) } + + 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 diff --git a/spec/grape/dsl/logger_spec.rb b/spec/grape/dsl/logger_spec.rb new file mode 100644 index 0000000000..bc7884ba0b --- /dev/null +++ b/spec/grape/dsl/logger_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +module Grape + module DSL + module LoggerSpec + class Dummy + extend Grape::DSL::Logger + end + end + describe Logger do + subject { Class.new(LoggerSpec::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 + end + end +end