module Cell # Test your cells. # # This class is roughly equal to ActionController::TestCase, exposing the same semantics. It will try # to infer the tested cell name from the test name if you use declarative testing. You can also set it # with TestCase.tests. # # A declarative test would look like # # class SellOutTest < Cell::TestCase # tests ShoppingCartCell # # it "should be rendered nicely" do # invoke :order_button, :items => @fixture_items # # assert_select "button", "Order now!" # end # # You can also do stuff yourself, like # # it "should be rendered even nicer" do # html = render_cell(:shopping_cart, :order_button, , :items => @fixture_items) # assert_selector "button", "Order now!", html # end # # Or even unit test your cell: # # it "should provide #default_items" do # assert_equal [@item1, @item2], cell(:shopping_cart).default_items # end # # == Test helpers # # Basically, we got these new methods: # # +invoke+:: Renders the passed +state+ with your tested cell. You may pass options like in #render_cell. # +render_cell+:: As in your views. Will return the rendered view. # +assert_selector+:: Like #assert_select except that the last argument is the html markup you wanna test. # +cell+:: Gives you a cell instance for unit testing and stuff. class TestCase < ActiveSupport::TestCase module AssertSelect # Invokes assert_select for the last argument, the +content+ string. # # Example: # assert_selector "h1", "The latest and greatest!", "

The latest and greatest!

" # # would be true. def assert_selector(*args, &block) rails_assert_select(HTML::Document.new(args.pop).root, *args, &block) end # Invokes assert_select on the markup set by the last #invoke. # # Example: # invoke :latest # assert_select "h1", "The latest and greatest!" def assert_select(*args, &block) super(HTML::Document.new(last_invoke).root, *args, &block) end end module TestMethods def setup @controller = Class.new(ActionController::Base).new @request = ::ActionController::TestRequest.new @response = ::ActionController::TestResponse.new @controller.request = @request @controller.response = @response @controller.params = {} end # Use this for functional tests of your application cells. # # Example: # should "spit out a h1 title" do # html = render_cell(:news, :latest) # assert_selekt html, "h1", "The latest and greatest!" def render_cell(*args) @controller.render_cell(*args) end # Builds an instance of nameCell for unit testing. # Passes the optional block to cell.instance_eval. # # Example: # assert_equal "Banks kill planet!" cell(:news, :topic => :terror).latest_headline def cell(name, opts={}, &block) cell = ::Cell::Base.create_cell_for(@controller, name, opts) cell.instance_eval &block if block_given? cell end # Execute the passed +block+ in a real view context of +cell_class+. # Usually you'd test helpers here. # # Example: # # assert_equal("

Modularity rocks.

", in_view do content_tag(:h1, "Modularity rocks.")) def in_view(cell_class, &block) subject = cell(cell_class, :block => block) setup_test_states_in(subject) # add #in_view to subject cell. subject.render_state(:in_view) end protected def setup_test_states_in(cell) cell.instance_eval do def in_view render :inline => "<%= instance_exec(&block) %>", :locals => {:block => options[:block]} end end end end include TestMethods include ActionDispatch::Assertions::SelectorAssertions # imports "their" #assert_select. alias_method :rails_assert_select, :assert_select # i hate that. include AssertSelect extend ActionController::TestCase::Behavior::ClassMethods class_attribute :_controller_class attr_reader :last_invoke def invoke(state, *args) @last_invoke = self.class.controller_class.new(@controller, *args).render_state(state) end end end