diff --git a/Rakefile b/Rakefile index 434341cc..a3fa1774 100644 --- a/Rakefile +++ b/Rakefile @@ -3,7 +3,6 @@ require "bundler/gem_tasks" require 'rake/testtask' Rake::TestTask.new do |t| - t.libs << "lib" t.test_files = FileList['test/*_test.rb'] t.ruby_opts = ['-r./test/test_helper.rb'] t.verbose = true diff --git a/lib/generators/serializer/USAGE b/lib/generators/serializer/USAGE new file mode 100644 index 00000000..422f785a --- /dev/null +++ b/lib/generators/serializer/USAGE @@ -0,0 +1,6 @@ +Description: + Generates a serializer for the given resource with tests. + +Example: + `rails generate serializer Account name created_at` + diff --git a/lib/generators/serializer/serializer_generator.rb b/lib/generators/serializer/serializer_generator.rb new file mode 100644 index 00000000..54db86e2 --- /dev/null +++ b/lib/generators/serializer/serializer_generator.rb @@ -0,0 +1,37 @@ +module Rails + module Generators + class SerializerGenerator < NamedBase + source_root File.expand_path("../templates", __FILE__) + check_class_collision :suffix => "Serializer" + + argument :attributes, :type => :array, :default => [], :banner => "field:type field:type" + + class_option :parent, :type => :string, :desc => "The parent class for the generated serializer" + + def create_serializer_file + template 'serializer.rb', File.join('app/serializers', class_path, "#{file_name}_serializer.rb") + end + + private + + def attributes_names + [:id] + attributes.select { |attr| !attr.reference? }.map { |a| a.name.to_sym } + end + + def association_names + attributes.select { |attr| attr.reference? }.map { |a| a.name.to_sym } + end + + def parent_class_name + if options[:parent] + options[:parent] + elsif defined?(::ApplicationSerializer) + "ApplicationSerializer" + else + "ActiveModel::Serializer" + end + end + end + end +end + diff --git a/lib/generators/serializer/templates/serializer.rb b/lib/generators/serializer/templates/serializer.rb new file mode 100644 index 00000000..b1342098 --- /dev/null +++ b/lib/generators/serializer/templates/serializer.rb @@ -0,0 +1,8 @@ +<% module_namespacing do -%> +class <%= class_name %>Serializer < <%= parent_class_name %> + attributes <%= attributes_names.map(&:inspect).join(", ") %> +end +<% association_names.each do |attribute| -%> + has_one :<%= attribute %> +<% end -%> +<% end -%> diff --git a/test/generators_test.rb b/test/generators_test.rb new file mode 100644 index 00000000..76501760 --- /dev/null +++ b/test/generators_test.rb @@ -0,0 +1,59 @@ +class Foo < Rails::Application + if Rails.version.to_s.start_with? '4' + config.eager_load = false + config.secret_key_base = 'abc123' + end +end + +Rails.application.load_generators + +require 'generators/serializer/serializer_generator' + +class SerializerGeneratorTest < Rails::Generators::TestCase + destination File.expand_path("../tmp", __FILE__) + setup :prepare_destination + + tests Rails::Generators::SerializerGenerator + arguments %w(account name:string description:text business:references) + + def test_generates_a_serializer + run_generator + assert_file "app/serializers/account_serializer.rb", /class AccountSerializer < ActiveModel::Serializer/ + end + + def test_generates_a_namespaced_serializer + run_generator ["admin/account"] + assert_file "app/serializers/admin/account_serializer.rb", /class Admin::AccountSerializer < ActiveModel::Serializer/ + end + + def test_uses_application_serializer_if_one_exists + Object.const_set(:ApplicationSerializer, Class.new) + run_generator + assert_file "app/serializers/account_serializer.rb", /class AccountSerializer < ApplicationSerializer/ + ensure + Object.send :remove_const, :ApplicationSerializer + end + + def test_uses_given_parent + Object.const_set(:ApplicationSerializer, Class.new) + run_generator ["Account", "--parent=MySerializer"] + assert_file "app/serializers/account_serializer.rb", /class AccountSerializer < MySerializer/ + ensure + Object.send :remove_const, :ApplicationSerializer + end + + def test_generates_attributes_and_associations + run_generator + assert_file "app/serializers/account_serializer.rb" do |serializer| + assert_match(/^ attributes :id, :name, :description$/, serializer) + assert_match(/^ has_one :business$/, serializer) + end + end + + def test_with_no_attributes_does_not_add_extra_space + run_generator ["account"] + assert_file "app/serializers/account_serializer.rb" do |content| + assert_no_match /\n\nend/, content + end + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 0834af7e..a23ad862 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -5,3 +5,4 @@ require "active_support/json" require 'rails' +require 'minitest/autorun'