-
-
Notifications
You must be signed in to change notification settings - Fork 909
/
render_with_layout_matcher.rb
149 lines (136 loc) · 3.81 KB
/
render_with_layout_matcher.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
module Shoulda
module Matchers
module ActionController
# The `render_with_layout` matcher asserts that an action is rendered with
# a particular layout.
#
# class PostsController < ApplicationController
# def show
# render layout: 'posts'
# end
# end
#
# # RSpec
# RSpec.describe PostsController, type: :controller do
# describe 'GET #show' do
# before { get :show }
#
# it { should render_with_layout('posts') }
# end
# end
#
# # Minitest (Shoulda)
# class PostsControllerTest < ActionController::TestCase
# context 'GET #show' do
# setup { get :show }
#
# should render_with_layout('posts')
# end
# end
#
# It can also be used to assert that the action is not rendered with a
# layout at all:
#
# class PostsController < ApplicationController
# def sidebar
# render layout: false
# end
# end
#
# # RSpec
# RSpec.describe PostsController, type: :controller do
# describe 'GET #sidebar' do
# before { get :sidebar }
#
# it { should_not render_with_layout }
# end
# end
#
# # Minitest (Shoulda)
# class PostsControllerTest < ActionController::TestCase
# context 'GET #sidebar' do
# setup { get :sidebar }
#
# should_not render_with_layout
# end
# end
#
# @return [RenderWithLayoutMatcher]
#
def render_with_layout(expected_layout = nil)
RenderWithLayoutMatcher.new(expected_layout).in_context(self)
end
# @private
class RenderWithLayoutMatcher
def initialize(expected_layout)
@expected_layout =
if expected_layout
expected_layout.to_s
else
nil
end
@controller = nil
end
# Used to provide access to layouts recorded by
# ActionController::TemplateAssertions in Rails 3
def in_context(context)
@context = context
self
end
def matches?(controller)
@controller = controller
rendered_with_layout? && rendered_with_expected_layout?
end
def failure_message
"Expected #{expectation}, but #{result}"
end
def failure_message_when_negated
"Did not expect #{expectation}, but #{result}"
end
def description
description = 'render with '
description <<
if @expected_layout.nil?
'a layout'
else
"the #{@expected_layout.inspect} layout"
end
description
end
private
def rendered_with_layout?
!rendered_layouts.empty?
end
def rendered_with_expected_layout?
if @expected_layout.nil?
true
else
rendered_layouts.include?(@expected_layout)
end
end
def rendered_layouts
recorded_layouts.keys.compact.map { |layout|
layout.sub(%r{^layouts/}, '')
}
end
def recorded_layouts
if @context
@context.instance_variable_get('@_layouts')
else
{}
end
end
def expectation
"to #{description}"
end
def result
if rendered_with_layout?
"rendered with #{rendered_layouts.map(&:inspect).join(', ')}"
else
'rendered without a layout'
end
end
end
end
end
end