diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..3ffe2b0 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,2 @@ +inherit_from: .rubocop_todo.yml + diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 0000000..ed49631 --- /dev/null +++ b/.rubocop_todo.yml @@ -0,0 +1,24 @@ +# This configuration was generated by `rubocop --auto-gen-config` +# on 2015-01-13 18:47:14 -0500 using RuboCop version 0.28.0. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# Offense count: 25 +# Configuration parameters: AllowURI, URISchemes. +Metrics/LineLength: + Max: 179 + +# Offense count: 7 +Style/Documentation: + Enabled: false + +# Offense count: 2 +# Configuration parameters: Exclude. +Style/FileName: + Enabled: false + +# Offense count: 4 +Style/RegexpLiteral: + MaxSlashes: 0 diff --git a/Guardfile b/Guardfile index f547850..4ee6431 100644 --- a/Guardfile +++ b/Guardfile @@ -4,15 +4,15 @@ guard 'rspec' do watch(%r{^spec/.+_spec\.rb$}) watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } - watch('spec/spec_helper.rb') { "spec" } + watch('spec/spec_helper.rb') { 'spec' } # Rails example watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" } watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] } - watch(%r{^spec/support/(.+)\.rb$}) { "spec" } - watch('config/routes.rb') { "spec/routing" } - watch('app/controllers/application_controller.rb') { "spec/controllers" } + watch(%r{^spec/support/(.+)\.rb$}) { 'spec' } + watch('config/routes.rb') { 'spec/routing' } + watch('app/controllers/application_controller.rb') { 'spec/controllers' } # Capybara features specs watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/features/#{m[1]}_spec.rb" } @@ -21,4 +21,3 @@ guard 'rspec' do watch(%r{^spec/acceptance/(.+)\.feature$}) watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' } end - diff --git a/README.md b/README.md index 9b3a796..2012fa0 100644 --- a/README.md +++ b/README.md @@ -82,18 +82,18 @@ end ```ruby # Serializer options can be specified on routes or namespaces. -namespace 'foo', :serializer => BarSerializer do +namespace 'foo', serializer: BarSerializer do get "/" do # will use "bar" serializer end # Options specified on a route or namespace override those of the containing namespace. - get "/home", :serializer => HomeSerializer do + get "/home", serializer: HomeSerializer do # will use "home" serializer end # All standard options for `ActiveModel::Serializers` are supported. - get "/fancy_homes", :root => 'world', :each_serializer => FancyHomesSerializer + get "/fancy_homes", root: 'world', each_serializer: FancyHomesSerializer ... end end @@ -130,7 +130,7 @@ helper method: ```ruby helpers do def current_user - @current_user ||= User.where( :access_token => params[:token]).first + @current_user ||= User.where(access_token: params[:token]).first end def authenticate! @@ -168,7 +168,7 @@ class API < Grape::API end end -API.new.get "/home" # => '{:user=>{:first_name=>"JR", :last_name=>"HE"}}' +API.new.get "/home" # => '{ user: { first_name: "JR", last_name: "HE" } }' ``` diff --git a/Rakefile b/Rakefile index da5d3ba..a0298c6 100644 --- a/Rakefile +++ b/Rakefile @@ -1,5 +1,5 @@ #!/usr/bin/env rake -require "bundler/gem_tasks" +require 'bundler/gem_tasks' require 'rspec/core' require 'rspec/core/rake_task' @@ -8,4 +8,7 @@ RSpec::Core::RakeTask.new(:spec) do |spec| spec.pattern = FileList['spec/**/*_spec.rb'] end -task :default => :spec \ No newline at end of file +require 'rubocop/rake_task' +RuboCop::RakeTask.new(:rubocop) + +task default: [:rubocop, :spec] diff --git a/grape-active_model_serializers.gemspec b/grape-active_model_serializers.gemspec index 21a209b..ec82ee5 100644 --- a/grape-active_model_serializers.gemspec +++ b/grape-active_model_serializers.gemspec @@ -2,25 +2,26 @@ require File.expand_path('../lib/grape-active_model_serializers/version', __FILE__) Gem::Specification.new do |gem| - gem.authors = ["Jonathan Richard Henry Evans"] - gem.email = ["contact@jrhe.co.uk"] - gem.summary = %q{Use active_model_serializer in grape} - gem.description = %q{Provides a Formatter for the Grape API DSL to emit objects serialized with active_model_serializers.} - gem.homepage = "https://github.com/jrhe/grape-active_model_serializers" + gem.authors = ['Jonathan Richard Henry Evans'] + gem.email = ['contact@jrhe.co.uk'] + gem.summary = 'Use active_model_serializer in grape' + gem.description = 'Provides a Formatter for the Grape API DSL to emit objects serialized with active_model_serializers.' + gem.homepage = 'https://github.com/jrhe/grape-active_model_serializers' - gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } + gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) } gem.files = `git ls-files`.split("\n") gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") - gem.name = "grape-active_model_serializers" - gem.require_paths = ["lib"] + gem.name = 'grape-active_model_serializers' + gem.require_paths = ['lib'] gem.version = Grape::ActiveModelSerializers::VERSION gem.licenses = ['MIT'] - gem.add_dependency "grape" - gem.add_dependency "active_model_serializers", ">= 0.9.0" + gem.add_dependency 'grape' + gem.add_dependency 'active_model_serializers', '>= 0.9.0' - gem.add_development_dependency "rspec" - gem.add_development_dependency "rack-test" - gem.add_development_dependency "rake" - gem.add_development_dependency "guard-rspec" + gem.add_development_dependency 'rspec' + gem.add_development_dependency 'rack-test' + gem.add_development_dependency 'rake' + gem.add_development_dependency 'guard-rspec' + gem.add_development_dependency 'rubocop', '0.28.0' end diff --git a/lib/grape-active_model_serializers/endpoint_extension.rb b/lib/grape-active_model_serializers/endpoint_extension.rb index d3b1d4a..9fa59e0 100644 --- a/lib/grape-active_model_serializers/endpoint_extension.rb +++ b/lib/grape-active_model_serializers/endpoint_extension.rb @@ -35,22 +35,18 @@ module Grape end end - def render(resources, meta={}) - set_meta_and_meta_key(meta) + def render(resources, meta = {}) + Formatter::ActiveModelSerializers.meta = meta[:meta] + Formatter::ActiveModelSerializers.meta_key = meta[:meta_key] resources end - def default_serializer_options; end - - def url_options; end - - private - - def set_meta_and_meta_key(meta) - Formatter::ActiveModelSerializers.meta = meta[:meta] - Formatter::ActiveModelSerializers.meta_key = meta[:meta_key] + def default_serializer_options end + def url_options + end end + Endpoint.send(:include, EndpointExtension) end diff --git a/lib/grape-active_model_serializers/formatter.rb b/lib/grape-active_model_serializers/formatter.rb index d20dc44..4398be3 100644 --- a/lib/grape-active_model_serializers/formatter.rb +++ b/lib/grape-active_model_serializers/formatter.rb @@ -16,12 +16,13 @@ module Grape endpoint = env['api.endpoint'] options = build_options_from_endpoint(endpoint) - if serializer = options.fetch(:serializer, ActiveModel::Serializer.serializer_for(resource)) - options[:scope] = endpoint unless options.has_key?(:scope) - # ensure we have an root to fallback on - options[:resource_name] = default_root(endpoint) if resource.respond_to?(:to_ary) - serializer.new(resource, options.merge(other_options)) - end + serializer = options.fetch(:serializer, ActiveModel::Serializer.serializer_for(resource)) + return nil unless serializer + + options[:scope] = endpoint unless options.key?(:scope) + # ensure we have an root to fallback on + options[:resource_name] = default_root(endpoint) if resource.respond_to?(:to_ary) + serializer.new(resource, options.merge(other_options)) end def other_options @@ -57,10 +58,10 @@ module Grape # otherwise the route name (e.g. get 'name') def default_root(endpoint) innermost_scope = if endpoint.respond_to?(:namespace_stackable) - endpoint.namespace_stackable(:namespace).last - else - endpoint.settings.peek[:namespace] - end + endpoint.namespace_stackable(:namespace).last + else + endpoint.settings.peek[:namespace] + end if innermost_scope innermost_scope.space diff --git a/spec/features/grape-active_model_serializers/render_spec.rb b/spec/features/grape-active_model_serializers/render_spec.rb index 7523571..0d69f30 100644 --- a/spec/features/grape-active_model_serializers/render_spec.rb +++ b/spec/features/grape-active_model_serializers/render_spec.rb @@ -20,43 +20,40 @@ describe '#render' do context 'with meta key' do it 'includes meta key and content' do - result = get_resource_with({ meta: { total: 2 }}) + result = get_resource_with(meta: { total: 2 }) expect(result).to have_key('meta') - expect(result.fetch('meta')).to eq({ 'total' => 2 }) + expect(result.fetch('meta')).to eq('total' => 2) end end context 'with a custom meta_key' do - it 'includes the custom meta key name' do - result = get_resource_with({ meta: { total: 2 }, meta_key: :custom_key_name }) + result = get_resource_with(meta: { total: 2 }, meta_key: :custom_key_name) expect(result).to have_key('custom_key_name') - expect(result.fetch('custom_key_name')).to eq({ 'total' => 2 }) + expect(result.fetch('custom_key_name')).to eq('total' => 2) end it 'ignores a lonely meta_key' do - result = get_resource_with({ meta_key: :custom_key_name }) + result = get_resource_with(meta_key: :custom_key_name) expect(result).not_to have_key('meta') expect(result).not_to have_key('custom_key_name') end end context 'junk keys' do - it 'ignores junk keys' do - result = get_resource_with({ junk_key: { total: 2 } }) + result = get_resource_with(junk_key: { total: 2 }) expect(result).not_to have_key('junk_key') end it 'ignores empty meta_key' do - result = get_resource_with({ meta: { total: 2 }, meta_key: nil }) + result = get_resource_with(meta: { total: 2 }, meta_key: nil) expect(result).to have_key('meta') end it 'ignores empty meta' do - result = get_resource_with({ meta: nil }) + result = get_resource_with(meta: nil) expect(result).not_to have_key('meta') end - end end diff --git a/spec/grape-active_model_serializers/endpoint_extension_spec.rb b/spec/grape-active_model_serializers/endpoint_extension_spec.rb index dec8151..142e84d 100644 --- a/spec/grape-active_model_serializers/endpoint_extension_spec.rb +++ b/spec/grape-active_model_serializers/endpoint_extension_spec.rb @@ -1,11 +1,10 @@ require 'spec_helper' describe 'Grape::EndpointExtension' do - if Grape::Util.const_defined?('InheritableSetting') - subject { Grape::Endpoint.new(Grape::Util::InheritableSetting.new, {path: '/', method: 'foo'}) } + subject { Grape::Endpoint.new(Grape::Util::InheritableSetting.new, path: '/', method: 'foo') } else - subject { Grape::Endpoint.new({}, {path: '/', method: 'foo'}) } + subject { Grape::Endpoint.new({}, path: '/', method: 'foo') } end let(:serializer) { Grape::Formatter::ActiveModelSerializers } @@ -20,10 +19,10 @@ describe 'Grape::EndpointExtension' do let(:users) { [user, user] } - describe "#render" do + describe '#render' do it { should respond_to(:render) } - let (:meta_content) { { total: 2 } } - let (:meta_full) { { meta: meta_content } } + let(:meta_content) { { total: 2 } } + let(:meta_full) { { meta: meta_content } } context 'supplying meta' do it 'passes through the Resource and uses given meta settings' do expect(serializer).to receive(:meta=).with(meta_content) @@ -31,7 +30,7 @@ describe 'Grape::EndpointExtension' do end end context 'supplying meta and key' do - let (:meta_key) { { meta_key: :custom_key_name } } + let(:meta_key) { { meta_key: :custom_key_name } } it 'passes through the Resource and uses given meta settings' do expect(serializer).to receive(:meta=).with(meta_content) expect(serializer).to receive(:meta_key=).with(meta_key[:meta_key]) @@ -39,5 +38,4 @@ describe 'Grape::EndpointExtension' do end end end - end diff --git a/spec/grape-active_model_serializers/formatter_spec.rb b/spec/grape-active_model_serializers/formatter_spec.rb index 68c3edc..079bdbd 100644 --- a/spec/grape-active_model_serializers/formatter_spec.rb +++ b/spec/grape-active_model_serializers/formatter_spec.rb @@ -16,7 +16,7 @@ describe Grape::Formatter::ActiveModelSerializers do it 'will wrap valid input in the meta: {} wrapper' do subject.meta = { total: 2 } - expect(subject.meta).to eq({ meta: { total: 2 } }) + expect(subject.meta).to eq(meta: { total: 2 }) end end @@ -28,7 +28,7 @@ describe Grape::Formatter::ActiveModelSerializers do it 'will wrap valid input in the meta_key: {} wrapper' do subject.meta_key = :custom_key_name - expect(subject.meta_key).to eq({ meta_key: :custom_key_name }) + expect(subject.meta_key).to eq(meta_key: :custom_key_name) end end @@ -36,9 +36,9 @@ describe Grape::Formatter::ActiveModelSerializers do let(:user) { User.new(first_name: 'John') } if Grape::Util.const_defined?('InheritableSetting') - let(:endpoint) { Grape::Endpoint.new(Grape::Util::InheritableSetting.new, {path: '/', method: 'foo'}) } + let(:endpoint) { Grape::Endpoint.new(Grape::Util::InheritableSetting.new, path: '/', method: 'foo') } else - let(:endpoint) { Grape::Endpoint.new({}, {path: '/', method: 'foo'}) } + let(:endpoint) { Grape::Endpoint.new({}, path: '/', method: 'foo') } end let(:env) { { 'api.endpoint' => endpoint } } diff --git a/spec/grape-active_model_serializers_spec.rb b/spec/grape-active_model_serializers_spec.rb index bc076ce..a642ad1 100644 --- a/spec/grape-active_model_serializers_spec.rb +++ b/spec/grape-active_model_serializers_spec.rb @@ -1,5 +1,4 @@ require 'spec_helper' describe 'grape-active_model_serializers' do - end diff --git a/spec/old_grape_ams_spec.rb b/spec/old_grape_ams_spec.rb index 28ce100..f4f6384 100644 --- a/spec/old_grape_ams_spec.rb +++ b/spec/old_grape_ams_spec.rb @@ -3,7 +3,7 @@ require 'support/models/user' require 'support/models/blog_post' require 'support/serializers/user_serializer' require 'support/serializers/blog_post_serializer' -require "grape-active_model_serializers" +require 'grape-active_model_serializers' describe Grape::ActiveModelSerializers do let(:app) { Class.new(Grape::API) } @@ -14,79 +14,78 @@ describe Grape::ActiveModelSerializers do app.formatter :json, Grape::Formatter::ActiveModelSerializers end - - it "should respond with proper content-type" do - app.get("/home/users", :serializer => UserSerializer) do + it 'should respond with proper content-type' do + app.get('/home/users', serializer: UserSerializer) do User.new end - get("/home/users") - expect(last_response.headers["Content-Type"]).to eql "application/json" + get('/home/users') + expect(last_response.headers['Content-Type']).to eql 'application/json' end context 'serializer is set to nil' do before do - app.get("/home", serializer: nil) do - {user: {first_name: "JR", last_name: "HE"}} + app.get('/home', serializer: nil) do + { user: { first_name: 'JR', last_name: 'HE' } } end end it 'uses the built in grape serializer' do - get("/home") + get('/home') expect(subject).to eql "{\"user\":{\"first_name\":\"JR\",\"last_name\":\"HE\"}}" end end context "serializer isn't set" do before do - app.get("/home") do - User.new({first_name: 'JR', last_name: 'HE', email: 'contact@jrhe.co.uk'}) + app.get('/home') do + User.new(first_name: 'JR', last_name: 'HE', email: 'contact@jrhe.co.uk') end end it 'infers the serializer' do - get "/home" + get '/home' expect(subject).to eql "{\"user\":{\"first_name\":\"JR\",\"last_name\":\"HE\"}}" end end - it "serializes arrays of objects" do - app.get("/users") do - user = User.new({first_name: 'JR', last_name: 'HE', email: 'contact@jrhe.co.uk'}) + it 'serializes arrays of objects' do + app.get('/users') do + user = User.new(first_name: 'JR', last_name: 'HE', email: 'contact@jrhe.co.uk') [user, user] end - get "/users" + get '/users' expect(subject).to eql "{\"users\":[{\"first_name\":\"JR\",\"last_name\":\"HE\"},{\"first_name\":\"JR\",\"last_name\":\"HE\"}]}" end - context "models with compound names" do + context 'models with compound names' do it "generates the proper 'root' node for individual objects" do - app.get("/home") do - BlogPost.new({title: 'Grape AM::S Rocks!', body: 'Really, it does.'}) + app.get('/home') do + BlogPost.new(title: 'Grape AM::S Rocks!', body: 'Really, it does.') end - get "/home" + get '/home' expect(subject).to eql "{\"blog_post\":{\"title\":\"Grape AM::S Rocks!\",\"body\":\"Really, it does.\"}}" end it "generates the proper 'root' node for serialized arrays" do - app.get("/blog_posts") do - blog_post = BlogPost.new({title: 'Grape AM::S Rocks!', body: 'Really, it does.'}) + app.get('/blog_posts') do + blog_post = BlogPost.new(title: 'Grape AM::S Rocks!', body: 'Really, it does.') [blog_post, blog_post] end - get "/blog_posts" + get '/blog_posts' expect(subject).to eql "{\"blog_posts\":[{\"title\":\"Grape AM::S Rocks!\",\"body\":\"Really, it does.\"},{\"title\":\"Grape AM::S Rocks!\",\"body\":\"Really, it does.\"}]}" end end - it "uses namespace options when provided" do - app.namespace :admin, :serializer => UserSerializer do + it 'uses namespace options when provided' do + app.namespace :admin, serializer: UserSerializer do get('/jeff') do User.new(first_name: 'Jeff') end end - get "/admin/jeff" + get '/admin/jeff' expect(subject).to eql "{\"user\":{\"first_name\":\"Jeff\",\"last_name\":null}}" end @@ -99,7 +98,7 @@ describe Grape::ActiveModelSerializers do end end - get "/admin/jeff" + get '/admin/jeff' expect(subject).to eql "{\"admin\":[{\"first_name\":\"Jeff\",\"last_name\":null},{\"first_name\":\"Jeff\",\"last_name\":null}]}" end end @@ -111,9 +110,8 @@ describe Grape::ActiveModelSerializers do [user, user] end - get "/people" + get '/people' expect(subject).to eql "{\"people\":[{\"first_name\":\"Jeff\",\"last_name\":null},{\"first_name\":\"Jeff\",\"last_name\":null}]}" end end end - diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 55f4181..8b1450f 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -4,9 +4,9 @@ $LOAD_PATH.unshift(File.dirname(__FILE__)) require 'bundler' Bundler.setup :default, :test -require "active_model_serializers" +require 'active_model_serializers' require 'active_support/core_ext/hash/conversions' -require "active_support/json" +require 'active_support/json' require 'rspec' require 'rack/test' require 'grape-active_model_serializers' @@ -15,4 +15,4 @@ RSpec.configure do |config| config.include Rack::Test::Methods end -Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f} +Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f } diff --git a/spec/support/models/blog_post.rb b/spec/support/models/blog_post.rb index 991f53f..4cd580a 100644 --- a/spec/support/models/blog_post.rb +++ b/spec/support/models/blog_post.rb @@ -2,8 +2,8 @@ class BlogPost include ActiveModel::SerializerSupport attr_accessor :title, :body - def initialize(params={}) - params.each do |k,v| + def initialize(params = {}) + params.each do |k, v| instance_variable_set("@#{k}", v) unless v.nil? end end diff --git a/spec/support/models/user.rb b/spec/support/models/user.rb index 8e6b6b8..7b84800 100644 --- a/spec/support/models/user.rb +++ b/spec/support/models/user.rb @@ -2,8 +2,8 @@ class User include ActiveModel::SerializerSupport attr_accessor :first_name, :last_name, :password, :email - def initialize(params={}) - params.each do |k,v| + def initialize(params = {}) + params.each do |k, v| instance_variable_set("@#{k}", v) unless v.nil? end end