/
test_case.rb
135 lines (121 loc) · 4.43 KB
/
test_case.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
require "active_support/test_case"
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!", "<h1>The latest and greatest!</h1>"
#
# 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 <tt>name</tt>Cell for unit testing.
# Passes the optional block to <tt>cell.instance_eval</tt>.
#
# 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
end
include TestMethods
include ActionController::Assertions::SelectorAssertions # imports "their" #assert_select.
alias_method :rails_assert_select, :assert_select # i hate that.
include AssertSelect
attr_reader :last_invoke
def invoke(state, *args)
@last_invoke = self.class.controller_class.new(@controller, *args).render_state(state)
end
class << self
# Sets the controller class name. Useful if the name can't be inferred from test class.
# Expects +controller_class+ as a constant. Example: <tt>tests WidgetController</tt>.
def tests(controller_class)
self.controller_class = controller_class
end
def controller_class=(new_class)
write_inheritable_attribute(:controller_class, new_class)
end
def controller_class
if current_controller_class = read_inheritable_attribute(:controller_class)
current_controller_class
else
self.controller_class = determine_default_controller_class(name)
end
end
def determine_default_controller_class(name)
name.sub(/Test$/, '').constantize
rescue NameError
nil
end
end
end
end