Skip to content

Commit

Permalink
Rspec: verify partial doubles
Browse files Browse the repository at this point in the history
  • Loading branch information
miks committed Oct 19, 2014
1 parent 352d14f commit d6ed3b0
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 52 deletions.
8 changes: 8 additions & 0 deletions releaf-core/spec/helpers/application_helper_spec.rb
Expand Up @@ -31,8 +31,16 @@

describe "#i18n_options_for_select" do
Color = Struct.new(:id, :to_s)
let(:helper) do
helper = instance_double(Releaf::BaseController)
helper.extend Releaf::ApplicationHelper
helper.extend ActionView::Helpers

helper
end

before do

translation = FactoryGirl.create(:translation, :key => "admin.global.colors-red")
FactoryGirl.create(:translation_data, :lang => "en", :localization => "Color red", :translation => translation)
I18n.backend.reload_cache
Expand Down
4 changes: 2 additions & 2 deletions releaf-core/spec/helpers/form_builder_spec.rb
Expand Up @@ -99,15 +99,15 @@ class FormBuilderTestHelper < ActionView::Base

describe "#render_field_by_options" do
let(:options){ {
render_method: "custom_render_method",
render_method: "sortable_column_name", # just random method here
association: nil,
field: "title",
subfields: [:a, :b],
association: true
} }

before do
allow(subject).to receive(:custom_render_method)
allow(subject).to receive(:sortable_column_name)
.with(no_args).and_return("_render_method_content_")
allow(subject).to receive(:releaf_association_fields)
.with("title", [:a, :b]).and_return("_association_method_content_")
Expand Down
42 changes: 26 additions & 16 deletions releaf-core/spec/helpers/table_builder_spec.rb
Expand Up @@ -2,15 +2,25 @@

describe Releaf::TableBuilder, type: :class do
class TableBuilderTestHelper < ActionView::Base
include Releaf::ToolboxHelper
include Releaf::ApplicationHelper
end

class DummyTableBuilderInheriter < Releaf::TableBuilder
def some_cell_method(resource, column); end
def custom_format(resource, column); end
def format_big_boolean_content(resource, column); end
def title_cell; end
def custom_title(resource); end
end

let(:template){ TableBuilderTestHelper.new }
let(:resource_class){ Book }
let(:resource){ resource_class.new(id: 77) }
let(:collection){ Book.all }
let(:options){ {toolbox: false} }
let(:subject){ described_class.new(collection, resource_class, template, options) }
let(:inheriter_subject){ DummyTableBuilderInheriter.new(collection, resource_class, template, options) }

it "includes Releaf::Builder" do
expect(Releaf::TableBuilder.ancestors).to include(Releaf::Builder)
Expand Down Expand Up @@ -180,7 +190,9 @@ class TableBuilderTestHelper < ActionView::Base

describe "#row_url" do
it "returns edit url for given resource" do
allow(subject.template).to receive(:resource_edit_url).with("a").and_return('_url_')
template = double("some template")
allow(template).to receive(:resource_edit_url).with("a").and_return('_url_')
allow(subject).to receive(:template).and_return(template)
expect(subject.row_url("a")).to eq('_url_')
end

Expand Down Expand Up @@ -222,35 +234,35 @@ class TableBuilderTestHelper < ActionView::Base
}
resource = resource_class.new(id: 89)

allow(subject).to receive(:columns).and_return(columns)
allow(subject).to receive(:row_url).with(resource).and_return("url_value")
allow(inheriter_subject).to receive(:columns).and_return(columns)
allow(inheriter_subject).to receive(:row_url).with(resource).and_return("url_value")

allow(subject).to receive(:some_cell_method)
allow(inheriter_subject).to receive(:some_cell_method)
.with(resource, cell_method: "some_cell_method", url: "url_value").and_return("_title_cell_value")
allow(subject).to receive(:cell)
allow(inheriter_subject).to receive(:cell)
.with(resource, :color, url: "url_value").and_return("_color_cell_value")

content = '<tr class="row" data-id="89">_title_cell_value_color_cell_value</tr>'
expect(subject.row(resource)).to eq(content)
expect(inheriter_subject.row(resource)).to eq(content)
end
end

describe "#cell_content" do
it "returns format method output with resource and column as arguments wrapped in span element" do
options = {format_method: "custom_format"}
allow(subject).to receive(:custom_format).with("a", :title).and_return('_custom " format_')
allow(inheriter_subject).to receive(:custom_format).with("a", :title).and_return('_custom " format_')

content = '<span>_custom &quot; format_</span>'
expect(subject.cell_content("a", :title, options)).to eq(content)
expect(inheriter_subject.cell_content("a", :title, options)).to eq(content)
end

context "when given options has :content_method" do
it "returns content method output with resource as argument wrapped in span element" do
options = {content_method: "custom_title", format_method: "custom_format"}
allow(subject).to receive(:custom_title).with("a").and_return('_custom " _value_')
allow(inheriter_subject).to receive(:custom_title).with("a").and_return('_custom " _value_')

content = '<span>_custom &quot; _value_</span>'
expect(subject.cell_content("a", :title, options)).to eq(content)
expect(inheriter_subject.cell_content("a", :title, options)).to eq(content)
end
end
end
Expand Down Expand Up @@ -350,8 +362,7 @@ class TableBuilderTestHelper < ActionView::Base
describe "#cell_content_method" do
context "when custom cell content method exists" do
it "returns custom cell content method name" do
allow(subject).to receive(:title_content)
expect(subject.cell_content_method(:title)).to eq("title_content")
expect(subject.cell_content_method(:format_string)).to eq("format_string_content")
end
end

Expand All @@ -365,8 +376,7 @@ class TableBuilderTestHelper < ActionView::Base
describe "#cell_method" do
context "when custom cell method exists" do
it "returns custom cell method name" do
allow(subject).to receive(:title_cell)
expect(subject.cell_method(:title)).to eq("title_cell")
expect(inheriter_subject.cell_method(:title)).to eq("title_cell")
end
end

Expand Down Expand Up @@ -426,12 +436,12 @@ class TableBuilderTestHelper < ActionView::Base
describe "#column_type_format_method" do
before do
allow(subject).to receive(:column_type).with(:title).and_return(:big_boolean)
allow(inheriter_subject).to receive(:column_type).with(:title).and_return(:big_boolean)
end

context "when format method for returned column type exists" do
it "returns column type format method" do
allow(subject).to receive(:format_big_boolean_content)
expect(subject.column_type_format_method(:title)).to eq(:format_big_boolean_content)
expect(inheriter_subject.column_type_format_method(:title)).to eq(:format_big_boolean_content)
end
end

Expand Down
8 changes: 4 additions & 4 deletions releaf-core/spec/lib/error_formatter_spec.rb
Expand Up @@ -165,15 +165,15 @@ def base_validation
end

it "adds error to errors" do
message = "error message"
message = ActiveModel::ErrorMessage.new("error message")
allow(message).to receive(:error_code).and_return('test error')
allow(message).to receive(:data).and_return(nil)

other_message = "invalid author"
other_message = ActiveModel::ErrorMessage.new("invalid author")
allow(other_message).to receive(:error_code).and_return('invalid')
allow(other_message).to receive(:data).and_return({foo: :bar})

jet_another_message = "jet another error message"
jet_another_message = ActiveModel::ErrorMessage.new("jet another error message")
allow(jet_another_message).to receive(:error_code).and_return('test error')
allow(jet_another_message).to receive(:data).and_return(nil)

Expand All @@ -193,7 +193,7 @@ def base_validation
end

it "localizes error messages" do
message = "error message"
message = ActiveModel::ErrorMessage.new("error message")
allow(message).to receive(:error_code).and_return('test error')
allow(message).to receive(:data).and_return(nil)

Expand Down
44 changes: 19 additions & 25 deletions releaf-core/spec/lib/template_field_type_mapper_spec.rb
@@ -1,6 +1,8 @@
require "spec_helper"

describe Releaf::TemplateFieldTypeMapper do
let(:object){ double("generic object") }

def file_field_error_message field_name, obj
"object doesn't respond to `%s` method. Did you forgot to add `file_accessor :%s` to `%s` model?" % [field_name, field_name, obj.class.name]
end
Expand All @@ -15,7 +17,7 @@ def image_field_error_message field_name, obj

describe ".use_i18n?" do
context "when object translates" do
context "when given attribute translatable" do
context "when given attribute translatable" do
it "returns true" do
expect(Releaf::TemplateFieldTypeMapper.use_i18n?(Book.new, :description)).to be true
end
Expand All @@ -38,24 +40,22 @@ def image_field_error_message field_name, obj
describe ".image_or_error" do
context "given field_name that doesn't end with _uid" do
it "raises ArgumentError" do
obj = Object.new
expect { subject.send(:image_or_error, 'image', obj) }.to raise_error ArgumentError
allow(object).to receive(:image)
expect { subject.send(:image_or_error, 'image', object) }.to raise_error ArgumentError
end
end

context 'given field_name is `image_uid`' do
context 'when object responds to `image` method' do
it "returns 'image'" do
obj = Object.new
allow(obj).to receive(:image)
expect( subject.send(:image_or_error, 'image_uid', obj) ).to eq 'image'
allow(object).to receive(:image)
expect( subject.send(:image_or_error, 'image_uid', object) ).to eq 'image'
end
end

context 'when object does not respond to `image` method' do
it 'raises RuntimeError' do
obj = Object.new
expect { subject.send(:image_or_error, 'image_uid', obj) }.to raise_error(RuntimeError, image_field_error_message('image', obj))
expect { subject.send(:image_or_error, 'image_uid', object) }.to raise_error(RuntimeError, image_field_error_message('image', object))
end
end
end
Expand All @@ -64,24 +64,22 @@ def image_field_error_message field_name, obj
describe ".file_or_error" do
context "given field_name that doesn't end with _uid" do
it "raises ArgumentError" do
obj = Object.new
expect { subject.send(:file_or_error, 'file', obj) }.to raise_error ArgumentError
allow(object).to receive(:file)
expect { subject.send(:file_or_error, 'file', object) }.to raise_error ArgumentError
end
end

context 'given field_name is `file_uid`' do
context 'when object responds to `file` method' do
it "returns 'file'" do
obj = Object.new
allow(obj).to receive(:file)
expect( subject.send(:file_or_error, 'file_uid', obj) ).to eq 'file'
allow(object).to receive(:file)
expect( subject.send(:file_or_error, 'file_uid', object) ).to eq 'file'
end
end

context 'when object does not respond to `file` method' do
it 'raises RuntimeError' do
obj = Object.new
expect { subject.send(:file_or_error, 'file_uid', obj) }.to raise_error(RuntimeError, file_field_error_message('file', obj))
expect { subject.send(:file_or_error, 'file_uid', object) }.to raise_error(RuntimeError, file_field_error_message('file', object))
end
end
end
Expand All @@ -92,17 +90,15 @@ def image_field_error_message field_name, obj
context "when attribute name is '#{field_name}'" do
context "when object responds to '#{field_name.sub(/_uid$/, '')}'" do
it "returns 'image'" do
obj = Object.new
allow(obj).to receive(field_name.sub(/_uid$/, '').to_sym)
expect( subject.send(:field_type_name_for_string, field_name, obj) ).to eq 'image'
allow(object).to receive(field_name.sub(/_uid$/, '').to_sym)
expect( subject.send(:field_type_name_for_string, field_name, object) ).to eq 'image'
end
end

context "when object doesn't respond to '#{field_name.sub(/_uid$/, '')}'" do
it "raises RuntimeError" do
test_field_name = field_name.sub(/_uid$/, '')
obj = Object.new
expect { subject.send(:field_type_name_for_string, field_name, obj) }.to raise_error(RuntimeError, image_field_error_message(test_field_name, obj))
expect { subject.send(:field_type_name_for_string, field_name, object) }.to raise_error(RuntimeError, image_field_error_message(test_field_name, object))
end
end
end
Expand All @@ -124,17 +120,15 @@ def image_field_error_message field_name, obj
context "when attribute name is '#{field_name}'" do
context "when object responds to '#{field_name.sub(/_uid$/, '')}'" do
it "returns 'file'" do
obj = Object.new
allow(obj).to receive(field_name.sub(/_uid$/, '').to_sym)
expect( subject.send(:field_type_name_for_string, field_name, obj) ).to eq 'file'
allow(object).to receive(field_name.sub(/_uid$/, '').to_sym)
expect( subject.send(:field_type_name_for_string, field_name, object) ).to eq 'file'
end
end

context "when object doesn't respond to '#{field_name.sub(/_uid$/, '')}'" do
it "raises RuntimeError" do
test_field_name = field_name.sub(/_uid$/, '')
obj = Object.new
expect { subject.send(:field_type_name_for_string, field_name, obj) }.to raise_error(RuntimeError, file_field_error_message(test_field_name, obj))
expect { subject.send(:field_type_name_for_string, field_name, object) }.to raise_error(RuntimeError, file_field_error_message(test_field_name, object))
end
end
end
Expand Down
Expand Up @@ -124,8 +124,13 @@ def file_attachment
describe "#import" do
context "when file uploaded" do
before do
file = fixture_file_upload(File.expand_path('../../fixtures/translations_import.xlsx', __dir__), 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', true)
allow(file).to receive(:tempfile).and_return(file)
file = fixture_file_upload(File.expand_path('../../fixtures/translations_import.xlsx', __dir__), 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
class << file
# The reader method is present in a real invocation,
# but missing from the fixture object for some reason (Rails 3.1.1)
attr_reader :tempfile
end

post :import, import_file: file
end

Expand Down
7 changes: 4 additions & 3 deletions spec/spec_helper.rb
Expand Up @@ -59,20 +59,21 @@ def write(message)
end

RSpec.configure do |config|
config.mock_with :rspec
config.use_transactional_fixtures = false
config.infer_base_class_for_anonymous_controllers = false
config.order = "random"
config.infer_spec_type_from_file_location!

config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end

config.color = true

if ENV['COVERAGE']
config.add_formatter(:progress)
end

config.add_formatter(:html, 'rspec.html')

config.include Helpers
config.include WaitSteps
config.include ExcelHelpers
Expand Down

0 comments on commit d6ed3b0

Please sign in to comment.