sinatra 1.2.6 → 1.2.7

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.

@@ -1014,7 +1014,7 @@ DSL верхнего уровня загрязняет пространство
1014
1014
  Rack-совместимый сервер приложений.
1015
1015
 
1016
1016
  # config.ru
1017
- require 'my_app'
1017
+ require './my_app'
1018
1018
  run MyApp
1019
1019
 
1020
1020
  Запускаем:
@@ -1034,7 +1034,7 @@ Rack-совместимый сервер приложений.
1034
1034
 
1035
1035
  И соответствующий <tt>config.ru</tt>:
1036
1036
 
1037
- require 'app'
1037
+ require './app'
1038
1038
  run Sinatra::Application
1039
1039
 
1040
1040
  === Когда использовать config.ru?
@@ -884,7 +884,7 @@ Session被用来在请求之间保持状态。如果被激活,每一个用户
884
884
  get '/foo' do
885
885
  status 418
886
886
  headers \
887
- "Allow" => "BREW, POST, GET, PROPFIND, WHEN"
887
+ "Allow" => "BREW, POST, GET, PROPFIND, WHEN",
888
888
  "Refresh" => "Refresh: 20; http://www.ietf.org/rfc/rfc2324.txt"
889
889
  body "I'm a tea pot!"
890
890
  end
@@ -948,7 +948,7 @@ Sinatra并不理解。使用 +mime_type+ 通过文件扩展名来注册它们:
948
948
 
949
949
  或者使用session:
950
950
 
951
- enable :session
951
+ enable :sessions
952
952
 
953
953
  get '/foo' do
954
954
  session[:secret] = 'foo'
@@ -1500,7 +1500,7 @@ Sinatra::Base子类可用的方法实际上就是通过顶层 DSL
1500
1500
  或者使用一个 <tt>config.ru</tt>,允许你使用任何Rack处理器:
1501
1501
 
1502
1502
  # config.ru
1503
- require 'my_app'
1503
+ require './my_app'
1504
1504
  run MyApp
1505
1505
 
1506
1506
  运行:
@@ -1520,7 +1520,7 @@ Sinatra::Base子类可用的方法实际上就是通过顶层 DSL
1520
1520
 
1521
1521
  加入相应的 <tt>config.ru</tt>:
1522
1522
 
1523
- require 'app'
1523
+ require './app'
1524
1524
  run Sinatra::Application
1525
1525
 
1526
1526
  === 什么时候用 config.ru?
data/Rakefile CHANGED
@@ -3,6 +3,12 @@ require 'rake/testtask'
3
3
  require 'fileutils'
4
4
  require 'date'
5
5
 
6
+ # CI Reporter is only needed for the CI
7
+ begin
8
+ require 'ci/reporter/rake/test_unit'
9
+ rescue LoadError
10
+ end
11
+
6
12
  task :default => :test
7
13
  task :spec => :test
8
14
 
@@ -37,6 +43,16 @@ Rake::TestTask.new(:test) do |t|
37
43
  t.ruby_opts << '-I.'
38
44
  end
39
45
 
46
+ Rake::TestTask.new(:"test:core") do |t|
47
+ core_tests = %w[base delegator encoding extensions filter
48
+ helpers mapped_error middleware radius rdoc
49
+ readme request response result route_added_hook
50
+ routing server settings sinatra static templates]
51
+ t.test_files = core_tests.map {|n| "test/#{n}_test.rb"}
52
+ t.ruby_opts = ["-rubygems"] if defined? Gem
53
+ t.ruby_opts << "-I."
54
+ end
55
+
40
56
  # Rcov ================================================================
41
57
 
42
58
  namespace :test do
@@ -67,7 +83,7 @@ task :add_template, [:name] do |t, args|
67
83
  puts "Liquid not found in #{file}"
68
84
  else
69
85
  puts "Adding section to #{file}"
70
- template = template.gsub(/Liquid/, args.name.capitalize).gsub(/liquid/, args.name.downcase)
86
+ template = template.gsub(/Liquid/, args.name.capitalize).gsub(/liquid/, args.name.downcase)
71
87
  code.gsub! /^(\s*===.*CoffeeScript)/, "\n" << template << "\n\\1"
72
88
  File.open(file, "w") { |f| f << code }
73
89
  end
@@ -90,18 +106,22 @@ task :thanks, [:release,:backports] do |t, a|
90
106
  "(based on commits included in #{a.release}, but not in #{a.backports})"
91
107
  end
92
108
 
93
- task :authors, [:format, :sep] do |t, a|
94
- a.with_defaults :format => "%s (%d)", :sep => ', '
109
+ desc "list of authors"
110
+ task :authors, [:commit_range, :format, :sep] do |t, a|
111
+ a.with_defaults :format => "%s (%d)", :sep => ", ", :commit_range => '--all'
95
112
  authors = Hash.new { |h,k| h[k] = 0 }
96
113
  blake = "Blake Mizerany"
114
+ overall = 0
97
115
  mapping = {
98
116
  "blake.mizerany@gmail.com" => blake, "bmizerany" => blake,
99
117
  "a_user@mac.com" => blake, "ichverstehe" => "Harry Vangberg",
100
118
  "Wu Jiang (nouse)" => "Wu Jiang" }
101
- `git shortlog -s`.lines.map do |line|
119
+ `git shortlog -s #{a.commit_range}`.lines.map do |line|
102
120
  num, name = line.split("\t", 2).map(&:strip)
103
121
  authors[mapping[name] || name] += num.to_i
122
+ overall += num.to_i
104
123
  end
124
+ puts "#{overall} commits by #{authors.count} authors:"
105
125
  puts authors.sort_by { |n,c| -c }.map { |e| a.format % e }.join(a.sep)
106
126
  end
107
127
 
@@ -147,9 +167,8 @@ if defined?(Gem)
147
167
  # read spec file and split out manifest section
148
168
  spec = File.read(f.name)
149
169
  head, manifest, tail = spec.split(" # = MANIFEST =\n")
150
- # replace version and date
170
+ # replace version
151
171
  head.sub!(/\.version = '.*'/, ".version = '#{source_version}'")
152
- head.sub!(/\.date = '.*'/, ".date = '#{Date.today.to_s}'")
153
172
  # determine file list from git ls-files
154
173
  files = `git ls-files`.
155
174
  split("\n").
@@ -7,7 +7,7 @@ require 'sinatra/showexceptions'
7
7
  require 'tilt'
8
8
 
9
9
  module Sinatra
10
- VERSION = '1.2.6'
10
+ VERSION = '1.2.7'
11
11
 
12
12
  # The request object. See Rack::Request for more info:
13
13
  # http://rack.rubyforge.org/doc/classes/Rack/Request.html
@@ -16,7 +16,7 @@ module Sinatra
16
16
  def accept
17
17
  @env['sinatra.accept'] ||= begin
18
18
  entries = @env['HTTP_ACCEPT'].to_s.split(',')
19
- entries.map { |e| accept_entry(e) }.sort_by(&:last).map(&:first)
19
+ entries.map { |e| accept_entry(e) }.sort_by { |e| e.last }.map { |e| e.first }
20
20
  end
21
21
  end
22
22
 
@@ -69,16 +69,16 @@ module Sinatra
69
69
  # http://rack.rubyforge.org/doc/classes/Rack/Response.html
70
70
  # http://rack.rubyforge.org/doc/classes/Rack/Response/Helpers.html
71
71
  class Response < Rack::Response
72
- def finish
73
- @body = block if block_given?
72
+ def finish(&block)
74
73
  if [204, 304].include?(status.to_i)
75
74
  header.delete "Content-Type"
75
+ header.delete "Content-Length"
76
76
  [status.to_i, header.to_hash, []]
77
77
  else
78
- body = @body || []
79
- body = [body] if body.respond_to? :to_str
80
- if body.respond_to?(:to_ary)
81
- header["Content-Length"] = body.to_ary.
78
+ body = block || @body || []
79
+ body = [body] if String === body
80
+ if Array === body
81
+ header["Content-Length"] = body.
82
82
  inject(0) { |len, part| len + Rack::Utils.bytesize(part) }.to_s
83
83
  end
84
84
  [status.to_i, header.to_hash, body]
@@ -127,9 +127,7 @@ module Sinatra
127
127
  return addr if addr =~ /\A[A-z][A-z0-9\+\.\-]*:/
128
128
  uri = [host = ""]
129
129
  if absolute
130
- host << 'http'
131
- host << 's' if request.secure?
132
- host << "://"
130
+ host << "http#{'s' if request.secure?}://"
133
131
  if request.forwarded? or request.port != (request.secure? ? 443 : 80)
134
132
  host << request.host_with_port
135
133
  else
@@ -240,6 +238,11 @@ module Sinatra
240
238
 
241
239
  attr_accessor :range # a Range or nil
242
240
 
241
+ def initialize(*args)
242
+ super(*args)
243
+ @range = nil
244
+ end
245
+
243
246
  # Checks for byte-ranges in the request and sets self.range appropriately.
244
247
  # Returns false if the ranges are unsatisfiable and the request should return 416.
245
248
  def parse_ranges(env, size)
@@ -281,6 +284,10 @@ module Sinatra
281
284
  ranges
282
285
  end
283
286
 
287
+ def close
288
+ super unless closed?
289
+ end
290
+
284
291
  CHUNK_SIZE = 8192
285
292
 
286
293
  def each
@@ -451,6 +458,11 @@ module Sinatra
451
458
  attr_accessor :content_type
452
459
  end
453
460
 
461
+ def initialize
462
+ super
463
+ @default_layout = :layout
464
+ end
465
+
454
466
  def erb(template, options={}, locals={})
455
467
  render :erb, template, options, locals
456
468
  end
@@ -548,7 +560,6 @@ module Sinatra
548
560
  # extract generic options
549
561
  locals = options.delete(:locals) || locals || {}
550
562
  views = options.delete(:views) || settings.views || "./views"
551
- @default_layout = :layout if @default_layout.nil?
552
563
  layout = options.delete(:layout)
553
564
  eat_errors = layout.nil?
554
565
  layout = @default_layout if layout.nil? or layout == true
@@ -619,6 +630,7 @@ module Sinatra
619
630
  attr_reader :template_cache
620
631
 
621
632
  def initialize(app=nil)
633
+ super()
622
634
  @app = app
623
635
  @template_cache = Tilt::Cache.new
624
636
  yield self if block_given?
@@ -644,7 +656,7 @@ module Sinatra
644
656
  invoke { dispatch! }
645
657
  invoke { error_block!(response.status) }
646
658
  unless @response['Content-Type']
647
- if body.respond_to?(:to_ary) and body.first.respond_to? :content_type
659
+ if Array === body and body.first.respond_to? :content_type
648
660
  content_type body.first.content_type
649
661
  else
650
662
  content_type :html
@@ -804,15 +816,14 @@ module Sinatra
804
816
  end
805
817
 
806
818
  # Run the block with 'throw :halt' support and apply result to the response.
807
- def invoke(&block)
808
- res = catch(:halt) { instance_eval(&block) }
819
+ def invoke
820
+ res = catch(:halt) { yield }
809
821
  return if res.nil?
810
822
 
811
823
  case
812
824
  when res.respond_to?(:to_str)
813
825
  @response.body = [res]
814
- when res.respond_to?(:to_ary)
815
- res = res.to_ary
826
+ when Array === res
816
827
  if Fixnum === res.first
817
828
  if res.length == 3
818
829
  @response.status, headers, body = res
@@ -1069,6 +1080,15 @@ module Sinatra
1069
1080
  @conditions << block
1070
1081
  end
1071
1082
 
1083
+ def public=(value)
1084
+ set :public_folder, value
1085
+ end
1086
+
1087
+ def public(*)
1088
+ super
1089
+ public_folder
1090
+ end
1091
+
1072
1092
  private
1073
1093
  # Condition for matching host name. Parameter might be String or Regexp.
1074
1094
  def host_name(pattern)
@@ -1186,7 +1206,7 @@ module Sinatra
1186
1206
  # Makes the methods defined in the block and in the Modules given
1187
1207
  # in `extensions` available to the handlers and templates
1188
1208
  def helpers(*extensions, &block)
1189
- class_eval(&block) if block_given?
1209
+ class_eval(&block) if block_given?
1190
1210
  include(*extensions) if extensions.any?
1191
1211
  end
1192
1212
 
@@ -1220,7 +1240,7 @@ module Sinatra
1220
1240
  def quit!(server, handler_name)
1221
1241
  # Use Thin's hard #stop! if available, otherwise just #stop.
1222
1242
  server.respond_to?(:stop!) ? server.stop! : server.stop
1223
- puts "\n== Sinatra has ended his set (crowd applauds)" unless handler_name =~/cgi/i
1243
+ $stderr.puts "\n== Sinatra has ended his set (crowd applauds)" unless handler_name =~/cgi/i
1224
1244
  end
1225
1245
 
1226
1246
  # Run the Sinatra app as a self-hosted server using
@@ -1229,14 +1249,14 @@ module Sinatra
1229
1249
  set options
1230
1250
  handler = detect_rack_handler
1231
1251
  handler_name = handler.name.gsub(/.*::/, '')
1232
- puts "== Sinatra/#{Sinatra::VERSION} has taken the stage " +
1252
+ $stderr.puts "== Sinatra/#{Sinatra::VERSION} has taken the stage " +
1233
1253
  "on #{port} for #{environment} with backup from #{handler_name}" unless handler_name =~/cgi/i
1234
1254
  handler.run self, :Host => bind, :Port => port do |server|
1235
1255
  [:INT, :TERM].each { |sig| trap(sig) { quit!(server, handler_name) } }
1236
1256
  set :running, true
1237
1257
  end
1238
1258
  rescue Errno::EADDRINUSE => e
1239
- puts "== Someone is already performing on port #{port}!"
1259
+ $stderr.puts "== Someone is already performing on port #{port}!"
1240
1260
  end
1241
1261
 
1242
1262
  # The prototype instance used to process requests.
@@ -1282,7 +1302,7 @@ module Sinatra
1282
1302
  servers = Array(server)
1283
1303
  servers.each do |server_name|
1284
1304
  begin
1285
- return Rack::Handler.get(server_name.downcase)
1305
+ return Rack::Handler.get(server_name)
1286
1306
  rescue LoadError
1287
1307
  rescue NameError
1288
1308
  end
@@ -1313,7 +1333,7 @@ module Sinatra
1313
1333
  CALLERS_TO_IGNORE = [ # :nodoc:
1314
1334
  /\/sinatra(\/(base|main|showexceptions))?\.rb$/, # all sinatra code
1315
1335
  /lib\/tilt.*\.rb$/, # all tilt code
1316
- /\(.*\)/, # generated code
1336
+ /^\(.*\)$/, # generated code
1317
1337
  /rubygems\/custom_require\.rb$/, # rubygems require hacks
1318
1338
  /active_support/, # active_support require hacks
1319
1339
  /bundler(\/runtime)?\.rb/, # bundler require hacks
@@ -1350,7 +1370,7 @@ module Sinatra
1350
1370
  def self.force_encoding(data, encoding = default_encoding)
1351
1371
  return if data == settings || data.is_a?(Tempfile)
1352
1372
  if data.respond_to? :force_encoding
1353
- data.force_encoding encoding
1373
+ data.force_encoding(encoding).encode!
1354
1374
  elsif data.respond_to? :each_value
1355
1375
  data.each_value { |v| force_encoding(v, encoding) }
1356
1376
  elsif data.respond_to? :each
@@ -1360,7 +1380,7 @@ module Sinatra
1360
1380
  end
1361
1381
  else
1362
1382
  def self.force_encoding(data, *) data end
1363
- end
1383
+ end
1364
1384
 
1365
1385
  reset!
1366
1386
 
@@ -1372,7 +1392,8 @@ module Sinatra
1372
1392
  set :logging, false
1373
1393
  set :method_override, false
1374
1394
  set :default_encoding, "utf-8"
1375
- set :add_charset, [/^text\//, 'application/javascript', 'application/xml', 'application/xhtml+xml']
1395
+ set :add_charset, %w[javascript xml xhtml+xml json].map { |t| "application/#{t}" }
1396
+ settings.add_charset << /^text\//
1376
1397
 
1377
1398
  # explicitly generating this eagerly to play nice with preforking
1378
1399
  set :session_secret, '%x' % rand(2**255)
@@ -1398,7 +1419,7 @@ module Sinatra
1398
1419
  set :reload_templates, Proc.new { development? or RUBY_VERSION < '1.8.7' }
1399
1420
  set :lock, false
1400
1421
 
1401
- set :public, Proc.new { root && File.join(root, 'public') }
1422
+ set :public_folder, Proc.new { root && File.join(root, 'public') }
1402
1423
  set :static, Proc.new { public && File.exist?(public) }
1403
1424
 
1404
1425
  error ::Exception do
@@ -1446,7 +1467,7 @@ module Sinatra
1446
1467
  #
1447
1468
  # The Application class should not be subclassed, unless you want to
1448
1469
  # inherit all settings, routes, handlers, and error pages from the
1449
- # top-level. Subclassing Sinatra::Base is heavily recommended for
1470
+ # top-level. Subclassing Sinatra::Base is highly recommended for
1450
1471
  # modular applications.
1451
1472
  class Application < Base
1452
1473
  set :logging, Proc.new { ! test? }
@@ -16,7 +16,7 @@ module Sinatra
16
16
  op.on('-x') { set :lock, true }
17
17
  op.on('-e env') { |val| set :environment, val.to_sym }
18
18
  op.on('-s server') { |val| set :server, val }
19
- op.on('-p port') { |val| set :port, val.to_i }
19
+ op.on('-p port') { |val| set :port, Integer(val) }
20
20
  op.on('-o addr') { |val| set :bind, val }
21
21
  }.parse!(ARGV.dup)
22
22
  end
@@ -252,7 +252,7 @@ TEMPLATE = <<-HTML # :nodoc:
252
252
 
253
253
  <div id="get">
254
254
  <h3 id="get-info">GET</h3>
255
- <% unless req.GET.empty? %>
255
+ <% if req.GET and not req.GET.empty? %>
256
256
  <table class="req">
257
257
  <tr>
258
258
  <th>Variable</th>
@@ -273,7 +273,7 @@ TEMPLATE = <<-HTML # :nodoc:
273
273
 
274
274
  <div id="post">
275
275
  <h3 id="post-info">POST</h3>
276
- <% unless req.POST.empty? %>
276
+ <% if req.POST and not req.POST.empty? %>
277
277
  <table class="req">
278
278
  <tr>
279
279
  <th>Variable</th>
@@ -3,8 +3,7 @@ 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.2.6'
7
- s.date = '2011-05-01'
6
+ s.version = '1.2.7'
8
7
 
9
8
  s.description = "Classy web-development dressed in a DSL"
10
9
  s.summary = "Classy web-development dressed in a DSL"
@@ -58,6 +57,7 @@ Gem::Specification.new do |s|
58
57
  test/middleware_test.rb
59
58
  test/nokogiri_test.rb
60
59
  test/public/favicon.ico
60
+ test/rack_test.rb
61
61
  test/radius_test.rb
62
62
  test/rdoc_test.rb
63
63
  test/request_test.rb
@@ -1,3 +1,5 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
1
3
  class DelegatorTest < Test::Unit::TestCase
2
4
  class Mirror
3
5
  attr_reader :last_call
@@ -419,6 +419,7 @@ class HelpersTest < Test::Unit::TestCase
419
419
  assert_equal content_type(:xml), 'application/xml;charset=utf-8'
420
420
  assert_equal content_type(:xhtml), 'application/xhtml+xml;charset=utf-8'
421
421
  assert_equal content_type(:js), 'application/javascript;charset=utf-8'
422
+ assert_equal content_type(:json), 'application/json;charset=utf-8'
422
423
  assert_equal content_type(:bar), 'application/bar'
423
424
  assert_equal content_type(:png), 'image/png'
424
425
  assert_equal content_type(:baz), 'application/baz;charset=utf-8'
@@ -15,7 +15,7 @@ class NokogiriTest < Test::Unit::TestCase
15
15
  it 'renders inline Nokogiri strings' do
16
16
  nokogiri_app { nokogiri 'xml' }
17
17
  assert ok?
18
- assert_body %{<?xml version="1.0"?>\n}
18
+ assert_body %(<?xml version="1.0"?>\n)
19
19
  end
20
20
 
21
21
  it 'renders inline blocks' do
@@ -26,7 +26,7 @@ class NokogiriTest < Test::Unit::TestCase
26
26
  end
27
27
  end
28
28
  assert ok?
29
- assert_body "<?xml version=\"1.0\"?>\n<couple>Frank &amp; Mary</couple>\n"
29
+ assert_body %(<?xml version="1.0"?>\n<couple>Frank &amp; Mary</couple>\n)
30
30
  end
31
31
 
32
32
  it 'renders .nokogiri files in views path' do
@@ -35,7 +35,7 @@ class NokogiriTest < Test::Unit::TestCase
35
35
  nokogiri :hello
36
36
  end
37
37
  assert ok?
38
- assert_body %(<?xml version="1.0"?>\n<exclaim>You're my boy, Blue!</exclaim>\n)
38
+ assert_body "<?xml version=\"1.0\"?>\n<exclaim>You're my boy, Blue!</exclaim>\n"
39
39
  end
40
40
 
41
41
  it "renders with inline layouts" do
@@ -46,17 +46,16 @@ class NokogiriTest < Test::Unit::TestCase
46
46
  end
47
47
  get '/'
48
48
  assert ok?
49
- assert_body "<?xml version=\"1.0\"?>\n<layout>\n <em>Hello World</em>\n</layout>\n"
49
+ assert_body %(<?xml version="1.0"?>\n<layout>\n <em>Hello World</em>\n</layout>\n)
50
50
  end
51
51
 
52
52
  it "renders with file layouts" do
53
53
  next if Tilt::VERSION <= "1.1"
54
54
  nokogiri_app do
55
- @name = "Blue"
56
55
  nokogiri %(xml.em 'Hello World'), :layout => :layout2
57
56
  end
58
57
  assert ok?
59
- assert_body "<?xml version=\"1.0\"?>\n<layout>\n <em>Hello World</em>\n</layout>\n"
58
+ assert_body %(<?xml version="1.0"?>\n<layout>\n <em>Hello World</em>\n</layout>\n)
60
59
  end
61
60
 
62
61
  it "raises error if template not found" do