sinatra-contrib 1.3.2 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,7 +13,7 @@ module Sinatra
13
13
  #
14
14
  # === Classic Application
15
15
  #
16
- # To enable the realoader in a classic application all you need to do is
16
+ # To enable the reloader in a classic application all you need to do is
17
17
  # require it:
18
18
  #
19
19
  # require "sinatra"
@@ -23,7 +23,7 @@ module Sinatra
23
23
  #
24
24
  # === Modular Application
25
25
  #
26
- # To enable the realoader in a modular application all you need to do is
26
+ # To enable the reloader in a modular application all you need to do is
27
27
  # require it, and then, register it:
28
28
  #
29
29
  # require "sinatra/base"
@@ -75,7 +75,7 @@ module Sinatra
75
75
  module Reloader
76
76
 
77
77
  # Watches a file so it can tell when it has been updated, and what
78
- # elements contains.
78
+ # elements does it contain.
79
79
  class Watcher
80
80
 
81
81
  # Represents an element of a Sinatra application that may need to
@@ -95,8 +95,8 @@ module Sinatra
95
95
  # Collection of file +Watcher+ that can be associated with a
96
96
  # Sinatra application. That way, we can know which files belong
97
97
  # to a given application and which files have been modified. It
98
- # also provides a mechanism to inform a Watcher the elements
99
- # defined in the file being watched and if it changes should be
98
+ # also provides a mechanism to inform a Watcher of the elements
99
+ # defined in the file being watched and if its changes should be
100
100
  # ignored.
101
101
  class List
102
102
  @app_list_map = Hash.new { |hash, key| hash[key] = new }
@@ -113,7 +113,7 @@ module Sinatra
113
113
  end
114
114
  end
115
115
 
116
- # Lets the +Watcher+ for the file localted at +path+ know that the
116
+ # Lets the +Watcher+ for the file located at +path+ know that the
117
117
  # +element+ is defined there, and adds the +Watcher+ to the +List+,
118
118
  # if it isn't already there.
119
119
  def watch(path, element)
@@ -159,7 +159,7 @@ module Sinatra
159
159
  !ignore? && !removed? && mtime != File.mtime(path)
160
160
  end
161
161
 
162
- # Updates the file being watched mtime.
162
+ # Updates the mtime of the file being watched.
163
163
  def update
164
164
  @mtime = File.mtime(path)
165
165
  end
@@ -1,11 +1,11 @@
1
- require 'sinatra/base'
2
1
  require 'sinatra/json'
2
+ require 'sinatra/base'
3
3
 
4
4
  module Sinatra
5
- ##
5
+ #
6
6
  # = Sinatra::RespondWith
7
7
  #
8
- # This extensions lets Sinatra automatically choose what template to render or
8
+ # These extensions let Sinatra automatically choose what template to render or
9
9
  # action to perform depending on the request's Accept header.
10
10
  #
11
11
  # Example:
@@ -53,8 +53,8 @@ module Sinatra
53
53
  # == Security
54
54
  #
55
55
  # Since methods are triggered based on client input, this can lead to security
56
- # issues (but not as seviere as those might apear in the first place: keep in
57
- # mind that only known file extensions are used). You therefore should limit
56
+ # issues (but not as severe as those might appear in the first place: keep in
57
+ # mind that only known file extensions are used). You should limit
58
58
  # the possible formats you serve.
59
59
  #
60
60
  # This is possible with the +provides+ condition:
@@ -64,7 +64,7 @@ module Sinatra
64
64
  # end
65
65
  #
66
66
  # However, since you have to set +provides+ for every route, this extension
67
- # adds a app global (class method) `respond_to`, that let's you define content
67
+ # adds an app global (class method) `respond_to`, that lets you define content
68
68
  # types for all routes:
69
69
  #
70
70
  # respond_to :html, :json, :xml, :atom
@@ -118,9 +118,9 @@ module Sinatra
118
118
  @app.halt 406
119
119
  end
120
120
 
121
- def method_missing(meth, *args, &block)
122
- return super if args.any? or block.nil? or not @app.mime_type(meth)
123
- on(meth, &block)
121
+ def method_missing(method, *args, &block)
122
+ return super if args.any? or block.nil? or not @app.mime_type(method)
123
+ on(method, &block)
124
124
  end
125
125
  end
126
126
 
@@ -138,15 +138,18 @@ module Sinatra
138
138
  if args.any?
139
139
  locals = { :object => object }
140
140
  locals.merge! object.to_hash if object.respond_to? :to_hash
141
- args << { :locals => locals }
142
- halt send(*args)
141
+
142
+ renderer = args.first
143
+ options = args[1..-1] + [{:locals => locals}]
144
+
145
+ halt send(renderer, *options)
143
146
  end
144
147
  end
145
148
  if object
146
149
  exts.each do |ext|
147
150
  halt json(object) if ext == :json
148
- next unless meth = "to_#{ext}" and object.respond_to? meth
149
- halt(*object.send(meth))
151
+ next unless object.respond_to? method = "to_#{ext}"
152
+ halt(*object.send(method))
150
153
  end
151
154
  end
152
155
  false
@@ -161,7 +164,7 @@ module Sinatra
161
164
  private
162
165
 
163
166
  def template_for(name, exts)
164
- # in production this is cached, so don't worry to much about runtime
167
+ # in production this is cached, so don't worry too much about runtime
165
168
  possible = []
166
169
  settings.template_engines[:all].each do |engine|
167
170
  exts.each { |ext| possible << [engine, "#{name}.#{ext}"] }
@@ -224,6 +227,7 @@ module Sinatra
224
227
  :css => [:less, :sass, :scss],
225
228
  :xml => [:builder, :nokogiri],
226
229
  :js => [:coffee],
230
+ :json => [:yajl],
227
231
  :html => [:erb, :erubis, :haml, :slim, :liquid, :radius, :mab, :markdown,
228
232
  :textile, :rdoc],
229
233
  :all => Sinatra::Templates.instance_methods.map(&:to_sym) + [:mab] -
@@ -7,7 +7,7 @@ module Sinatra
7
7
  # = Sinatra::Streaming
8
8
  #
9
9
  # Sinatra 1.3 introduced the +stream+ helper. This addon improves the
10
- # streaming API by making the stream object immitate an IO object, turing
10
+ # streaming API by making the stream object immitate an IO object, turning
11
11
  # it into a real Deferrable and making the body play nicer with middleware
12
12
  # unaware of streaming.
13
13
  #
@@ -44,9 +44,9 @@ module Sinatra
44
44
  #
45
45
  # == Better Middleware Handling
46
46
  #
47
- # Blocks passed to #map! or #map will actually be applied while streaming
48
- # (as you might suspect, #map! applies modifications to the current body,
49
- # #map creates a new one):
47
+ # Blocks passed to #map! or #map will actually be applied when streaming
48
+ # takes place (as you might have suspected, #map! applies modifications
49
+ # to the current body, while #map creates a new one):
50
50
  #
51
51
  # class StupidMiddleware
52
52
  # def initialize(app) @app = app end
@@ -89,7 +89,7 @@ module Sinatra
89
89
  #
90
90
  # require "sinatra/base"
91
91
  # require "sinatra/streaming"
92
- #
92
+ #
93
93
  # class MyApp < Sinatra::Base
94
94
  # helpers Sinatra::Streaming
95
95
  # end
@@ -264,4 +264,4 @@ module Sinatra
264
264
  end
265
265
 
266
266
  helpers Streaming
267
- end
267
+ end
@@ -72,7 +72,7 @@ module Sinatra
72
72
 
73
73
  def session
74
74
  return {} unless last_request?
75
- raise Rack::Test:Error, "session not enabled for app" unless last_env["rack.session"] or app.session?
75
+ raise Rack::Test::Error, "session not enabled for app" unless last_env["rack.session"] or app.session?
76
76
  last_request.session
77
77
  end
78
78
 
@@ -1,7 +1,7 @@
1
1
  # Run `rake sinatra-contrib.gemspec` to update the gemspec.
2
2
  Gem::Specification.new do |s|
3
3
  s.name = "sinatra-contrib"
4
- s.version = "1.3.2"
4
+ s.version = "1.4.0"
5
5
  s.description = "Collection of useful Sinatra extensions"
6
6
  s.homepage = "http://github.com/sinatra/sinatra-contrib"
7
7
  s.summary = s.description
@@ -10,17 +10,10 @@ Gem::Specification.new do |s|
10
10
  s.authors = [
11
11
  "Konstantin Haase",
12
12
  "Gabriel Andretta",
13
- "Trevor Bramble",
14
13
  "Nicolas Sanguinetti",
15
- "Ilya Shindyapin",
16
- "Masahiro Fujiwara",
17
- "Adrian Pacała",
18
- "Andrew Crump",
19
14
  "Eliot Shepard",
20
- "Eric Marden",
21
- "Gray Manley",
15
+ "Andrew Crump",
22
16
  "Matt Lyon",
23
- "lest",
24
17
  "undr"
25
18
  ]
26
19
 
@@ -28,17 +21,10 @@ Gem::Specification.new do |s|
28
21
  s.email = [
29
22
  "konstantin.mailinglists@googlemail.com",
30
23
  "ohhgabriel@gmail.com",
31
- "inbox@trevorbramble.com",
32
24
  "contacto@nicolassanguinetti.info",
33
- "ilya@shindyapin.com",
34
- "m-fujiwara@axsh.net",
35
- "altpacala@gmail.com",
36
- "andrew.crump@ieee.org",
37
25
  "eshepard@slower.net",
38
- "eric.marden@gmail.com",
39
- "g.manley@tukaiz.com",
26
+ "andrew.crump@ieee.org",
40
27
  "matt@flowerpowered.com",
41
- "just.lest@gmail.com",
42
28
  "undr@yandex.ru"
43
29
  ]
44
30
 
@@ -70,6 +56,7 @@ Gem::Specification.new do |s|
70
56
  "sinatra-contrib.gemspec",
71
57
  "spec/capture_spec.rb",
72
58
  "spec/config_file/key_value.yml",
59
+ "spec/config_file/key_value.yml.erb",
73
60
  "spec/config_file/key_value_override.yml",
74
61
  "spec/config_file/missing_env.yml",
75
62
  "spec/config_file/with_envs.yml",
@@ -79,10 +66,6 @@ Gem::Specification.new do |s|
79
66
  "spec/content_for/different_key.erubis",
80
67
  "spec/content_for/different_key.haml",
81
68
  "spec/content_for/different_key.slim",
82
- "spec/content_for/footer.erb",
83
- "spec/content_for/footer.erubis",
84
- "spec/content_for/footer.haml",
85
- "spec/content_for/footer.slim",
86
69
  "spec/content_for/layout.erb",
87
70
  "spec/content_for/layout.erubis",
88
71
  "spec/content_for/layout.haml",
@@ -129,7 +112,7 @@ Gem::Specification.new do |s|
129
112
  "spec/streaming_spec.rb"
130
113
  ]
131
114
 
132
- s.add_dependency "sinatra", "~> 1.3.0"
115
+ s.add_dependency "sinatra", "~> 1.4.2"
133
116
  s.add_dependency "backports", ">= 2.0"
134
117
  s.add_dependency "tilt", "~> 1.3"
135
118
  s.add_dependency "rack-test"
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  require 'backports'
2
3
  require 'slim'
3
4
  require_relative 'spec_helper'
@@ -20,6 +21,7 @@ describe Sinatra::Capture do
20
21
 
21
22
  shared_examples_for "a template language" do |engine|
22
23
  lang = engine == :erubis ? :erb : engine
24
+ require "#{engine}"
23
25
 
24
26
  it "captures content" do
25
27
  render(engine, "simple_#{lang}").should == "Say Hello World!"
@@ -32,8 +34,15 @@ describe Sinatra::Capture do
32
34
 
33
35
  describe('haml') { it_behaves_like "a template language", :haml }
34
36
  describe('slim') { it_behaves_like "a template language", :slim }
35
- describe('erb') { it_behaves_like "a template language", :erb }
36
37
  describe('erubis') { it_behaves_like "a template language", :erubis }
38
+
39
+ describe 'erb' do
40
+ it_behaves_like "a template language", :erb
41
+
42
+ it "handles utf-8 encoding" do
43
+ render(:erb, "utf_8").should == "UTF-8 –"
44
+ end
45
+ end
37
46
  end
38
47
 
39
48
  __END__
@@ -78,3 +87,7 @@ Say
78
87
  World
79
88
  #{b.strip}!
80
89
  Hello #{a.strip}
90
+
91
+ @@ utf_8
92
+ <% a = capture do %>–<% end %>
93
+ UTF-8 <%= a %>
@@ -0,0 +1,6 @@
1
+ ---
2
+ foo: <%= "bar" %>
3
+ something: <%= 42 %>
4
+ nested:
5
+ a: <%= 1 %>
6
+ b: <%= 2 %>
@@ -23,6 +23,16 @@ describe Sinatra::ConfigFile do
23
23
  settings.nested[:a].should == 1
24
24
  end
25
25
 
26
+ it 'should render options in ERB tags' do
27
+ config_file 'key_value.yml.erb'
28
+ settings.foo.should == "bar"
29
+ settings.something.should == 42
30
+ settings.nested['a'].should == 1
31
+ settings.nested[:a].should == 1
32
+ settings.nested['b'].should == 2
33
+ settings.nested[:b].should == 2
34
+ end
35
+
26
36
  it 'should recognize env specific settings per file' do
27
37
  config_file 'with_envs.yml'
28
38
  settings.foo.should == 'test'
@@ -138,13 +138,13 @@ describe Sinatra::ContentFor do
138
138
  render(inner, :passes_values).should == "<i>1</i>2"
139
139
  end
140
140
  end
141
-
141
+
142
142
  describe "with content_for? in Ruby" do
143
- it 'renders block if key is set' do
143
+ it 'renders block if key is set' do
144
144
  content_for(:foo) { "foot" }
145
145
  render(inner, :footer).should == "foot"
146
146
  end
147
-
147
+
148
148
  it 'does not render a block if different key' do
149
149
  content_for(:different_key) { "foot" }
150
150
  render(inner, :footer).should be_empty
@@ -154,11 +154,11 @@ describe Sinatra::Cookies do
154
154
  end.should be_nil
155
155
  end
156
156
 
157
- it 'expiers existing cookies' do
157
+ it 'expires existing cookies' do
158
158
  cookie_route("foo=bar") do
159
159
  cookies.clear
160
160
  response['Set-Cookie']
161
- end.should include("foo=; expires=Thu, 01-Jan-1970 00:00:00 GMT")
161
+ end.should include("foo=;", "expires=", "1970 00:00:00")
162
162
  end
163
163
  end
164
164
 
@@ -185,16 +185,32 @@ describe Sinatra::Cookies do
185
185
  it 'removes response cookies from cookies hash' do
186
186
  cookie_route do
187
187
  cookies['foo'] = 'bar'
188
- cookies.clear
188
+ cookies.delete 'foo'
189
189
  cookies['foo']
190
190
  end.should be_nil
191
191
  end
192
192
 
193
- it 'expiers existing cookies' do
193
+ it 'expires existing cookies' do
194
194
  cookie_route("foo=bar") do
195
195
  cookies.delete 'foo'
196
196
  response['Set-Cookie']
197
- end.should include("foo=; expires=Thu, 01-Jan-1970 00:00:00 GMT")
197
+ end.should include("foo=;", "expires=", "1970 00:00:00")
198
+ end
199
+
200
+ it 'honours the app cookie_options' do
201
+ @cookie_app.class_eval do
202
+ set :cookie_options, {
203
+ :path => '/foo',
204
+ :domain => 'bar.com',
205
+ :secure => true,
206
+ :httponly => true
207
+ }
208
+ end
209
+ cookie_header = cookie_route("foo=bar") do
210
+ cookies.delete 'foo'
211
+ response['Set-Cookie']
212
+ end
213
+ cookie_header.should include("path=/foo;", "domain=bar.com;", "secure;", "HttpOnly")
198
214
  end
199
215
 
200
216
  it 'does not touch other cookies' do
@@ -466,7 +482,11 @@ describe Sinatra::Cookies do
466
482
  end
467
483
 
468
484
  it 'raises an exception if key does not exist' do
469
- error = RUBY_VERSION >= '1.9' ? KeyError : IndexError
485
+ error = if defined? JRUBY_VERSION
486
+ IndexError
487
+ else
488
+ RUBY_VERSION >= '1.9' ? KeyError : IndexError
489
+ end
470
490
  expect { cookies.fetch('foo') }.to raise_exception(error)
471
491
  end
472
492
 
@@ -1,4 +1,6 @@
1
1
  require 'backports'
2
+ require 'multi_json'
3
+
2
4
  require_relative 'spec_helper'
3
5
  require_relative 'okjson'
4
6
 
@@ -41,8 +43,8 @@ describe Sinatra::JSON do
41
43
  end
42
44
 
43
45
  it "encodes objects to json out of the box" do
44
- mock_app { get('/') { json :foo => [1, 'bar'] } }
45
- results_in 'foo' => [1, 'bar']
46
+ mock_app { get('/') { json :foo => [1, 'bar', nil] } }
47
+ results_in 'foo' => [1, 'bar', nil]
46
48
  end
47
49
 
48
50
  it "sets the content type to 'application/json'" do
@@ -107,7 +109,7 @@ describe Sinatra::JSON do
107
109
  get('/').body.should == '42'
108
110
  end
109
111
 
110
- describe('Yajl') { it_should_behave_like "a json encoder", "yajl", "Yajl::Encoder" }
112
+ describe('Yajl') { it_should_behave_like "a json encoder", "yajl", "Yajl::Encoder" } unless defined? JRUBY_VERSION
111
113
  describe('JSON') { it_should_behave_like "a json encoder", "json", "::JSON" }
112
114
  describe('OkJson') { it_should_behave_like "a json encoder", nil, "OkJson" }
113
115
  describe('to_json') { it_should_behave_like "a json encoder", "json", ":to_json" }
@@ -2,25 +2,23 @@ require 'backports'
2
2
  require_relative 'spec_helper'
3
3
 
4
4
  describe Sinatra::MultiRoute do
5
- before do
6
- count = 0
5
+
6
+ it 'does not break normal routing' do
7
7
  mock_app do
8
- set(:some_condition) { |_| count += 1 }
9
8
  register Sinatra::MultiRoute
10
9
  get('/') { 'normal' }
11
- get('/foo', '/bar', :some_condition => true) { 'paths' }
12
- route('PUT', 'POST', '/') { 'verb' }
13
- route(:get, '/baz') { 'symbol as verb' }
14
10
  end
15
- @count = count
16
- end
17
11
 
18
- it 'does still allow normal routing' do
19
12
  get('/').should be_ok
20
13
  body.should be == 'normal'
21
14
  end
22
15
 
23
- it 'supports multpile routes' do
16
+ it 'supports multiple routes' do
17
+ mock_app do
18
+ register Sinatra::MultiRoute
19
+ get('/foo', '/bar') { 'paths' }
20
+ end
21
+
24
22
  get('/foo').should be_ok
25
23
  body.should be == 'paths'
26
24
  get('/bar').should be_ok
@@ -28,10 +26,22 @@ describe Sinatra::MultiRoute do
28
26
  end
29
27
 
30
28
  it 'triggers conditions' do
31
- @count.should be == 4
29
+ count = 0
30
+ mock_app do
31
+ register Sinatra::MultiRoute
32
+ set(:some_condition) { |_| count += 1 }
33
+ get('/foo', '/bar', :some_condition => true) { 'paths' }
34
+ end
35
+
36
+ count.should be == 4
32
37
  end
33
38
 
34
- it 'supports multpile verbs' do
39
+ it 'supports multiple verbs' do
40
+ mock_app do
41
+ register Sinatra::MultiRoute
42
+ route('PUT', 'POST', '/') { 'verb' }
43
+ end
44
+
35
45
  post('/').should be_ok
36
46
  body.should be == 'verb'
37
47
  put('/').should be_ok
@@ -39,7 +49,12 @@ describe Sinatra::MultiRoute do
39
49
  end
40
50
 
41
51
  it 'takes symbols as verbs' do
52
+ mock_app do
53
+ register Sinatra::MultiRoute
54
+ route(:get, '/baz') { 'symbol as verb' }
55
+ end
56
+
42
57
  get('/baz').should be_ok
43
58
  body.should be == 'symbol as verb'
44
59
  end
45
- end
60
+ end