jellyfish 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/CHANGES.md +23 -0
  2. data/Gemfile +7 -0
  3. data/README.md +2 -2
  4. data/example/config.ru +11 -0
  5. data/jellyfish.gemspec +48 -3
  6. data/lib/jellyfish.rb +21 -25
  7. data/lib/jellyfish/test.rb +22 -0
  8. data/lib/jellyfish/version.rb +1 -1
  9. data/sinatra/builder_test.rb +95 -0
  10. data/sinatra/coffee_test.rb +92 -0
  11. data/sinatra/contest.rb +98 -0
  12. data/sinatra/creole_test.rb +65 -0
  13. data/sinatra/delegator_test.rb +162 -0
  14. data/sinatra/encoding_test.rb +20 -0
  15. data/sinatra/erb_test.rb +104 -0
  16. data/sinatra/extensions_test.rb +100 -0
  17. data/sinatra/filter_test.rb +428 -0
  18. data/sinatra/haml_test.rb +101 -0
  19. data/sinatra/helper.rb +123 -0
  20. data/sinatra/helpers_test.rb +1783 -0
  21. data/sinatra/integration/app.rb +62 -0
  22. data/sinatra/integration_helper.rb +214 -0
  23. data/sinatra/integration_test.rb +85 -0
  24. data/sinatra/less_test.rb +67 -0
  25. data/sinatra/liquid_test.rb +59 -0
  26. data/sinatra/mapped_error_test.rb +259 -0
  27. data/sinatra/markaby_test.rb +80 -0
  28. data/sinatra/markdown_test.rb +81 -0
  29. data/sinatra/middleware_test.rb +68 -0
  30. data/sinatra/nokogiri_test.rb +69 -0
  31. data/sinatra/rack_test.rb +45 -0
  32. data/sinatra/radius_test.rb +59 -0
  33. data/sinatra/rdoc_test.rb +66 -0
  34. data/sinatra/readme_test.rb +136 -0
  35. data/sinatra/request_test.rb +45 -0
  36. data/sinatra/response_test.rb +61 -0
  37. data/sinatra/result_test.rb +98 -0
  38. data/sinatra/route_added_hook_test.rb +59 -0
  39. data/sinatra/routing_test.rb +1104 -0
  40. data/sinatra/sass_test.rb +116 -0
  41. data/sinatra/scss_test.rb +89 -0
  42. data/sinatra/server_test.rb +48 -0
  43. data/sinatra/settings_test.rb +538 -0
  44. data/sinatra/sinatra_test.rb +17 -0
  45. data/sinatra/slim_test.rb +88 -0
  46. data/sinatra/static_test.rb +178 -0
  47. data/sinatra/streaming_test.rb +140 -0
  48. data/sinatra/templates_test.rb +298 -0
  49. data/sinatra/textile_test.rb +65 -0
  50. data/test/sinatra/test_base.rb +123 -0
  51. metadata +48 -3
@@ -0,0 +1,259 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class FooError < RuntimeError
4
+ end
5
+
6
+ class FooNotFound < Sinatra::NotFound
7
+ end
8
+
9
+ class FooSpecialError < RuntimeError
10
+ def code; 501 end
11
+ end
12
+
13
+ class MappedErrorTest < Test::Unit::TestCase
14
+ def test_default
15
+ assert true
16
+ end
17
+
18
+ describe 'Exception Mappings' do
19
+ it 'invokes handlers registered with ::error when raised' do
20
+ mock_app {
21
+ set :raise_errors, false
22
+ error(FooError) { 'Foo!' }
23
+ get '/' do
24
+ raise FooError
25
+ end
26
+ }
27
+ get '/'
28
+ assert_equal 500, status
29
+ assert_equal 'Foo!', body
30
+ end
31
+
32
+ it 'passes the exception object to the error handler' do
33
+ mock_app do
34
+ set :raise_errors, false
35
+ error(FooError) { |e| assert_equal(FooError, e.class) }
36
+ get('/') { raise FooError }
37
+ end
38
+ get('/')
39
+ end
40
+
41
+ it 'uses the Exception handler if no matching handler found' do
42
+ mock_app {
43
+ set :raise_errors, false
44
+ error(Exception) { 'Exception!' }
45
+ get '/' do
46
+ raise FooError
47
+ end
48
+ }
49
+
50
+ get '/'
51
+ assert_equal 500, status
52
+ assert_equal 'Exception!', body
53
+ end
54
+
55
+ it 'walks down inheritance chain for errors' do
56
+ mock_app {
57
+ set :raise_errors, false
58
+ error(RuntimeError) { 'Exception!' }
59
+ get '/' do
60
+ raise FooError
61
+ end
62
+ }
63
+
64
+ get '/'
65
+ assert_equal 500, status
66
+ assert_equal 'Exception!', body
67
+ end
68
+
69
+ it 'favors subclass handler over superclass handler if available' do
70
+ mock_app {
71
+ set :raise_errors, false
72
+ error(Exception) { 'Exception!' }
73
+ error(FooError) { 'FooError!' }
74
+ error(RuntimeError) { 'Exception!' }
75
+ get '/' do
76
+ raise FooError
77
+ end
78
+ }
79
+
80
+ get '/'
81
+ assert_equal 500, status
82
+ assert_equal 'FooError!', body
83
+ end
84
+
85
+ it "sets env['sinatra.error'] to the rescued exception" do
86
+ mock_app {
87
+ set :raise_errors, false
88
+ error(FooError) {
89
+ assert env.include?('sinatra.error')
90
+ assert env['sinatra.error'].kind_of?(FooError)
91
+ 'looks good'
92
+ }
93
+ get '/' do
94
+ raise FooError
95
+ end
96
+ }
97
+ get '/'
98
+ assert_equal 'looks good', body
99
+ end
100
+
101
+ it "raises errors from the app when raise_errors set and no handler defined" do
102
+ mock_app {
103
+ set :raise_errors, true
104
+ get '/' do
105
+ raise FooError
106
+ end
107
+ }
108
+ assert_raise(FooError) { get '/' }
109
+ end
110
+
111
+ it "calls error handlers before raising errors even when raise_errors is set" do
112
+ mock_app {
113
+ set :raise_errors, true
114
+ error(FooError) { "she's there." }
115
+ get '/' do
116
+ raise FooError
117
+ end
118
+ }
119
+ assert_nothing_raised { get '/' }
120
+ assert_equal 500, status
121
+ end
122
+
123
+ it "never raises Sinatra::NotFound beyond the application" do
124
+ mock_app(Sinatra::Application) { get('/') { raise Sinatra::NotFound }}
125
+ assert_nothing_raised { get '/' }
126
+ assert_equal 404, status
127
+ end
128
+
129
+ it "cascades for subclasses of Sinatra::NotFound" do
130
+ mock_app {
131
+ set :raise_errors, true
132
+ error(FooNotFound) { "foo! not found." }
133
+ get '/' do
134
+ raise FooNotFound
135
+ end
136
+ }
137
+ assert_nothing_raised { get '/' }
138
+ assert_equal 404, status
139
+ assert_equal 'foo! not found.', body
140
+ end
141
+
142
+ it 'has a not_found method for backwards compatibility' do
143
+ mock_app {
144
+ not_found do
145
+ "Lost, are we?"
146
+ end
147
+ }
148
+
149
+ get '/test'
150
+ assert_equal 404, status
151
+ assert_equal "Lost, are we?", body
152
+ end
153
+
154
+ it 'inherits error mappings from base class' do
155
+ base = Class.new(Sinatra::Base)
156
+ base.error(FooError) { 'base class' }
157
+
158
+ mock_app(base) {
159
+ set :raise_errors, false
160
+ get '/' do
161
+ raise FooError
162
+ end
163
+ }
164
+
165
+ get '/'
166
+ assert_equal 'base class', body
167
+ end
168
+
169
+ it 'overrides error mappings in base class' do
170
+ base = Class.new(Sinatra::Base)
171
+ base.error(FooError) { 'base class' }
172
+
173
+ mock_app(base) {
174
+ set :raise_errors, false
175
+ error(FooError) { 'subclass' }
176
+ get '/' do
177
+ raise FooError
178
+ end
179
+ }
180
+
181
+ get '/'
182
+ assert_equal 'subclass', body
183
+ end
184
+
185
+ it 'honors Exception#code if present' do
186
+ mock_app do
187
+ set :raise_errors, false
188
+ error(501) { 'Foo!' }
189
+ get('/') { raise FooSpecialError }
190
+ end
191
+ get '/'
192
+ assert_equal 501, status
193
+ assert_equal 'Foo!', body
194
+ end
195
+ end
196
+
197
+ describe 'Custom Error Pages' do
198
+ it 'allows numeric status code mappings to be registered with ::error' do
199
+ mock_app {
200
+ set :raise_errors, false
201
+ error(500) { 'Foo!' }
202
+ get '/' do
203
+ [500, {}, 'Internal Foo Error']
204
+ end
205
+ }
206
+ get '/'
207
+ assert_equal 500, status
208
+ assert_equal 'Foo!', body
209
+ end
210
+
211
+ it 'allows ranges of status code mappings to be registered with :error' do
212
+ mock_app {
213
+ set :raise_errors, false
214
+ error(500..550) { "Error: #{response.status}" }
215
+ get '/' do
216
+ [507, {}, 'A very special error']
217
+ end
218
+ }
219
+ get '/'
220
+ assert_equal 507, status
221
+ assert_equal 'Error: 507', body
222
+ end
223
+
224
+ it 'allows passing more than one range' do
225
+ mock_app {
226
+ set :raise_errors, false
227
+ error(409..411, 503..509) { "Error: #{response.status}" }
228
+ get '/' do
229
+ [507, {}, 'A very special error']
230
+ end
231
+ }
232
+ get '/'
233
+ assert_equal 507, status
234
+ assert_equal 'Error: 507', body
235
+ end
236
+
237
+ class FooError < RuntimeError
238
+ end
239
+
240
+ it 'runs after exception mappings and overwrites body' do
241
+ mock_app {
242
+ set :raise_errors, false
243
+ error FooError do
244
+ response.status = 502
245
+ 'from exception mapping'
246
+ end
247
+ error(500) { 'from 500 handler' }
248
+ error(502) { 'from custom error page' }
249
+
250
+ get '/' do
251
+ raise FooError
252
+ end
253
+ }
254
+ get '/'
255
+ assert_equal 502, status
256
+ assert_equal 'from custom error page', body
257
+ end
258
+ end
259
+ end
@@ -0,0 +1,80 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ begin
4
+ require 'markaby'
5
+
6
+ class MarkabyTest < Test::Unit::TestCase
7
+ def markaby_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 markaby strings' do
16
+ markaby_app { markaby 'h1 "Hiya"' }
17
+ assert ok?
18
+ assert_equal "<h1>Hiya</h1>", body
19
+ end
20
+
21
+ it 'renders .markaby files in views path' do
22
+ markaby_app { markaby :hello }
23
+ assert ok?
24
+ assert_equal "<h1>Hello From Markaby</h1>", body
25
+ end
26
+
27
+ it "renders with inline layouts" do
28
+ mock_app do
29
+ layout { 'h1 { text "THIS. IS. "; yield }' }
30
+ get('/') { markaby 'em "SPARTA"' }
31
+ end
32
+ get '/'
33
+ assert ok?
34
+ assert_equal "<h1>THIS. IS. <em>SPARTA</em></h1>", body
35
+ end
36
+
37
+ it "renders with file layouts" do
38
+ markaby_app { markaby 'text "Hello World"', :layout => :layout2 }
39
+ assert ok?
40
+ assert_equal "<h1>Markaby Layout!</h1><p>Hello World</p>", body
41
+ end
42
+
43
+ it 'renders inline markaby blocks' do
44
+ markaby_app { markaby { h1 'Hiya' } }
45
+ assert ok?
46
+ assert_equal "<h1>Hiya</h1>", body
47
+ end
48
+
49
+ it 'renders inline markaby blocks with inline layouts' do
50
+ markaby_app do
51
+ settings.layout { 'h1 { text "THIS. IS. "; yield }' }
52
+ markaby { em 'SPARTA' }
53
+ end
54
+ assert ok?
55
+ assert_equal "<h1>THIS. IS. <em>SPARTA</em></h1>", body
56
+ end
57
+
58
+ it 'renders inline markaby blocks with file layouts' do
59
+ markaby_app { markaby(:layout => :layout2) { text "Hello World" } }
60
+ assert ok?
61
+ assert_equal "<h1>Markaby Layout!</h1><p>Hello World</p>", body
62
+ end
63
+
64
+ it "raises error if template not found" do
65
+ mock_app { get('/') { markaby :no_such_template } }
66
+ assert_raise(Errno::ENOENT) { get('/') }
67
+ end
68
+
69
+ it "allows passing locals" do
70
+ markaby_app do
71
+ markaby 'text value', :locals => { :value => 'foo' }
72
+ end
73
+ assert ok?
74
+ assert_equal 'foo', body
75
+ end
76
+ end
77
+
78
+ rescue LoadError
79
+ warn "#{$!.to_s}: skipping markaby tests"
80
+ end
@@ -0,0 +1,81 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ MarkdownTest = proc do
4
+ def markdown_app(&block)
5
+ mock_app do
6
+ set :views, File.dirname(__FILE__) + '/views'
7
+ get '/', &block
8
+ end
9
+ get '/'
10
+ end
11
+
12
+ def setup
13
+ Tilt.prefer engine, 'markdown', 'mkd', 'md'
14
+ super
15
+ end
16
+
17
+ it 'uses the correct engine' do
18
+ assert_equal engine, Tilt[:md]
19
+ assert_equal engine, Tilt[:mkd]
20
+ assert_equal engine, Tilt[:markdown]
21
+ end
22
+
23
+ it 'renders inline markdown strings' do
24
+ markdown_app { markdown '# Hiya' }
25
+ assert ok?
26
+ assert_like "<h1>Hiya</h1>\n", body
27
+ end
28
+
29
+ it 'renders .markdown files in views path' do
30
+ markdown_app { markdown :hello }
31
+ assert ok?
32
+ assert_like "<h1>Hello From Markdown</h1>", body
33
+ end
34
+
35
+ it "raises error if template not found" do
36
+ mock_app { get('/') { markdown :no_such_template } }
37
+ assert_raise(Errno::ENOENT) { get('/') }
38
+ end
39
+
40
+ it "renders with inline layouts" do
41
+ mock_app do
42
+ layout { 'THIS. IS. #{yield.upcase}!' }
43
+ get('/') { markdown 'Sparta', :layout_engine => :str }
44
+ end
45
+ get '/'
46
+ assert ok?
47
+ assert_like 'THIS. IS. <P>SPARTA</P>!', body
48
+ end
49
+
50
+ it "renders with file layouts" do
51
+ markdown_app { markdown 'Hello World', :layout => :layout2, :layout_engine => :erb }
52
+ assert ok?
53
+ assert_body "ERB Layout!\n<p>Hello World</p>"
54
+ end
55
+
56
+ it "can be used in a nested fashion for partials and whatnot" do
57
+ mock_app do
58
+ template(:inner) { "hi" }
59
+ template(:outer) { "<outer><%= markdown :inner %></outer>" }
60
+ get '/' do
61
+ erb :outer
62
+ end
63
+ end
64
+
65
+ get '/'
66
+ assert ok?
67
+ assert_like '<outer><p>hi</p></outer>', body
68
+ end
69
+ end
70
+
71
+ # Will generate RDiscountTest, KramdownTest, etc.
72
+ Tilt.mappings['md'].each do |t|
73
+ begin
74
+ t.new { "" }
75
+ klass = Class.new(Test::Unit::TestCase) { define_method(:engine) { t }}
76
+ klass.class_eval(&MarkdownTest)
77
+ Object.const_set t.name[/[^:]+(?=Template$)/] << "Test", klass
78
+ rescue LoadError
79
+ warn "#{$!}: skipping markdown tests with #{t}"
80
+ end
81
+ end
@@ -0,0 +1,68 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class MiddlewareTest < Test::Unit::TestCase
4
+ setup do
5
+ @app = mock_app(Sinatra::Application) {
6
+ get '/*' do
7
+ response.headers['X-Tests'] = env['test.ran'].
8
+ map { |n| n.split('::').last }.
9
+ join(', ')
10
+ env['PATH_INFO']
11
+ end
12
+ }
13
+ end
14
+
15
+ class MockMiddleware < Struct.new(:app)
16
+ def call(env)
17
+ (env['test.ran'] ||= []) << self.class.to_s
18
+ app.call(env)
19
+ end
20
+ end
21
+
22
+ class UpcaseMiddleware < MockMiddleware
23
+ def call(env)
24
+ env['PATH_INFO'] = env['PATH_INFO'].upcase
25
+ super
26
+ end
27
+ end
28
+
29
+ it "is added with Sinatra::Application.use" do
30
+ @app.use UpcaseMiddleware
31
+ get '/hello-world'
32
+ assert ok?
33
+ assert_equal '/HELLO-WORLD', body
34
+ end
35
+
36
+ class DowncaseMiddleware < MockMiddleware
37
+ def call(env)
38
+ env['PATH_INFO'] = env['PATH_INFO'].downcase
39
+ super
40
+ end
41
+ end
42
+
43
+ it "runs in the order defined" do
44
+ @app.use UpcaseMiddleware
45
+ @app.use DowncaseMiddleware
46
+ get '/Foo'
47
+ assert_equal "/foo", body
48
+ assert_equal "UpcaseMiddleware, DowncaseMiddleware", response['X-Tests']
49
+ end
50
+
51
+ it "resets the prebuilt pipeline when new middleware is added" do
52
+ @app.use UpcaseMiddleware
53
+ get '/Foo'
54
+ assert_equal "/FOO", body
55
+ @app.use DowncaseMiddleware
56
+ get '/Foo'
57
+ assert_equal '/foo', body
58
+ assert_equal "UpcaseMiddleware, DowncaseMiddleware", response['X-Tests']
59
+ end
60
+
61
+ it "works when app is used as middleware" do
62
+ @app.use UpcaseMiddleware
63
+ @app = @app.new
64
+ get '/Foo'
65
+ assert_equal "/FOO", body
66
+ assert_equal "UpcaseMiddleware", response['X-Tests']
67
+ end
68
+ end