require 'spec_helper' require 'btspm/presenters' class Test attr_accessor :name def initialize(name) @name = name end end class TestsPresenter include Btspm::Presenters::Presentable class Scalar < Btspm::Presenters::ScalarPresenter def access_view_context h.test_method end def access_delegated_object name end def additional_local_param @additional_param end end class Enum < Btspm::Presenters::EnumPresenter end end class FakeViewContext def test_method :accessible end end RSpec.describe TestsPresenter do describe '#TestsPresenter' do it 'returns a scalar presenter for non-enumerables' do presenter = TestsPresenter.present(Test.new('one'), FakeViewContext.new) expect(presenter).to be_a(TestsPresenter::Scalar) end it 'returns a enum presenter for enumerables' do presenter = TestsPresenter.present([Test.new('one')], FakeViewContext.new) expect(presenter).to be_a(TestsPresenter::Enum) end it 'enum presenter #each wraps elements in scalar presenter' do presenter = TestsPresenter.present([Test.new('one')], FakeViewContext.new) expect(presenter.first).to be_a(TestsPresenter::Scalar) end it 'knows ActiveRecord::Relations are enumerables too.' do presenter = TestsPresenter.present(User.where('1 = 1'), FakeViewContext.new) expect(presenter).to be_a(TestsPresenter::Enum) end it 'allows access to the view context' do presenter = TestsPresenter.present(Test.new('one'), FakeViewContext.new) expect(presenter.access_view_context).to eq(:accessible) end it 'allows access to delegated object' do presenter = TestsPresenter.present(Test.new('one'), FakeViewContext.new) expect(presenter.name).to eq('one') end it 'can return delegated object' do test = Test.new('one') presenter = TestsPresenter.present(test, FakeViewContext.new) expect(presenter.data_object).to eql(test) end it 'allows access to additional local parameters passed into present' do locals = {additional_param: 'two'} presenter = TestsPresenter.present(Test.new('one'), FakeViewContext.new, locals) expect(presenter.additional_local_param).to eql(locals[:additional_param]) end it 'allows access to additional local parameters for each object in an enumerable' do locals = {additional_param: 'three'} presenters = TestsPresenter.present([Test.new('one'), Test.new('two')], FakeViewContext.new, locals) presenters.each do |presenter| expect(presenter.additional_local_param).to eql(locals[:additional_param]) end end end end class UsersPresenter include Btspm::Presenters::Presentable class Scalar < Btspm::Presenters::ScalarPresenter end class Enum < Btspm::Presenters::EnumPresenter end end describe 'present helper method' do it 'is exposed to Rails.' do ActionController::Base.instance_methods.include?(:present) ActionView::Base.instance_methods.include?(:present) end it 'uses the right view context' do controller = ActionController::Base.new view = controller.view_context presenter = controller.present(Test.new('one')) expect(presenter.h).to be_a(ActionView::Base) presenter = view.present(Test.new('one')) expect(presenter.h).to be_a(ActionView::Base) end it 'infers the correct presenter' do controller = ActionController::Base.new presenter = controller.present(Test.new('one')) expect(presenter).to be_a(TestsPresenter::Scalar) presenter = controller.present([Test.new('one')]) expect(presenter).to be_a(TestsPresenter::Enum) presenter = controller.present(User.new) expect(presenter).to be_a(UsersPresenter::Scalar) presenter = controller.present(User.where('1 = 1')) expect(presenter).to be_a(UsersPresenter::Enum) end it 'can override default presenter' do controller = ActionController::Base.new presenter = controller.present(Test.new('one'), UsersPresenter) expect(presenter).to be_a(UsersPresenter::Scalar) end end