File: templates_test.rb

package info (click to toggle)
ruby-sinatra 1.3.2-2
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 1,200 kB
  • sloc: ruby: 7,675; makefile: 5
file content (298 lines) | stat: -rw-r--r-- 8,440 bytes parent folder | download
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
# encoding: UTF-8
require File.expand_path('../helper', __FILE__)
File.delete(File.dirname(__FILE__) + '/views/layout.test') rescue nil

class TestTemplate < Tilt::Template
  def prepare
  end

  def evaluate(scope, locals={}, &block)
    inner = block ? block.call : ''
    data + inner
  end

  Tilt.register 'test', self
end

class TemplatesTest < Test::Unit::TestCase
  def render_app(base=Sinatra::Base, options = {}, &block)
    base, options = Sinatra::Base, base if base.is_a? Hash
    mock_app(base) {
      set :views, File.dirname(__FILE__) + '/views'
      set options
      get '/', &block
      template(:layout3) { "Layout 3!\n" }
    }
    get '/'
  end

  def with_default_layout
    layout = File.dirname(__FILE__) + '/views/layout.test'
    File.open(layout, 'wb') { |io| io.write "Layout!\n" }
    yield
  ensure
    File.unlink(layout) rescue nil
  end

  it 'renders String templates directly' do
    render_app { render :test, 'Hello World' }
    assert ok?
    assert_equal 'Hello World', body
  end

  it 'renders Proc templates using the call result' do
    render_app { render :test, Proc.new {'Hello World'} }
    assert ok?
    assert_equal 'Hello World', body
  end

  it 'looks up Symbol templates in views directory' do
    render_app { render :test, :hello }
    assert ok?
    assert_equal "Hello World!\n", body
  end

  it 'uses the default layout template if not explicitly overridden' do
    with_default_layout do
      render_app { render :test, :hello }
      assert ok?
      assert_equal "Layout!\nHello World!\n", body
    end
  end

  it 'uses the default layout template if not really overriden' do
    with_default_layout do
      render_app { render :test, :hello, :layout => true }
      assert ok?
      assert_equal "Layout!\nHello World!\n", body
    end
  end

  it 'uses the layout template specified' do
    render_app { render :test, :hello, :layout => :layout2 }
    assert ok?
    assert_equal "Layout 2!\nHello World!\n", body
  end

  it 'uses layout templates defined with the #template method' do
    render_app { render :test, :hello, :layout => :layout3 }
    assert ok?
    assert_equal "Layout 3!\nHello World!\n", body
  end

  it 'avoids wrapping layouts around nested templates' do
    render_app { render :str, :nested, :layout => :layout2 }
    assert ok?
    assert_equal "<h1>String Layout!</h1>\n<content><h1>Hello From String</h1></content>", body
  end

  it 'allows explicitly wrapping layouts around nested templates' do
    render_app { render :str, :explicitly_nested, :layout => :layout2 }
    assert ok?
    assert_equal "<h1>String Layout!</h1>\n<content><h1>String Layout!</h1>\n<h1>Hello From String</h1></content>", body
  end

  it 'two independent render calls do not disable layouts' do
    render_app do
      render :str, :explicitly_nested, :layout => :layout2
      render :str, :nested, :layout => :layout2
    end
    assert ok?
    assert_equal "<h1>String Layout!</h1>\n<content><h1>Hello From String</h1></content>", body
  end

  it 'is possible to use partials in layouts' do
    render_app do
      settings.layout { "<%= erb 'foo' %><%= yield %>" }
      erb 'bar'
    end
    assert ok?
    assert_equal "foobar", body
  end

  it 'loads templates from source file' do
    mock_app { enable :inline_templates }
    assert_equal "this is foo\n\n", @app.templates[:foo][0]
    assert_equal "X\n= yield\nX\n", @app.templates[:layout][0]
  end

  it 'ignores spaces after names of inline templates' do
    mock_app { enable :inline_templates }
    assert_equal "There's a space after 'bar'!\n\n", @app.templates[:bar][0]
    assert_equal "this is not foo\n\n", @app.templates[:"foo bar"][0]
  end

  it 'loads templates from given source file' do
    mock_app { set :inline_templates, __FILE__ }
    assert_equal "this is foo\n\n", @app.templates[:foo][0]
  end

  test 'inline_templates ignores IO errors' do
    assert_nothing_raised {
      mock_app {
        set :inline_templates, '/foo/bar'
      }
    }

    assert @app.templates.empty?
  end

  it 'allows unicode in inline templates' do
    mock_app { set :inline_templates, __FILE__ }
    assert_equal "Den som tror at hemma det är där man bor har aldrig vart hos mig.\n\n",
      @app.templates[:umlaut][0]
  end

  it 'loads templates from specified views directory' do
    render_app { render :test, :hello, :views => settings.views + '/foo' }

    assert_equal "from another views directory\n", body
  end

  it 'passes locals to the layout' do
    mock_app {
      template :my_layout do
        'Hello <%= name %>!<%= yield %>'
      end

      get '/' do
        erb '<p>content</p>', { :layout => :my_layout }, { :name => 'Mike'}
      end
    }

    get '/'
    assert ok?
    assert_equal 'Hello Mike!<p>content</p>', body
  end

  it 'loads templates defined in subclasses' do
    base = Class.new(Sinatra::Base)
    base.template(:foo) { 'bar' }
    render_app(base) { render :test, :foo }
    assert ok?
    assert_equal 'bar', body
  end

  it 'allows setting default content type per template engine' do
    render_app(:str => { :content_type => :txt }) { render :str, 'foo' }
    assert_equal 'text/plain;charset=utf-8', response['Content-Type']
  end

  it 'setting default content type does not affect other template engines' do
    render_app(:str => { :content_type => :txt }) { render :test, 'foo' }
    assert_equal 'text/html;charset=utf-8', response['Content-Type']
  end

  it 'setting default content type per template engine does not override content_type' do
    render_app :str => { :content_type => :txt } do
      content_type :html
      render :str, 'foo'
    end
    assert_equal 'text/html;charset=utf-8', response['Content-Type']
  end

  it 'uses templates in superclasses before subclasses' do
    base = Class.new(Sinatra::Base)
    base.template(:foo) { 'template in superclass' }
    assert_equal 'template in superclass', base.templates[:foo].first.call

    mock_app(base) {
      set :views, File.dirname(__FILE__) + '/views'
      template(:foo) { 'template in subclass' }
      get('/') { render :test, :foo }
    }
    assert_equal 'template in subclass', @app.templates[:foo].first.call

    get '/'
    assert ok?
    assert_equal 'template in subclass', body
  end

  it "is possible to use a different engine for the layout than for the template itself explicitely" do
    render_app do
      settings.template(:layout) { 'Hello <%= yield %>!' }
      render :str, "<%= 'World' %>", :layout_engine => :erb
    end
    assert_equal "Hello <%= 'World' %>!", body
  end

  it "is possible to use a different engine for the layout than for the template itself globally" do
    render_app :str => { :layout_engine => :erb } do
      settings.template(:layout) { 'Hello <%= yield %>!' }
      render :str, "<%= 'World' %>"
    end
    assert_equal "Hello <%= 'World' %>!", body
  end

  it "does not leak the content type to the template" do
    render_app :str => { :layout_engine => :erb } do
      settings.template(:layout) { 'Hello <%= yield %>!' }
      render :str, "<%= 'World' %>", :content_type => :txt
    end
    assert_equal "text/html;charset=utf-8", headers['Content-Type']
  end

  it "is possible to register another template" do
    Tilt.register "html.erb", Tilt[:erb]
    render_app { render :erb, :calc }
    assert_equal '2', body
  end

  it "passes scope to the template" do
    mock_app do
      template :scoped do
        'Hello <%= foo %>'
      end

      get '/' do
        some_scope = Object.new
        def some_scope.foo() 'World!' end
        erb :scoped, :scope => some_scope
      end
    end

    get '/'
    assert ok?
    assert_equal 'Hello World!', body
  end

  it "is possible to use custom logic for finding template files" do
    mock_app do
      set :views, ["a", "b"].map { |d| File.dirname(__FILE__) + '/views/' + d }
      def find_template(views, name, engine, &block)
        Array(views).each { |v| super(v, name, engine, &block) }
      end

      get('/:name') do
        render :str, params[:name].to_sym
      end
    end

    get '/in_a'
    assert_body 'Gimme an A!'

    get '/in_b'
    assert_body 'Gimme a B!'
  end
end

# __END__ : this is not the real end of the script.

__END__

@@ foo
this is foo

@@ bar 
There's a space after 'bar'!

@@ foo bar
this is not foo

@@ umlaut
Den som tror at hemma det är där man bor har aldrig vart hos mig.

@@ layout
X
= yield
X