sinatra 1.1.2 → 1.1.3

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.

@@ -90,7 +90,7 @@ Sinatra — это предметно-ориентированный язык (D
90
90
  end
91
91
 
92
92
  get '/foo' do
93
- # соответствует с non-songbird браузерам
93
+ # соответствует non-songbird браузерам
94
94
  end
95
95
 
96
96
  Другими доступными условиями являются +host_name+ и +provides+:
@@ -122,7 +122,7 @@ Sinatra — это предметно-ориентированный язык (D
122
122
  === Возвращаемые значения
123
123
 
124
124
  Возвращаемое значение блока маршрута ограничивается телом ответа, которое будет передано HTTP клиенту,
125
- или следующей подпрограммой (middleware) в Rack стеке. Чаще всего это строка, как в вышеизложенных примерах.
125
+ или следующей "прослойкой" (middleware, промежуточная программа) в Rack стеке. Чаще всего это строка, как в вышеизложенных примерах.
126
126
  Но и другие значения также приемлемы.
127
127
 
128
128
  Вы можете вернуть любой объект, который будет либо корректным Rack ответом, Rack
@@ -334,16 +334,31 @@ rdiscount gem/библиотека необходима для рендерин
334
334
  Отрисует <tt>./views/index.markdown</tt> (+md+ и +mkd+ также являются допустимыми файловыми
335
335
  расширениями).
336
336
 
337
- В markdown невозможно вызывать методы или передавать локальные переменные. Следовательно, вам скорее всего придется
338
- использовать этот шаблон совместно с другим движком рендеринга:
337
+ В Markdown невозможно вызывать методы или передавать локальные переменные.
338
+ Следовательно, вам скорее всего придется использовать этот шаблон совместно с другим
339
+ движком рендеринга:
339
340
 
340
341
  erb :overview, :locals => { :text => markdown(:introduction) }
341
342
 
342
- Заметьте, что вы можете вызывать метод markdown из других шаблонов:
343
+ Заметьте, что вы можете вызывать метод +markdown+ из других шаблонов:
343
344
 
344
345
  %h1 Hello From Haml!
345
346
  %p= markdown(:greetings)
346
347
 
348
+ Также возможно обрабатывать Markdown с помощью BlueCloth, а не RDiscount:
349
+
350
+ require 'bluecloth'
351
+
352
+ Tilt.register 'markdown', BlueClothTemplate
353
+ Tilt.register 'mkd', BlueClothTemplate
354
+ Tilt.register 'md', BlueClothTemplate
355
+
356
+ get '/' do
357
+ markdown :index
358
+ end
359
+
360
+ Отрисует <tt>./views/index.md</tt> с помощью BlueCloth.
361
+
347
362
  === Textile шаблоны
348
363
 
349
364
  RedCloth gem/библиотека необходима для рендеринга Textile шаблонов:
@@ -434,13 +449,13 @@ coffee-script gem/библиотека и `coffee` бинарный файл н
434
449
 
435
450
  Отрисует <tt>./views/application.coffee</tt>.
436
451
 
437
- === Внутристроковые шаблоны
452
+ === Встроенные шаблоны
438
453
 
439
454
  get '/' do
440
455
  haml '%div.title Hello World'
441
456
  end
442
457
 
443
- Отрисует внутристроковый шаблон.
458
+ Отрисует встроенный (строчный) шаблон.
444
459
 
445
460
  === Доступ к переменным в шаблонах
446
461
 
@@ -501,7 +516,8 @@ coffee-script gem/библиотека и `coffee` бинарный файл н
501
516
  end
502
517
 
503
518
  Если шаблон с именем "layout" существует, то он будет использован каждый раз,
504
- когда шаблоны будут отрисовываться. Вы можете отключить layout-шаблон с помощью <tt>:layout => false</tt>.
519
+ когда шаблоны будут отрисовываться. Вы можете отключать layout-шаблон в каждом конкретном случае с помощью
520
+ <tt>:layout => false</tt> или отключить его для всего приложения, например, так: <tt>set :haml, :layout => false</tt>.
505
521
 
506
522
  get '/' do
507
523
  haml :index, :layout => !request.xhr?
@@ -729,15 +745,15 @@ Sinatra устанавливает специальные <tt>not_found</tt> и
729
745
 
730
746
  content_type :foo
731
747
 
732
- == Rack подпрограммы
748
+ == Rack "прослойки"
733
749
 
734
750
  Sinatra использует Rack[http://rack.rubyforge.org/], минимальный стандартный
735
751
  интерфейс для веб-фреймворков на Ruby. Одной из самых интересных для разработчиков возможностей Rack
736
- является поддержка подпрограмм ("middleware") -- компонентов,
752
+ является поддержка "прослоек" ("middleware") компонентов,
737
753
  "сидящих" между сервером и вашим приложением, которые отслеживают и/или манипулируют
738
754
  HTTP запросами/ответами для предоставления различной функциональности.
739
755
 
740
- В Sinatra очень просто использовать такие Rack подпрограммы с помощью метода +use+:
756
+ В Sinatra очень просто использовать такие "прослойки" с помощью метода +use+:
741
757
 
742
758
  require 'sinatra'
743
759
  require 'my_custom_middleware'
@@ -758,7 +774,7 @@ Rack::Builder[http://rack.rubyforge.org/doc/classes/Rack/Builder.html] DSL
758
774
  username == 'admin' && password == 'secret'
759
775
  end
760
776
 
761
- Rack распространяется с различными стандартными подпрограммами
777
+ Rack распространяется с различными стандартными "прослойками"
762
778
  для логирования, отладки, маршрутизации URL, аутентификации, обработки сессий. Sinatra использует
763
779
  многие из этих компонентов автоматически, основываясь на конфигурации, чтобы вам не приходилось
764
780
  регистрировать/использовать (+use+) их вручную.
@@ -798,13 +814,12 @@ Rack распространяется с различными стандартн
798
814
  Заметьте: Встроенные модули Sinatra::Test и Sinatra::TestHarness являются
799
815
  устаревшими, начиная с 0.9.2 релиза.
800
816
 
801
- == Sinatra::Base - Подпрограммы, библиотеки и модульные приложения
817
+ == Sinatra::Base "прослойки", библиотеки и модульные приложения
802
818
 
803
819
  Описание своего приложения самым простейшим способом (с помощью DSL верхнего уровня, как в примерах выше)
804
- работает отлично для крохотных приложений, но имеет множество недостатков, когда надо
805
- создать компоненты, такие как Rack
806
- middleware, Rails metal, простые библиотеки с серверными компонентами,
807
- Sinatra расширения.
820
+ работает отлично для крохотных приложений, но имеет множество недостатков, когда надо создать компоненты, такие как
821
+ Rack middleware ("прослойки"), Rails metal, простые библиотеки с серверными компонентами,
822
+ расширения Sinatra.
808
823
  DSL верхнего уровня загрязняет пространство имен <tt>Object</tt> и подразумевает стиль конфигурации
809
824
  микро-приложения (например, единый файл приложения, ./public и
810
825
  ./views директории, создание логов, страницу деталей об исключениях
@@ -821,13 +836,6 @@ DSL верхнего уровня загрязняет пространство
821
836
  end
822
837
  end
823
838
 
824
- MyApp класс является независимым Rack компонентом, который может исполнять роли
825
- Rack подпрограммы, Rack приложения, Rails metal. Вы можете +use+ (использовать) или
826
- +run+ (запустить) этот класс из rackup файла +config.ru+; или контролировать серверную
827
- часть из библиотеки:
828
-
829
- MyApp.run! :host => 'localhost', :port => 9090
830
-
831
839
  Методы, доступные Sinatra::Base сабклассам идентичны тем, что доступны
832
840
  в DSL верхнего уровня. Большинство приложений верхнего уровня могут быть
833
841
  конвертированы в Sinatra::Base компоненты с помощью двух модификаций:
@@ -840,10 +848,68 @@ Rack подпрограммы, Rack приложения, Rails metal. Вы мо
840
848
  Смотрите {Опции и Конфигурация}[http://www.sinatrarb.com/configuration.html] для детальной информации
841
849
  об опциях и их поведении.
842
850
 
843
- === Использование Sinatra как подпрограммы
851
+ === Запуск модульных приложений
852
+
853
+ Есть два общепринятых способа запускать модульные приложения: запуск напрямую с помощью <tt>run!</tt>:
854
+
855
+ # my_app.rb
856
+ require 'sinatra/base'
857
+
858
+ class MyApp < Sinatra::Base
859
+ # ... здесь код приложения ...
860
+
861
+ # запускаем сервер, если исполняется текущий файл
862
+ run! if app_file == $0
863
+ end
864
+
865
+ И запускаем с помощью:
866
+
867
+ ruby my_app.rb
868
+
869
+ Или с помощью конфигурационного файла <tt>config.ru</tt>, который позволяет использовать любой
870
+ Rack-совместимый сервер приложений.
871
+
872
+ # config.ru
873
+ require 'my_app'
874
+ run MyApp
875
+
876
+ Запускаем:
877
+
878
+ rackup -p 4567
879
+
880
+ === Запуск "классических" приложений с config.ru
881
+
882
+ Файл приложения:
883
+
884
+ # app.rb
885
+ require 'sinatra'
886
+
887
+ get '/' do
888
+ 'Hello world!'
889
+ end
890
+
891
+ И соответствующий <tt>config.ru</tt>:
892
+
893
+ require 'app'
894
+ run Sinatra::Application
895
+
896
+ === Когда использовать config.ru?
897
+
898
+ Вот несколько причин, по которым вы, возможно, захотите использовать <tt>config.ru</tt>:
899
+
900
+ * вы хотите разворачивать свое приложение на различных Rack-совместимых серверах (Passenger, Unicorn,
901
+ Heroku, ...).
902
+ * вы хотите использовать более одного сабкласса <tt>Sinatra::Base</tt>.
903
+ * вы хотите использовать Sinatra только в качестве "прослойки" Rack.
904
+
905
+ <b>Совсем необязательно переходить на использование <tt>config.ru</tt> лишь потому, что вы стали
906
+ использовать модульный стиль приложения. И необязательно использовать модульный стиль, чтобы
907
+ запускать приложение с помощью <tt>config.ru</tt>.</b>
908
+
909
+ === Использование Sinatra в качестве "прослойки"
844
910
 
845
- Не только сама Sinatra может использовать подпрограммы Rack, любое Sinatra приложение
846
- само может быть добавлено к любому Rack эндпоинту в качестве подпрограммы. Этим эндпоинтом
911
+ Не только сама Sinatra может использовать "прослойки" Rack, но и любое Sinatra приложение
912
+ само может быть добавлено к любому Rack эндпоинту в качестве "прослойки". Этим эндпоинтом
847
913
  может быть другое Sinatra приложение, или приложение, основанное на Rack (Rails/Ramaze/Camping/...).
848
914
 
849
915
  require 'sinatra/base'
@@ -863,7 +929,7 @@ Rack подпрограммы, Rack приложения, Rails metal. Вы мо
863
929
  end
864
930
 
865
931
  class MyApp < Sinatra::Base
866
- # подпрограмма будет запущена перед фильтрами
932
+ # "прослойка" будет запущена перед фильтрами
867
933
  use LoginScreen
868
934
 
869
935
  before do
data/Rakefile CHANGED
@@ -6,6 +6,8 @@ require 'date'
6
6
  task :default => :test
7
7
  task :spec => :test
8
8
 
9
+ CLEAN.include "**/*.rbc"
10
+
9
11
  def source_version
10
12
  line = File.read('lib/sinatra/base.rb')[/^\s*VERSION = .*/]
11
13
  line.match(/.*VERSION = '(.*)'/)[1]
@@ -17,21 +19,11 @@ task :test do
17
19
  ENV.delete 'LC_CTYPE'
18
20
  end
19
21
 
20
- if !ENV['NO_TEST_FIX'] and RUBY_VERSION == '1.9.2' and RUBY_PATCHLEVEL == 0
21
- # Avoids seg fault
22
- task(:test) do
23
- second_run = %w[settings rdoc markaby templates static textile].map { |l| "test/#{l}_test.rb" }
24
- first_run = Dir.glob('test/*_test.rb') - second_run
25
- [first_run, second_run].each { |f| sh "testrb #{f.join ' '}" }
26
- end
27
- else
28
- Rake::TestTask.new(:test) do |t|
29
- t.test_files = FileList['test/*_test.rb']
30
- t.ruby_opts = ['-rubygems'] if defined? Gem
31
- t.ruby_opts << '-I.'
32
- end
22
+ Rake::TestTask.new(:test) do |t|
23
+ t.test_files = FileList['test/*_test.rb']
24
+ t.ruby_opts = ['-rubygems'] if defined? Gem
25
+ t.ruby_opts << '-I.'
33
26
  end
34
-
35
27
  # Rcov ================================================================
36
28
  namespace :test do
37
29
  desc 'Mesures test coverage'
@@ -7,7 +7,7 @@ require 'sinatra/showexceptions'
7
7
  require 'tilt'
8
8
 
9
9
  module Sinatra
10
- VERSION = '1.1.2'
10
+ VERSION = '1.1.3'
11
11
 
12
12
  # The request object. See Rack::Request for more info:
13
13
  # http://rack.rubyforge.org/doc/classes/Rack/Request.html
@@ -324,10 +324,17 @@ module Sinatra
324
324
  # with a '304 Not Modified' response.
325
325
  def last_modified(time)
326
326
  return unless time
327
- time = time.to_time if time.respond_to?(:to_time)
328
- time = Time.parse time.strftime('%FT%T%:z') if time.respond_to?(:strftime)
329
- response['Last-Modified'] = time.respond_to?(:httpdate) ? time.httpdate : time.to_s
330
- halt 304 if Time.httpdate(request.env['HTTP_IF_MODIFIED_SINCE']) >= time
327
+ if time.respond_to?(:to_time)
328
+ time = time.to_time
329
+ else
330
+ ## make a best effort to convert something else to a time object
331
+ ## if this fails, this should throw an ArgumentError, then the
332
+ # rescue will result in an http 200, which should be safe
333
+ time = Time.parse(time.to_s)
334
+ end
335
+ response['Last-Modified'] = time.httpdate
336
+ # compare based on seconds since epoch
337
+ halt 304 if Time.httpdate(request.env['HTTP_IF_MODIFIED_SINCE']).to_i >= time.to_i
331
338
  rescue ArgumentError
332
339
  end
333
340
 
@@ -498,13 +505,12 @@ module Sinatra
498
505
  template.new(path, line.to_i, options) { body }
499
506
  else
500
507
  found = false
501
- path = ::File.join(views, "#{data}.#{engine}")
502
508
  Tilt.mappings.each do |ext, klass|
503
- break if found = File.exists?(path)
504
509
  next unless klass == template
505
510
  path = ::File.join(views, "#{data}.#{ext}")
511
+ break if found = File.exists?(path)
506
512
  end
507
- throw :layout_missing if eat_errors and !found
513
+ throw :layout_missing if eat_errors and not found
508
514
  template.new(path, 1, options)
509
515
  end
510
516
  when data.is_a?(Proc) || data.is_a?(String)
@@ -986,7 +992,7 @@ module Sinatra
986
992
  # Will set params[:agent].
987
993
  def user_agent(pattern)
988
994
  condition do
989
- if request.user_agent =~ pattern
995
+ if request.user_agent.to_s =~ pattern
990
996
  @params[:agent] = $~[1..-1]
991
997
  true
992
998
  else
@@ -1003,7 +1009,7 @@ module Sinatra
1003
1009
  condition do
1004
1010
  matching_types = (request.accept & types)
1005
1011
  unless matching_types.empty?
1006
- response.headers['Content-Type'] = matching_types.first
1012
+ content_type matching_types.first
1007
1013
  true
1008
1014
  else
1009
1015
  false
@@ -1062,7 +1068,7 @@ module Sinatra
1062
1068
  def compile(path)
1063
1069
  keys = []
1064
1070
  if path.respond_to? :to_str
1065
- special_chars = %w{. + ( )}
1071
+ special_chars = %w{. + ( ) $}
1066
1072
  pattern =
1067
1073
  path.to_str.gsub(/((:\w+)|[\*#{special_chars.join}])/) do |match|
1068
1074
  case match
@@ -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.1.2'
7
- s.date = '2010-12-25'
6
+ s.version = '1.1.3'
7
+ s.date = '2011-02-20'
8
8
 
9
9
  s.description = "Classy web-development dressed in a DSL"
10
10
  s.summary = "Classy web-development dressed in a DSL"
@@ -71,6 +71,7 @@ Gem::Specification.new do |s|
71
71
  test/templates_test.rb
72
72
  test/textile_test.rb
73
73
  test/views/ascii.haml
74
+ test/views/calc.html.erb
74
75
  test/views/error.builder
75
76
  test/views/error.erb
76
77
  test/views/error.erubis
@@ -114,7 +115,7 @@ Gem::Specification.new do |s|
114
115
 
115
116
  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]
116
117
  s.add_dependency 'rack', '~> 1.1'
117
- s.add_dependency 'tilt', '~> 1.2'
118
+ s.add_dependency 'tilt', '>= 1.2.2', '< 2.0'
118
119
  s.add_development_dependency 'rake'
119
120
  s.add_development_dependency 'shotgun', '~> 0.6'
120
121
  s.add_development_dependency 'rack-test', '>= 0.5.6'
@@ -592,6 +592,9 @@ class HelpersTest < Test::Unit::TestCase
592
592
  get '/compare', {}, { 'HTTP_IF_MODIFIED_SINCE' => 'Sun, 26 Sep 2010 23:43:52 GMT' }
593
593
  assert_equal 200, status
594
594
  assert_equal 'foo', body
595
+ get '/compare', {}, { 'HTTP_IF_MODIFIED_SINCE' => 'Sun, 26 Sep 2100 23:43:52 GMT' }
596
+ assert_equal 304, status
597
+ assert_equal '', body
595
598
  end
596
599
  end
597
600
 
@@ -247,7 +247,7 @@ class RoutingTest < Test::Unit::TestCase
247
247
  assert_equal 'right on', body
248
248
  end
249
249
 
250
- it "literally matches . in paths" do
250
+ it "literally matches dot in paths" do
251
251
  route_def '/test.bar'
252
252
 
253
253
  get '/test.bar'
@@ -256,14 +256,14 @@ class RoutingTest < Test::Unit::TestCase
256
256
  assert not_found?
257
257
  end
258
258
 
259
- it "literally matches $ in paths" do
259
+ it "literally matches dollar sign in paths" do
260
260
  route_def '/test$/'
261
261
 
262
262
  get '/test$/'
263
263
  assert ok?
264
264
  end
265
265
 
266
- it "literally matches + in paths" do
266
+ it "literally matches plus sign in paths" do
267
267
  route_def '/te+st/'
268
268
 
269
269
  get '/te%2Bst/'
@@ -272,7 +272,7 @@ class RoutingTest < Test::Unit::TestCase
272
272
  assert not_found?
273
273
  end
274
274
 
275
- it "literally matches () in paths" do
275
+ it "literally matches parens in paths" do
276
276
  route_def '/test(bar)/'
277
277
 
278
278
  get '/test(bar)/'
@@ -611,6 +611,18 @@ class RoutingTest < Test::Unit::TestCase
611
611
  assert_equal 'Hello World', body
612
612
  end
613
613
 
614
+ it "treats missing user agent like an empty string" do
615
+ mock_app do
616
+ user_agent(/.*/)
617
+ get '/' do
618
+ "Hello World"
619
+ end
620
+ end
621
+ get '/'
622
+ assert_equal 200, status
623
+ assert_equal 'Hello World', body
624
+ end
625
+
614
626
  it "makes captures in user agent pattern available in params[:agent]" do
615
627
  mock_app {
616
628
  user_agent(/Foo (.*)/)
@@ -636,7 +648,7 @@ class RoutingTest < Test::Unit::TestCase
636
648
  get '/', {}, { 'HTTP_ACCEPT' => 'application/xml' }
637
649
  assert ok?
638
650
  assert_equal 'application/xml', body
639
- assert_equal 'application/xml', response.headers['Content-Type']
651
+ assert_equal 'application/xml;charset=utf-8', response.headers['Content-Type']
640
652
 
641
653
  get '/', {}, { :accept => 'text/html' }
642
654
  assert !ok?
@@ -207,6 +207,12 @@ class TemplatesTest < Test::Unit::TestCase
207
207
  assert ok?
208
208
  assert_equal 'template in subclass', body
209
209
  end
210
+
211
+ it "is possible to register another template" do
212
+ Tilt.register "html.erb", Tilt[:erb]
213
+ render_app { render :erb, :calc }
214
+ assert_equal '2', body
215
+ end
210
216
  end
211
217
 
212
218
  # __END__ : this is not the real end of the script.
@@ -0,0 +1 @@
1
+ <%= 1 + 1 %>
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sinatra
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
5
- prerelease: false
4
+ hash: 21
5
+ prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 1
9
- - 2
10
- version: 1.1.2
9
+ - 3
10
+ version: 1.1.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Blake Mizerany
@@ -18,7 +18,7 @@ autorequire:
18
18
  bindir: bin
19
19
  cert_chain: []
20
20
 
21
- date: 2010-12-25 00:00:00 +01:00
21
+ date: 2011-02-20 00:00:00 +01:00
22
22
  default_executable:
23
23
  dependencies:
24
24
  - !ruby/object:Gem::Dependency
@@ -42,13 +42,21 @@ dependencies:
42
42
  requirement: &id002 !ruby/object:Gem::Requirement
43
43
  none: false
44
44
  requirements:
45
- - - ~>
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- hash: 11
47
+ hash: 27
48
48
  segments:
49
49
  - 1
50
50
  - 2
51
- version: "1.2"
51
+ - 2
52
+ version: 1.2.2
53
+ - - <
54
+ - !ruby/object:Gem::Version
55
+ hash: 3
56
+ segments:
57
+ - 2
58
+ - 0
59
+ version: "2.0"
52
60
  type: :runtime
53
61
  version_requirements: *id002
54
62
  - !ruby/object:Gem::Dependency
@@ -339,6 +347,7 @@ files:
339
347
  - test/templates_test.rb
340
348
  - test/textile_test.rb
341
349
  - test/views/ascii.haml
350
+ - test/views/calc.html.erb
342
351
  - test/views/error.builder
343
352
  - test/views/error.erb
344
353
  - test/views/error.erubis
@@ -410,7 +419,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
410
419
  requirements: []
411
420
 
412
421
  rubyforge_project: sinatra
413
- rubygems_version: 1.3.7
422
+ rubygems_version: 1.5.2
414
423
  signing_key:
415
424
  specification_version: 2
416
425
  summary: Classy web-development dressed in a DSL