sinatra 1.3.0.c → 1.3.0.d

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sinatra might be problematic. Click here for more details.

@@ -584,6 +584,19 @@ Thin - это более производительный и функциона
584
584
 
585
585
  Отобразит <tt>./views/index.slim</tt>.
586
586
 
587
+ === Creole шаблоны
588
+
589
+ <tt>creole</tt> gem/библиотека необходима для рендеринга creole шаблонов:
590
+
591
+ # Вам нужно будет подключить creole в приложении
592
+ require 'creole'
593
+
594
+ get '/' do
595
+ creole :index
596
+ end
597
+
598
+ Отобразит <tt>./views/index.creole</tt>.
599
+
587
600
  === CoffeeScript шаблоны
588
601
 
589
602
  Вам понадобится <tt>coffee-script</tt> gem/библиотека и что-то <b>одно</b> из следующего списка,
@@ -858,8 +871,8 @@ Thin - это более производительный и функциона
858
871
  вызова другого обработчика маршрута. В таком случае просто используйте +call+:
859
872
 
860
873
  get '/foo' do
861
- status, headers, body = call request.env.merge("PATH_INFO" => '/bar')
862
- [status, body.upcase]
874
+ status, headers, body = call env.merge("PATH_INFO" => '/bar')
875
+ [status, headers, body.map(&:upcase)]
863
876
  end
864
877
 
865
878
  get '/bar' do
@@ -1349,7 +1362,7 @@ Thin - это более производительный и функциона
1349
1362
  Частные ошибки:
1350
1363
 
1351
1364
  error MyCustomError do
1352
- 'So what happened was...' + request.env['sinatra.error'].message
1365
+ 'So what happened was...' + env['sinatra.error'].message
1353
1366
  end
1354
1367
 
1355
1368
  Тогда, если это произошло:
@@ -582,6 +582,19 @@ Rack body对象或者HTTP状态码:
582
582
 
583
583
  渲染 <tt>./views/index.slim</tt>。
584
584
 
585
+ === Creole 模板
586
+
587
+ 需要引入 <tt>creole</tt> gem/library 来渲染 Creole 模板:
588
+
589
+ # 需要在你的应用中引入 creole
590
+ require 'creole'
591
+
592
+ get '/' do
593
+ creole :index
594
+ end
595
+
596
+ 渲染 <tt>./views/index.creole</tt>。
597
+
585
598
  === CoffeeScript 模板
586
599
 
587
600
  需要引入 <tt>coffee-script</tt> gem/library 并至少满足下面条件一项
@@ -843,8 +856,8 @@ Session被用来在请求之间保持状态。如果被激活,每一个用户
843
856
  。简单的使用 +call+ 可以做到这一点:
844
857
 
845
858
  get '/foo' do
846
- status, headers, body = call request.env.merge("PATH_INFO" => '/bar')
847
- [status, body.upcase]
859
+ status, headers, body = call env.merge("PATH_INFO" => '/bar')
860
+ [status, headers, body.map(&:upcase)]
848
861
  end
849
862
 
850
863
  get '/bar' do
@@ -1314,7 +1327,7 @@ Sinatra会自动处理range请求。
1314
1327
  自定义错误:
1315
1328
 
1316
1329
  error MyCustomError do
1317
- 'So what happened was...' + request.env['sinatra.error'].message
1330
+ 'So what happened was...' + env['sinatra.error'].message
1318
1331
  end
1319
1332
 
1320
1333
  那么,当这个发生的时候:
@@ -6,15 +6,11 @@ require 'sinatra/showexceptions'
6
6
  require 'tilt'
7
7
 
8
8
  module Sinatra
9
- VERSION = '1.3.0.c'
9
+ VERSION = '1.3.0.d'
10
10
 
11
11
  # The request object. See Rack::Request for more info:
12
12
  # http://rack.rubyforge.org/doc/classes/Rack/Request.html
13
13
  class Request < Rack::Request
14
- def self.new(env)
15
- env['sinatra.request'] ||= super
16
- end
17
-
18
14
  # Returns an array of acceptable media types for the response
19
15
  def accept
20
16
  @env['sinatra.accept'] ||= begin
@@ -366,7 +362,7 @@ module Sinatra
366
362
  time = time_for time
367
363
  response['Last-Modified'] = time.httpdate
368
364
  # compare based on seconds since epoch
369
- halt 304 if Time.httpdate(request.env['HTTP_IF_MODIFIED_SINCE']).to_i >= time.to_i
365
+ halt 304 if Time.httpdate(env['HTTP_IF_MODIFIED_SINCE']).to_i >= time.to_i
370
366
  rescue ArgumentError
371
367
  end
372
368
 
@@ -455,6 +451,8 @@ module Sinatra
455
451
  end
456
452
 
457
453
  def erubis(template, options={}, locals={})
454
+ warn "Sinatra::Templates#erubis is deprecated and will be removed, use #erb instead.\n" \
455
+ "If you have Erubis installed, it will be used automatically.\n\tfrom #{caller.first}"
458
456
  render :erubis, template, options, locals
459
457
  end
460
458
 
@@ -520,12 +518,16 @@ module Sinatra
520
518
  render :slim, template, options, locals
521
519
  end
522
520
 
521
+ def creole(template, options={}, locals={})
522
+ render :creole, template, options, locals
523
+ end
524
+
523
525
  # Calls the given block for every possible template file in views,
524
526
  # named name.ext, where ext is registered on engine.
525
527
  def find_template(views, name, engine)
526
528
  yield ::File.join(views, "#{name}.#{@preferred_extension}")
527
529
  Tilt.mappings.each do |ext, engines|
528
- next unless ext != @preferred_extension and Array(engines).include? engine
530
+ next unless ext != @preferred_extension and engines.include? engine
529
531
  yield ::File.join(views, "#{name}.#{ext}")
530
532
  end
531
533
  end
@@ -650,17 +652,7 @@ module Sinatra
650
652
  end
651
653
  end
652
654
 
653
- status, header, body = @response.finish
654
-
655
- # Never produce a body on HEAD requests. Do retain the Content-Length
656
- # unless it's "0", in which case we assume it was calculated erroneously
657
- # for a manual HEAD response and remove it entirely.
658
- if @env['REQUEST_METHOD'] == 'HEAD'
659
- body = []
660
- header.delete('Content-Length') if header['Content-Length'] == '0'
661
- end
662
-
663
- [status, header, body]
655
+ @response.finish
664
656
  end
665
657
 
666
658
  # Access settings defined with Base.set.
@@ -696,7 +688,7 @@ module Sinatra
696
688
  # Forward the request to the downstream app -- middleware only.
697
689
  def forward
698
690
  fail "downstream app not set" unless @app.respond_to? :call
699
- status, headers, body = @app.call(@request.env)
691
+ status, headers, body = @app.call env
700
692
  @response.status = status
701
693
  @response.body = body
702
694
  @response.headers.merge! headers
@@ -948,14 +940,15 @@ module Sinatra
948
940
 
949
941
  # Sets an option to the given value. If the value is a proc,
950
942
  # the proc will be called every time the option is accessed.
951
- def set(option, value=self, &block)
952
- raise ArgumentError if block && value != self
943
+ def set(option, value = (not_set = true), &block)
944
+ raise ArgumentError if block and !not_set
953
945
  value = block if block
954
946
  if value.kind_of?(Proc)
955
947
  metadef(option, &value)
956
948
  metadef("#{option}?") { !!__send__(option) }
957
949
  metadef("#{option}=") { |val| metadef(option, &Proc.new{val}) }
958
- elsif value == self && option.respond_to?(:each)
950
+ elsif not_set
951
+ raise ArgumentError unless option.respond_to?(:each)
959
952
  option.each { |k,v| set(k, v) }
960
953
  elsif respond_to?("#{option}=")
961
954
  __send__ "#{option}=", value
@@ -1269,6 +1262,7 @@ module Sinatra
1269
1262
  builder = Rack::Builder.new
1270
1263
  builder.use Rack::MethodOverride if method_override?
1271
1264
  builder.use ShowExceptions if show_exceptions?
1265
+ builder.use Rack::Head
1272
1266
  setup_logging builder
1273
1267
  setup_sessions builder
1274
1268
  middleware.each { |c,a,b| builder.use(c, *a, &b) }
@@ -1296,7 +1290,8 @@ module Sinatra
1296
1290
 
1297
1291
  def setup_sessions(builder)
1298
1292
  return unless sessions?
1299
- options = { :secret => session_secret }
1293
+ options = {}
1294
+ options[:secret] = session_secret if session_secret?
1300
1295
  options.merge! sessions.to_hash if sessions.respond_to? :to_hash
1301
1296
  builder.use Rack::Session::Cookie, options
1302
1297
  end
@@ -1451,7 +1446,7 @@ module Sinatra
1451
1446
  </style>
1452
1447
  </head>
1453
1448
  <body>
1454
- <h2>Sinatra doesn't know this ditty.</h2>
1449
+ <h2>Sinatra doesn&rsquo;t know this ditty.</h2>
1455
1450
  <img src='#{uri "/__sinatra__/404.png"}'>
1456
1451
  <div id="c">
1457
1452
  Try this:
@@ -1475,6 +1470,7 @@ module Sinatra
1475
1470
  set :logging, Proc.new { ! test? }
1476
1471
  set :method_override, true
1477
1472
  set :run, Proc.new { ! test? }
1473
+ set :session_secret, Proc.new { super() unless development? }
1478
1474
 
1479
1475
  def self.register(*extensions, &block) #:nodoc:
1480
1476
  added_methods = extensions.map {|m| m.public_instance_methods }.flatten
@@ -1489,12 +1485,11 @@ module Sinatra
1489
1485
  module Delegator #:nodoc:
1490
1486
  def self.delegate(*methods)
1491
1487
  methods.each do |method_name|
1492
- eval <<-RUBY, binding, '(__DELEGATE__)', 1
1493
- def #{method_name}(*args, &b)
1494
- ::Sinatra::Delegator.target.send(#{method_name.inspect}, *args, &b)
1495
- end
1496
- private #{method_name.inspect}
1497
- RUBY
1488
+ define_method(method_name) do |*args, &block|
1489
+ return super(*args, &block) if respond_to? method_name
1490
+ Delegator.target.send(method_name, *args, &block)
1491
+ end
1492
+ private method_name
1498
1493
  end
1499
1494
  end
1500
1495
 
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
3
3
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
4
 
5
5
  s.name = 'sinatra'
6
- s.version = '1.3.0.c'
7
- s.date = '2011-04-13'
6
+ s.version = '1.3.0.d'
7
+ s.date = '2011-04-30'
8
8
 
9
9
  s.description = "Classy web-development dressed in a DSL"
10
10
  s.summary = "Classy web-development dressed in a DSL"
@@ -41,10 +41,10 @@ Gem::Specification.new do |s|
41
41
  test/builder_test.rb
42
42
  test/coffee_test.rb
43
43
  test/contest.rb
44
+ test/creole_test.rb
44
45
  test/delegator_test.rb
45
46
  test/encoding_test.rb
46
47
  test/erb_test.rb
47
- test/erubis_test.rb
48
48
  test/extensions_test.rb
49
49
  test/filter_test.rb
50
50
  test/haml_test.rb
@@ -80,15 +80,14 @@ Gem::Specification.new do |s|
80
80
  test/views/calc.html.erb
81
81
  test/views/error.builder
82
82
  test/views/error.erb
83
- test/views/error.erubis
84
83
  test/views/error.haml
85
84
  test/views/error.sass
86
85
  test/views/explicitly_nested.str
87
86
  test/views/foo/hello.test
88
87
  test/views/hello.builder
89
88
  test/views/hello.coffee
89
+ test/views/hello.creole
90
90
  test/views/hello.erb
91
- test/views/hello.erubis
92
91
  test/views/hello.haml
93
92
  test/views/hello.less
94
93
  test/views/hello.liquid
@@ -105,7 +104,6 @@ Gem::Specification.new do |s|
105
104
  test/views/hello.textile
106
105
  test/views/layout2.builder
107
106
  test/views/layout2.erb
108
- test/views/layout2.erubis
109
107
  test/views/layout2.haml
110
108
  test/views/layout2.liquid
111
109
  test/views/layout2.mab
@@ -123,7 +121,7 @@ Gem::Specification.new do |s|
123
121
 
124
122
  s.extra_rdoc_files = %w[README.rdoc README.de.rdoc README.jp.rdoc README.fr.rdoc README.es.rdoc README.hu.rdoc README.zh.rdoc LICENSE]
125
123
  s.add_dependency 'rack', '~> 1.2'
126
- s.add_dependency 'tilt', '~> 1.2', '>= 1.2.2'
124
+ s.add_dependency 'tilt', '~> 1.3'
127
125
  s.add_development_dependency 'shotgun', '~> 0.6'
128
126
 
129
127
  s.homepage = "http://sinatra.rubyforge.org"
@@ -0,0 +1,65 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ begin
4
+ require 'creole'
5
+
6
+ class CreoleTest < Test::Unit::TestCase
7
+ def creole_app(&block)
8
+ mock_app do
9
+ set :views, File.dirname(__FILE__) + '/views'
10
+ get '/', &block
11
+ end
12
+ get '/'
13
+ end
14
+
15
+ it 'renders inline creole strings' do
16
+ creole_app { creole '= Hiya' }
17
+ assert ok?
18
+ assert_body "<h1>Hiya</h1>"
19
+ end
20
+
21
+ it 'renders .creole files in views path' do
22
+ creole_app { creole :hello }
23
+ assert ok?
24
+ assert_body "<h1>Hello From Creole</h1>"
25
+ end
26
+
27
+ it "raises error if template not found" do
28
+ mock_app { get('/') { creole :no_such_template } }
29
+ assert_raise(Errno::ENOENT) { get('/') }
30
+ end
31
+
32
+ it "renders with inline layouts" do
33
+ mock_app do
34
+ layout { 'THIS. IS. #{yield.upcase}!' }
35
+ get('/') { creole 'Sparta', :layout_engine => :str }
36
+ end
37
+ get '/'
38
+ assert ok?
39
+ assert_like 'THIS. IS. <P>SPARTA</P>!', body
40
+ end
41
+
42
+ it "renders with file layouts" do
43
+ creole_app { creole 'Hello World', :layout => :layout2, :layout_engine => :erb }
44
+ assert ok?
45
+ assert_body "ERB Layout!\n<p>Hello World</p>"
46
+ end
47
+
48
+ it "can be used in a nested fashion for partials and whatnot" do
49
+ mock_app do
50
+ template(:inner) { "hi" }
51
+ template(:outer) { "<outer><%= creole :inner %></outer>" }
52
+ get '/' do
53
+ erb :outer
54
+ end
55
+ end
56
+
57
+ get '/'
58
+ assert ok?
59
+ assert_like '<outer><p>hi</p></outer>', body
60
+ end
61
+ end
62
+
63
+ rescue LoadError
64
+ warn "#{$!.to_s}: skipping creole tests"
65
+ end
@@ -100,13 +100,39 @@ class DelegatorTest < Test::Unit::TestCase
100
100
  assert_equal app.last_call, ["helpers", mixin.to_s ]
101
101
  end
102
102
 
103
-
104
103
  it "registers helpers with the delegation target" do
105
104
  app, mixin = mirror, Module.new
106
105
  Sinatra.use mixin
107
106
  assert_equal app.last_call, ["use", mixin.to_s ]
108
107
  end
109
108
 
109
+ it "should work with method_missing proxies for options" do
110
+ mixin = Module.new do
111
+ def respond_to?(method, *)
112
+ method.to_sym == :options or super
113
+ end
114
+
115
+ def method_missing(method, *args, &block)
116
+ return super unless method.to_sym == :options
117
+ {:some => :option}
118
+ end
119
+ end
120
+
121
+ value = nil
122
+ mirror do
123
+ extend mixin
124
+ value = options
125
+ end
126
+
127
+ assert_equal({:some => :option}, value)
128
+ end
129
+
130
+ it "delegates crazy method names" do
131
+ Sinatra::Delegator.delegate "foo:bar:"
132
+ method = mirror { send "foo:bar:" }.last_call.first
133
+ assert_equal "foo:bar:", method
134
+ end
135
+
110
136
  delegates 'get'
111
137
  delegates 'patch'
112
138
  delegates 'put'
@@ -1,6 +1,15 @@
1
1
  require File.dirname(__FILE__) + '/helper'
2
2
 
3
3
  class ERBTest < Test::Unit::TestCase
4
+ def engine
5
+ Tilt::ERBTemplate
6
+ end
7
+
8
+ def setup
9
+ Tilt.prefer engine, :erb
10
+ super
11
+ end
12
+
4
13
  def erb_app(&block)
5
14
  mock_app {
6
15
  set :views, File.dirname(__FILE__) + '/views'
@@ -9,6 +18,10 @@ class ERBTest < Test::Unit::TestCase
9
18
  get '/'
10
19
  end
11
20
 
21
+ it 'uses the correct engine' do
22
+ assert_equal engine, Tilt[:erb]
23
+ end
24
+
12
25
  it 'renders inline ERB strings' do
13
26
  erb_app { erb '<%= 1 + 1 %>' }
14
27
  assert ok?
@@ -45,7 +58,7 @@ class ERBTest < Test::Unit::TestCase
45
58
  erb 'Hello World', :layout => :layout2
46
59
  }
47
60
  assert ok?
48
- assert_equal "ERB Layout!\nHello World\n", body
61
+ assert_body "ERB Layout!\nHello World"
49
62
  end
50
63
 
51
64
  it "renders erb with blocks" do
@@ -79,3 +92,13 @@ class ERBTest < Test::Unit::TestCase
79
92
  assert_equal '<outer><inner>hi</inner></outer>', body
80
93
  end
81
94
  end
95
+
96
+
97
+ begin
98
+ require 'erubis'
99
+ class ErubisTest < ERBTest
100
+ def engine; Tilt::ErubisTemplate end
101
+ end
102
+ rescue LoadError
103
+ warn "#{$!.to_s}: skipping erubis tests"
104
+ end
@@ -65,6 +65,11 @@ class Test::Unit::TestCase
65
65
  assert_equal value.lstrip.gsub(/\s*\n\s*/, ""), body.lstrip.gsub(/\s*\n\s*/, "")
66
66
  end
67
67
 
68
+ def assert_like(a,b)
69
+ pattern = /\s*\n\s*| id=['"][^"']*["']/
70
+ assert_equal a.strip.gsub(pattern, ""), b.strip.gsub(pattern, "")
71
+ end
72
+
68
73
  def assert_include(str, substr)
69
74
  assert str.include?(substr), "expected #{str.inspect} to include #{substr.inspect}"
70
75
  end
@@ -76,6 +81,8 @@ class Test::Unit::TestCase
76
81
  else
77
82
  super
78
83
  end
84
+ rescue Rack::Test::Error
85
+ super
79
86
  end
80
87
 
81
88
  # Also check response since we delegate there.