require 'spec_helper' module RailsBestPractices module Reviews describe LawOfDemeterReview do let(:runner) { Core::Runner.new(prepares: [Prepares::ModelPrepare.new, Prepares::SchemaPrepare.new], reviews: LawOfDemeterReview.new) } describe "belongs_to" do before(:each) do content = <<-EOF class Invoice < ActiveRecord::Base belongs_to :user end EOF runner.prepare('app/models/invoice.rb', content) content = <<-EOF ActiveRecord::Schema.define(version: 20110216150853) do create_table "users", force => true do |t| t.string :name t.string :address t.string :cellphone end end EOF runner.prepare('db/schema.rb', content) end it "should law of demeter with erb" do content = <<-EOF <%= @invoice.user.name %> <%= @invoice.user.address %> <%= @invoice.user.cellphone %> EOF runner.review('app/views/invoices/show.html.erb', content) expect(runner.errors.size).to eq(3) expect(runner.errors[0].to_s).to eq("app/views/invoices/show.html.erb:1 - law of demeter") end it "should law of demeter with haml" do content = <<-EOF = @invoice.user.name = @invoice.user.address = @invoice.user.cellphone EOF runner.review('app/views/invoices/show.html.haml', content) expect(runner.errors.size).to eq(3) expect(runner.errors[0].to_s).to eq("app/views/invoices/show.html.haml:1 - law of demeter") end it "should law of demeter with slim" do content = <<-EOF = @invoice.user.name = @invoice.user.address = @invoice.user.cellphone EOF runner.review('app/views/invoices/show.html.slim', content) expect(runner.errors.size).to eq(3) expect(runner.errors[0].to_s).to eq("app/views/invoices/show.html.slim:1 - law of demeter") end it "should no law of demeter" do content = <<-EOF <%= @invoice.user_name %> <%= @invoice.user_address %> <%= @invoice.user_cellphone %> EOF runner.review('app/views/invoices/show.html.erb', content) expect(runner.errors.size).to eq(0) end end describe "has_one" do before(:each) do content = <<-EOF class Invoice < ActiveRecord::Base has_one :price end EOF runner.prepare('app/models/invoice.rb', content) content = <<-EOF ActiveRecord::Schema.define(version: 20110216150853) do create_table "prices", force => true do |t| t.string :currency t.integer :number end end EOF runner.prepare('db/schema.rb', content) end it "should law of demeter" do content = <<-EOF <%= @invoice.price.currency %> <%= @invoice.price.number %> EOF runner.review('app/views/invoices/show.html.erb', content) expect(runner.errors.size).to eq(2) expect(runner.errors[0].to_s).to eq("app/views/invoices/show.html.erb:1 - law of demeter") end end context "polymorphic association" do before :each do content = <<-EOF class Comment < ActiveRecord::Base belongs_to :commentable, polymorphic: true end EOF runner.prepare('app/models/comment.rb', content) content = <<-EOF class Post < ActiveRecord::Base has_many :comments end EOF runner.prepare('app/models/comment.rb', content) content = <<-EOF ActiveRecord::Schema.define(version: 20110216150853) do create_table "posts", force => true do |t| t.string :title end end EOF runner.prepare('db/schema.rb', content) end it "should law of demeter" do content = <<-EOF <%= @comment.commentable.title %> EOF runner.review('app/views/comments/index.html.erb', content) expect(runner.errors.size).to eq(1) expect(runner.errors[0].to_s).to eq("app/views/comments/index.html.erb:1 - law of demeter") end end it "should no law of demeter with method call" do content = <<-EOF class Question < ActiveRecord::Base has_many :answers, dependent: :destroy end EOF runner.prepare('app/models/question.rb', content) content = <<-EOF class Answer < ActiveRecord::Base belongs_to :question, counter_cache: true, touch: true end EOF runner.prepare('app/models/answer.rb', content) content = <<-EOF class CommentsController < ApplicationController def comment_url question_path(@answer.question) end end EOF runner.review('app/controllers/comments_controller.rb', content) expect(runner.errors.size).to eq(0) end it "should not check ignored files" do runner = Core::Runner.new(prepares: [Prepares::ModelPrepare.new, Prepares::SchemaPrepare.new], reviews: LawOfDemeterReview.new(ignored_files: /app\/views\/invoices/)) content = <<-EOF <%= @invoice.user.name %> <%= @invoice.user.address %> <%= @invoice.user.cellphone %> EOF runner.review('app/views/invoices/show.html.erb', content) expect(runner.errors.size).to eq(0) end end end end