/spec/rails_best_practices/prepares/model_prepare_spec.rb
http://github.com/flyerhzm/rails_best_practices · Ruby · 433 lines · 403 code · 29 blank · 1 comment · 0 complexity · 89eb64de8bbf3cfd333965da86a1705c MD5 · raw file
- # frozen_string_literal: true
- require 'spec_helper'
- module RailsBestPractices
- module Prepares
- describe ModelPrepare do
- let(:runner) { Core::Runner.new(prepares: described_class.new) }
- context 'models' do
- it 'class_name with modules ::' do
- content = <<-EOF
- class Blog::Post < ActiveRecord::Base
- end
- EOF
- runner.prepare('app/models/admin/post.rb', content)
- models = Prepares.models
- expect(models.map(&:to_s)).to eq(['Blog::Post'])
- end
- it 'class_name with modules' do
- content = <<-EOF
- module Blog
- class Post < ActiveRecord::Base
- end
- end
- EOF
- runner.prepare('app/models/admin/post.rb', content)
- models = Prepares.models
- expect(models.map(&:to_s)).to eq(['Blog::Post'])
- end
- end
- context 'associations' do
- it 'parses model associations' do
- content = <<-EOF
- class Project < ActiveRecord::Base
- belongs_to :portfolio
- has_one :project_manager
- has_many :milestones
- has_and_belongs_to_many :categories
- end
- EOF
- runner.prepare('app/models/project.rb', content)
- model_associations = Prepares.model_associations
- expect(model_associations.get_association('Project', 'portfolio')).to eq(
- 'meta' => 'belongs_to', 'class_name' => 'Portfolio'
- )
- expect(model_associations.get_association('Project', 'project_manager')).to eq(
- 'meta' => 'has_one', 'class_name' => 'ProjectManager'
- )
- expect(model_associations.get_association('Project', 'milestones')).to eq(
- 'meta' => 'has_many', 'class_name' => 'Milestone'
- )
- expect(model_associations.get_association('Project', 'categories')).to eq(
- 'meta' => 'has_and_belongs_to_many', 'class_name' => 'Category'
- )
- end
- context 'with class_name option' do
- it 'parses belongs_to' do
- content = <<-EOF
- class Post < ActiveRecord::Base
- belongs_to :author, "class_name" => "Person"
- end
- EOF
- runner.prepare('app/models/post.rb', content)
- model_associations = Prepares.model_associations
- expect(model_associations.get_association('Post', 'author')).to eq(
- 'meta' => 'belongs_to', 'class_name' => 'Person'
- )
- end
- it 'parses has_one' do
- content = <<-EOF
- class Project < ActiveRecord::Base
- has_one :project_manager, "class_name" => "Person"
- end
- EOF
- runner.prepare('app/models/post.rb', content)
- model_associations = Prepares.model_associations
- expect(model_associations.get_association('Project', 'project_manager')).to eq(
- 'meta' => 'has_one', 'class_name' => 'Person'
- )
- end
- it 'parses has_many' do
- content = <<-EOF
- class Project < ActiveRecord::Base
- has_many :people, "class_name" => "Person"
- end
- EOF
- runner.prepare('app/models/project.rb', content)
- model_associations = Prepares.model_associations
- expect(model_associations.get_association('Project', 'people')).to eq(
- 'meta' => 'has_many', 'class_name' => 'Person'
- )
- end
- it 'parses has_and_belongs_to_many' do
- content = <<-EOF
- class Citizen < ActiveRecord::Base
- has_and_belongs_to_many :nations, "class_name" => "Country"
- end
- EOF
- runner.prepare('app/models/citizen.rb', content)
- model_associations = Prepares.model_associations
- expect(model_associations.get_association('Citizen', 'nations')).to eq(
- 'meta' => 'has_and_belongs_to_many', 'class_name' => 'Country'
- )
- end
- context 'namespace' do
- it 'parses with namespace' do
- content = <<-EOF
- class Community < ActiveRecord::Base
- has_many :members
- end
- EOF
- runner.prepare('app/models/community.rb', content)
- content = <<-EOF
- class Community::Member < ActiveRecord::Base
- belongs_to :community
- end
- EOF
- runner.prepare('app/models/community/member.rb', content)
- runner.after_prepare
- model_associations = Prepares.model_associations
- expect(model_associations.get_association('Community', 'members')).to eq(
- 'meta' => 'has_many', 'class_name' => 'Community::Member'
- )
- expect(model_associations.get_association('Community::Member', 'community')).to eq(
- 'meta' => 'belongs_to', 'class_name' => 'Community'
- )
- end
- it 'parses without namespace' do
- content = <<-EOF
- class Community::Member::Rating < ActiveRecord::Base
- belongs_to :member
- end
- EOF
- runner.prepare('app/models/community/member/rating.rb', content)
- content = <<-EOF
- class Community::Member < ActiveRecord::Base
- has_many :ratings
- end
- EOF
- runner.prepare('app/models/community/member.rb', content)
- runner.after_prepare
- model_associations = Prepares.model_associations
- expect(model_associations.get_association('Community::Member::Rating', 'member')).to eq(
- 'meta' => 'belongs_to', 'class_name' => 'Community::Member'
- )
- expect(model_associations.get_association('Community::Member', 'ratings')).to eq(
- 'meta' => 'has_many', 'class_name' => 'Community::Member::Rating'
- )
- end
- end
- end
- context 'mongoid embeds' do
- it 'parses embeds_many' do
- content = <<-EOF
- class Person
- include Mongoid::Document
- embeds_many :addresses
- end
- EOF
- runner.prepare('app/models/person.rb', content)
- model_associations = Prepares.model_associations
- expect(model_associations.get_association('Person', 'addresses')).to eq(
- 'meta' => 'embeds_many', 'class_name' => 'Address'
- )
- end
- it 'parses embeds_one' do
- content = <<-EOF
- class Lush
- include Mongoid::Document
- embeds_one :whiskey, class_name: "Drink", inverse_of: :alcoholic
- end
- EOF
- runner.prepare('app/models/lush.rb', content)
- model_associations = Prepares.model_associations
- expect(model_associations.get_association('Lush', 'whiskey')).to eq(
- 'meta' => 'embeds_one', 'class_name' => 'Drink'
- )
- end
- it 'parses embedded_in' do
- content = <<-EOF
- class Drink
- include Mongoid::Document
- embedded_in :alcoholic, class_name: "Lush", inverse_of: :whiskey
- end
- EOF
- runner.prepare('app/models/drink.rb', content)
- model_associations = Prepares.model_associations
- expect(model_associations.get_association('Drink', 'alcoholic')).to eq(
- 'meta' => 'embedded_in', 'class_name' => 'Lush'
- )
- end
- end
- context 'mongomapper many/one' do
- it 'parses one' do
- content = <<-EOF
- class Employee
- include MongoMapper::Document
- one :desk
- end
- EOF
- runner.prepare('app/models/employee.rb', content)
- model_associations = Prepares.model_associations
- expect(model_associations.get_association('Employee', 'desk')).to eq(
- 'meta' => 'one', 'class_name' => 'Desk'
- )
- end
- it 'parses many' do
- content = <<-EOF
- class Tree
- include MongoMapper::Document
- many :birds
- end
- EOF
- runner.prepare('app/models/tree.rb', content)
- model_associations = Prepares.model_associations
- expect(model_associations.get_association('Tree', 'birds')).to eq('meta' => 'many', 'class_name' => 'Bird')
- end
- end
- end
- context 'methods' do
- it 'parses model methods' do
- content = <<-EOF
- class Post < ActiveRecord::Base
- def save; end
- def find; end
- end
- EOF
- runner.prepare('app/models/post.rb', content)
- methods = Prepares.model_methods
- expect(methods.get_methods('Post').map(&:method_name)).to eq(%w[save find])
- end
- it 'parses model methods with access control' do
- content = <<-EOF
- class Post < ActiveRecord::Base
- def save; end
- def find; end
- protected
- def create_or_update; end
- private
- def find_by_sql; end
- end
- EOF
- runner.prepare('app/models/post.rb', content)
- methods = Prepares.model_methods
- expect(methods.get_methods('Post').map(&:method_name)).to eq(%w[save find create_or_update find_by_sql])
- expect(methods.get_methods('Post', 'public').map(&:method_name)).to eq(%w[save find])
- expect(methods.get_methods('Post', 'protected').map(&:method_name)).to eq(['create_or_update'])
- expect(methods.get_methods('Post', 'private').map(&:method_name)).to eq(['find_by_sql'])
- end
- it 'parses model methods with module ::' do
- content = <<-EOF
- class Admin::Blog::Post < ActiveRecord::Base
- def save; end
- def find; end
- end
- EOF
- runner.prepare('app/models/admin/blog/post.rb', content)
- methods = Prepares.model_methods
- expect(methods.get_methods('Admin::Blog::Post').map(&:method_name)).to eq(%w[save find])
- end
- it 'parses model methods with module' do
- content = <<-EOF
- module Admin
- module Blog
- class Post < ActiveRecord::Base
- def save; end
- def find; end
- end
- end
- end
- EOF
- runner.prepare('app/models/admin/blog/post.rb', content)
- methods = Prepares.model_methods
- expect(methods.get_methods('Admin::Blog::Post').map(&:method_name)).to eq(%w[save find])
- end
- it 'does not add methods from module' do
- content = <<-EOF
- class Model < ActiveRecord::Base
- end
- EOF
- runner.prepare('app/models/model.rb', content)
- content = <<-EOF
- module Mixin
- def mixed_method
- end
- end
- EOF
- runner.prepare('app/models/mixins/mixin.rb', content)
- methods = Prepares.model_methods
- expect(methods.get_methods('Model')).to be_empty
- end
- end
- context 'scope' do
- it 'treats named_scope as method' do
- content = <<-EOF
- class Post < ActiveRecord::Base
- named_scope :active, conditions: {active: true}
- end
- EOF
- runner.prepare('app/models/post.rb', content)
- methods = Prepares.model_methods
- expect(methods.get_methods('Post').map(&:method_name)).to eq(['active'])
- end
- it 'treats scope as method' do
- content = <<-EOF
- class Post < ActiveRecord::Base
- scope :active, where(active: true)
- end
- EOF
- runner.prepare('app/models/post.rb', content)
- methods = Prepares.model_methods
- expect(methods.get_methods('Post').map(&:method_name)).to eq(['active'])
- end
- end
- context 'alias' do
- it 'treats alias as method' do
- content = <<-EOF
- class Post < ActiveRecord::Base
- alias :new :old
- end
- EOF
- runner.prepare('app/models/post.rb', content)
- methods = Prepares.model_methods
- expect(methods.get_methods('Post').map(&:method_name)).to eq(['new'])
- end
- it 'treats alias_method as method' do
- content = <<-EOF
- class Post < ActiveRecord::Base
- alias_method :new, :old
- end
- EOF
- runner.prepare('app/models/post.rb', content)
- methods = Prepares.model_methods
- expect(methods.get_methods('Post').map(&:method_name)).to eq(['new'])
- end
- it 'treats alias_method_chain as method' do
- content = <<-EOF
- class Post < ActiveRecord::Base
- alias_method_chain :method, :feature
- end
- EOF
- runner.prepare('app/models/post.rb', content)
- methods = Prepares.model_methods
- expect(methods.get_methods('Post').map(&:method_name)).to eq(%w[method_with_feature method])
- end
- end
- context 'attributes' do
- it 'parses mongoid field' do
- content = <<-EOF
- class Post
- include Mongoid::Document
- field :title
- field :tags, type: Array
- field :comments_count, type: Integer
- field :deleted_at, type: DateTime
- field :active, type: Boolean
- end
- EOF
- runner.prepare('app/models/post.rb', content)
- model_attributes = Prepares.model_attributes
- expect(model_attributes.get_attribute_type('Post', 'title')).to eq('String')
- expect(model_attributes.get_attribute_type('Post', 'tags')).to eq('Array')
- expect(model_attributes.get_attribute_type('Post', 'comments_count')).to eq('Integer')
- expect(model_attributes.get_attribute_type('Post', 'deleted_at')).to eq('DateTime')
- expect(model_attributes.get_attribute_type('Post', 'active')).to eq('Boolean')
- end
- it 'parses mongomapper field' do
- content = <<-EOF
- class Post
- include MongoMapper::Document
- key :first_name, String
- key :last_name, String
- key :age, Integer
- key :born_at, Time
- key :active, Boolean
- key :fav_colors, Array
- end
- EOF
- runner.prepare('app/models/post.rb', content)
- model_attributes = Prepares.model_attributes
- expect(model_attributes.get_attribute_type('Post', 'first_name')).to eq('String')
- expect(model_attributes.get_attribute_type('Post', 'last_name')).to eq('String')
- expect(model_attributes.get_attribute_type('Post', 'age')).to eq('Integer')
- expect(model_attributes.get_attribute_type('Post', 'born_at')).to eq('Time')
- expect(model_attributes.get_attribute_type('Post', 'active')).to eq('Boolean')
- expect(model_attributes.get_attribute_type('Post', 'fav_colors')).to eq('Array')
- end
- end
- context 'no error' do
- it 'raiseds for finder_sql option' do
- content = <<-EOF
- class EventSubscription < ActiveRecord::Base
- has_many :event_notification_template, finder_sql: ?
- end
- EOF
- content =
- content.sub(
- '?',
- '\'SELECT event_notification_templates.* from event_notification_templates where event_type_id=#{event_type_id} and delivery_method_id=#{delivery_method_id}\''
- )
- expect { runner.prepare('app/models/event_subscription.rb', content) }.not_to raise_error
- end
- end
- end
- end
- end