adamwiggins-sinatra 0.8.9 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/AUTHORS +8 -7
  2. data/CHANGES +211 -1
  3. data/LICENSE +1 -1
  4. data/README.rdoc +183 -139
  5. data/Rakefile +20 -81
  6. data/lib/sinatra.rb +5 -1
  7. data/lib/sinatra/base.rb +569 -278
  8. data/lib/sinatra/main.rb +12 -25
  9. data/lib/sinatra/showexceptions.rb +303 -0
  10. data/sinatra.gemspec +20 -44
  11. data/test/base_test.rb +140 -52
  12. data/test/builder_test.rb +14 -17
  13. data/test/contest.rb +64 -0
  14. data/test/erb_test.rb +42 -16
  15. data/test/extensions_test.rb +100 -0
  16. data/test/filter_test.rb +85 -13
  17. data/test/haml_test.rb +39 -21
  18. data/test/helper.rb +76 -0
  19. data/test/helpers_test.rb +219 -84
  20. data/test/mapped_error_test.rb +168 -146
  21. data/test/middleware_test.rb +22 -17
  22. data/test/options_test.rb +323 -54
  23. data/test/render_backtrace_test.rb +145 -0
  24. data/test/request_test.rb +28 -6
  25. data/test/response_test.rb +42 -0
  26. data/test/result_test.rb +27 -21
  27. data/test/route_added_hook_test.rb +59 -0
  28. data/test/routing_test.rb +558 -77
  29. data/test/sass_test.rb +52 -13
  30. data/test/server_test.rb +47 -0
  31. data/test/sinatra_test.rb +3 -5
  32. data/test/static_test.rb +57 -30
  33. data/test/templates_test.rb +74 -25
  34. data/test/views/error.builder +3 -0
  35. data/test/views/error.erb +3 -0
  36. data/test/views/error.haml +3 -0
  37. data/test/views/error.sass +2 -0
  38. data/test/views/foo/hello.test +1 -0
  39. metadata +50 -46
  40. data/compat/app_test.rb +0 -300
  41. data/compat/application_test.rb +0 -334
  42. data/compat/builder_test.rb +0 -101
  43. data/compat/custom_error_test.rb +0 -62
  44. data/compat/erb_test.rb +0 -136
  45. data/compat/events_test.rb +0 -75
  46. data/compat/filter_test.rb +0 -30
  47. data/compat/haml_test.rb +0 -233
  48. data/compat/helper.rb +0 -21
  49. data/compat/mapped_error_test.rb +0 -72
  50. data/compat/pipeline_test.rb +0 -71
  51. data/compat/public/foo.xml +0 -1
  52. data/compat/sass_test.rb +0 -57
  53. data/compat/sessions_test.rb +0 -39
  54. data/compat/streaming_test.rb +0 -121
  55. data/compat/sym_params_test.rb +0 -19
  56. data/compat/template_test.rb +0 -30
  57. data/compat/use_in_file_templates_test.rb +0 -47
  58. data/compat/views/foo.builder +0 -1
  59. data/compat/views/foo.erb +0 -1
  60. data/compat/views/foo.haml +0 -1
  61. data/compat/views/foo.sass +0 -2
  62. data/compat/views/foo_layout.erb +0 -2
  63. data/compat/views/foo_layout.haml +0 -2
  64. data/compat/views/layout_test/foo.builder +0 -1
  65. data/compat/views/layout_test/foo.erb +0 -1
  66. data/compat/views/layout_test/foo.haml +0 -1
  67. data/compat/views/layout_test/foo.sass +0 -2
  68. data/compat/views/layout_test/layout.builder +0 -3
  69. data/compat/views/layout_test/layout.erb +0 -1
  70. data/compat/views/layout_test/layout.haml +0 -1
  71. data/compat/views/layout_test/layout.sass +0 -2
  72. data/compat/views/no_layout/no_layout.builder +0 -1
  73. data/compat/views/no_layout/no_layout.haml +0 -1
  74. data/lib/sinatra/compat.rb +0 -239
  75. data/lib/sinatra/test.rb +0 -112
  76. data/lib/sinatra/test/rspec.rb +0 -2
  77. data/lib/sinatra/test/spec.rb +0 -2
  78. data/lib/sinatra/test/unit.rb +0 -11
  79. data/test/reload_test.rb +0 -65
@@ -1,48 +1,35 @@
1
1
  require 'sinatra/base'
2
2
 
3
3
  module Sinatra
4
- class Default < Base
5
- set :app_file, lambda {
6
- ignore = [
7
- /lib\/sinatra.*\.rb$/, # all sinatra code
8
- /\(.*\)/, # generated code
9
- /custom_require\.rb$/ # rubygems require hacks
10
- ]
11
- path =
12
- caller.map{ |line| line.split(':', 2).first }.find do |file|
13
- next if ignore.any? { |pattern| file =~ pattern }
14
- file
15
- end
16
- path || $0
17
- }.call
4
+ class Application < Base
5
+
6
+ # we assume that the first file that requires 'sinatra' is the
7
+ # app_file. all other path related options are calculated based
8
+ # on this path by default.
9
+ set :app_file, caller_files.first || $0
18
10
 
19
11
  set :run, Proc.new { $0 == app_file }
20
- set :reload, Proc.new{ app_file? && development? }
21
12
 
22
13
  if run? && ARGV.any?
23
14
  require 'optparse'
24
15
  OptionParser.new { |op|
25
- op.on('-x') { set :mutex, true }
16
+ op.on('-x') { set :lock, true }
26
17
  op.on('-e env') { |val| set :environment, val.to_sym }
27
18
  op.on('-s server') { |val| set :server, val }
28
19
  op.on('-p port') { |val| set :port, val.to_i }
29
20
  }.parse!(ARGV.dup)
30
21
  end
22
+
23
+ at_exit do
24
+ raise $! if $!
25
+ run! if run?
26
+ end
31
27
  end
32
28
  end
33
29
 
34
30
  include Sinatra::Delegator
35
31
 
36
- def helpers(&block)
37
- Sinatra::Application.send :class_eval, &block
38
- end
39
-
40
32
  def mime(ext, type)
41
33
  ext = ".#{ext}" unless ext.to_s[0] == ?.
42
34
  Rack::Mime::MIME_TYPES[ext.to_s] = type
43
35
  end
44
-
45
- at_exit do
46
- raise $! if $!
47
- Sinatra::Application.run! if Sinatra::Application.run?
48
- end
@@ -0,0 +1,303 @@
1
+ require 'rack/showexceptions'
2
+
3
+ module Sinatra
4
+ class ShowExceptions < Rack::ShowExceptions
5
+ def initialize(app)
6
+ @app = app
7
+ @template = ERB.new(TEMPLATE)
8
+ end
9
+
10
+ def frame_class(frame)
11
+ if frame.filename =~ /lib\/sinatra.*\.rb/
12
+ "framework"
13
+ elsif (defined?(Gem) && frame.filename.include?(Gem.dir)) ||
14
+ frame.filename =~ /\/bin\/(\w+)$/
15
+ "system"
16
+ else
17
+ "app"
18
+ end
19
+ end
20
+
21
+ TEMPLATE = <<HTML
22
+ <!DOCTYPE html>
23
+ <html>
24
+ <head>
25
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
26
+ <title><%=h exception.class %> at <%=h path %></title>
27
+
28
+ <script type="text/javascript">
29
+ //<!--
30
+ function toggle(id) {
31
+ var pre = document.getElementById("pre-" + id);
32
+ var post = document.getElementById("post-" + id);
33
+ var context = document.getElementById("context-" + id);
34
+
35
+ if (pre.style.display == 'block') {
36
+ pre.style.display = 'none';
37
+ post.style.display = 'none';
38
+ context.style.background = "none";
39
+ } else {
40
+ pre.style.display = 'block';
41
+ post.style.display = 'block';
42
+ context.style.background = "#fffed9";
43
+ }
44
+ }
45
+
46
+ function toggleBacktrace(){
47
+ var bt = document.getElementById("backtrace");
48
+ var toggler = document.getElementById("expando");
49
+
50
+ if (bt.className == 'condensed') {
51
+ bt.className = 'expanded';
52
+ toggler.innerHTML = "(condense)";
53
+ } else {
54
+ bt.className = 'condensed';
55
+ toggler.innerHTML = "(expand)";
56
+ }
57
+ }
58
+ //-->
59
+ </script>
60
+
61
+ <style type="text/css" media="screen">
62
+ * {margin: 0; padding: 0; border: 0; outline: 0;}
63
+ div.clear {clear: both;}
64
+ body {background: #EEEEEE; margin: 0; padding: 0;
65
+ font-family: 'Lucida Grande', 'Lucida Sans Unicode',
66
+ 'Garuda';}
67
+ code {font-family: 'Lucida Console', monospace;
68
+ font-size: 12px;}
69
+ li {height: 18px;}
70
+ ul {list-style: none; margin: 0; padding: 0;}
71
+ ol:hover {cursor: pointer;}
72
+ ol li {white-space: pre;}
73
+ #explanation {font-size: 12px; color: #666666;
74
+ margin: 20px 0 0 100px;}
75
+ /* WRAP */
76
+ #wrap {width: 860px; background: #FFFFFF; margin: 0 auto;
77
+ padding: 30px 50px 20px 50px;
78
+ border-left: 1px solid #DDDDDD;
79
+ border-right: 1px solid #DDDDDD;}
80
+ /* HEADER */
81
+ #header {margin: 0 auto 25px auto;}
82
+ #header img {float: left;}
83
+ #header #summary {float: left; margin: 12px 0 0 20px; width:520px;
84
+ font-family: 'Lucida Grande', 'Lucida Sans Unicode';}
85
+ h1 {margin: 0; font-size: 36px; color: #981919;}
86
+ h2 {margin: 0; font-size: 22px; color: #333333;}
87
+ #header ul {margin: 0; font-size: 12px; color: #666666;}
88
+ #header ul li strong{color: #444444;}
89
+ #header ul li {display: inline; padding: 0 10px;}
90
+ #header ul li.first {padding-left: 0;}
91
+ #header ul li.last {border: 0; padding-right: 0;}
92
+ /* BODY */
93
+ #backtrace,
94
+ #get,
95
+ #post,
96
+ #cookies,
97
+ #rack {width: 860px; margin: 0 auto 10px auto;}
98
+ p#nav {float: right; font-size: 14px;}
99
+ /* BACKTRACE */
100
+ a#expando {float: left; padding-left: 5px; color: #666666;
101
+ font-size: 14px; text-decoration: none; cursor: pointer;}
102
+ a#expando:hover {text-decoration: underline;}
103
+ h3 {float: left; width: 100px; margin-bottom: 10px;
104
+ color: #981919; font-size: 14px; font-weight: bold;}
105
+ #nav a {color: #666666; text-decoration: none; padding: 0 5px;}
106
+ #backtrace li.frame-info {background: #f7f7f7; padding-left: 10px;
107
+ font-size: 12px; color: #333333;}
108
+ #backtrace ul {list-style-position: outside; border: 1px solid #E9E9E9;
109
+ border-bottom: 0;}
110
+ #backtrace ol {width: 808px; margin-left: 50px;
111
+ font: 10px 'Lucida Console', monospace; color: #666666;}
112
+ #backtrace ol li {border: 0; border-left: 1px solid #E9E9E9;
113
+ padding: 2px 0;}
114
+ #backtrace ol code {font-size: 10px; color: #555555; padding-left: 5px;}
115
+ #backtrace-ul li {border-bottom: 1px solid #E9E9E9; height: auto;
116
+ padding: 3px 0;}
117
+ #backtrace-ul .code {padding: 6px 0 4px 0;}
118
+ #backtrace.condensed .system,
119
+ #backtrace.condensed .framework {display:none;}
120
+ /* REQUEST DATA */
121
+ p.no-data {padding-top: 2px; font-size: 12px; color: #666666;}
122
+ table.req {width: 760px; text-align: left; font-size: 12px;
123
+ color: #666666; padding: 0; border-spacing: 0;
124
+ border: 1px solid #EEEEEE; border-bottom: 0;
125
+ border-left: 0;}
126
+ table.req tr th {padding: 2px 10px; font-weight: bold;
127
+ background: #F7F7F7; border-bottom: 1px solid #EEEEEE;
128
+ border-left: 1px solid #EEEEEE;}
129
+ table.req tr td {padding: 2px 20px 2px 10px;
130
+ border-bottom: 1px solid #EEEEEE;
131
+ border-left: 1px solid #EEEEEE;}
132
+ /* HIDE PRE/POST CODE AT START */
133
+ .pre-context,
134
+ .post-context {display: none;}
135
+ </style>
136
+ </head>
137
+ <body>
138
+ <div id="wrap">
139
+ <div id="header">
140
+ <img src="/__sinatra__/500.png" alt="application error" />
141
+ <div id="summary">
142
+ <h1><strong><%=h exception.class %></strong> at <strong><%=h path %>
143
+ </strong></h1>
144
+ <h2><%=h exception.message %></h2>
145
+ <ul>
146
+ <li class="first"><strong>file:</strong> <code>
147
+ <%=h frames.first.filename.split("/").last %></code></li>
148
+ <li><strong>location:</strong> <code><%=h frames.first.function %>
149
+ </code></li>
150
+ <li class="last"><strong>line:
151
+ </strong> <%=h frames.first.lineno %></li>
152
+ </ul>
153
+ </div>
154
+ <div class="clear"></div>
155
+ </div>
156
+
157
+ <div id="backtrace" class='condensed'>
158
+ <h3>BACKTRACE</h3>
159
+ <p><a href="#" id="expando"
160
+ onclick="toggleBacktrace(); return false">(expand)</a></p>
161
+ <p id="nav"><strong>JUMP TO:</strong>
162
+ <a href="#get-info">GET</a>
163
+ <a href="#post-info">POST</a>
164
+ <a href="#cookie-info">COOKIES</a>
165
+ <a href="#env-info">ENV</a>
166
+ </p>
167
+ <div class="clear"></div>
168
+
169
+ <ul id="backtrace-ul">
170
+
171
+ <% id = 1 %>
172
+ <% frames.each do |frame| %>
173
+ <% if frame.context_line && frame.context_line != "#" %>
174
+
175
+ <li class="frame-info <%= frame_class(frame) %>">
176
+ <code><%=h frame.filename %></code> in
177
+ <code><strong><%=h frame.function %></strong></code>
178
+ </li>
179
+
180
+ <li class="code <%= frame_class(frame) %>">
181
+ <% if frame.pre_context %>
182
+ <ol start="<%=h frame.pre_context_lineno + 1 %>"
183
+ class="pre-context" id="pre-<%= id %>"
184
+ onclick="toggle(<%= id %>);">
185
+ <% frame.pre_context.each do |line| %>
186
+ <li class="pre-context-line"><code><%=h line %></code></li>
187
+ <% end %>
188
+ </ol>
189
+ <% end %>
190
+
191
+ <ol start="<%= frame.lineno %>" class="context" id="<%= id %>"
192
+ onclick="toggle(<%= id %>);">
193
+ <li class="context-line" id="context-<%= id %>"><code><%=
194
+ h frame.context_line %></code></li>
195
+ </ol>
196
+
197
+ <% if frame.post_context %>
198
+ <ol start="<%=h frame.lineno + 1 %>" class="post-context"
199
+ id="post-<%= id %>" onclick="toggle(<%= id %>);">
200
+ <% frame.post_context.each do |line| %>
201
+ <li class="post-context-line"><code><%=h line %></code></li>
202
+ <% end %>
203
+ </ol>
204
+ <% end %>
205
+ <div class="clear"></div>
206
+ </li>
207
+
208
+ <% end %>
209
+
210
+ <% id += 1 %>
211
+ <% end %>
212
+
213
+ </ul>
214
+ </div> <!-- /BACKTRACE -->
215
+
216
+ <div id="get">
217
+ <h3 id="get-info">GET</h3>
218
+ <% unless req.GET.empty? %>
219
+ <table class="req">
220
+ <tr>
221
+ <th>Variable</th>
222
+ <th>Value</th>
223
+ </tr>
224
+ <% req.GET.sort_by { |k, v| k.to_s }.each { |key, val| %>
225
+ <tr>
226
+ <td><%=h key %></td>
227
+ <td class="code"><div><%=h val.inspect %></div></td>
228
+ </tr>
229
+ <% } %>
230
+ </table>
231
+ <% else %>
232
+ <p class="no-data">No GET data.</p>
233
+ <% end %>
234
+ <div class="clear"></div>
235
+ </div> <!-- /GET -->
236
+
237
+ <div id="post">
238
+ <h3 id="post-info">POST</h3>
239
+ <% unless req.POST.empty? %>
240
+ <table class="req">
241
+ <tr>
242
+ <th>Variable</th>
243
+ <th>Value</th>
244
+ </tr>
245
+ <% req.POST.sort_by { |k, v| k.to_s }.each { |key, val| %>
246
+ <tr>
247
+ <td><%=h key %></td>
248
+ <td class="code"><div><%=h val.inspect %></div></td>
249
+ </tr>
250
+ <% } %>
251
+ </table>
252
+ <% else %>
253
+ <p class="no-data">No POST data.</p>
254
+ <% end %>
255
+ <div class="clear"></div>
256
+ </div> <!-- /POST -->
257
+
258
+ <div id="cookies">
259
+ <h3 id="cookie-info">COOKIES</h3>
260
+ <% unless req.cookies.empty? %>
261
+ <table class="req">
262
+ <tr>
263
+ <th>Variable</th>
264
+ <th>Value</th>
265
+ </tr>
266
+ <% req.cookies.each { |key, val| %>
267
+ <tr>
268
+ <td><%=h key %></td>
269
+ <td class="code"><div><%=h val.inspect %></div></td>
270
+ </tr>
271
+ <% } %>
272
+ </table>
273
+ <% else %>
274
+ <p class="no-data">No cookie data.</p>
275
+ <% end %>
276
+ <div class="clear"></div>
277
+ </div> <!-- /COOKIES -->
278
+
279
+ <div id="rack">
280
+ <h3 id="env-info">Rack ENV</h3>
281
+ <table class="req">
282
+ <tr>
283
+ <th>Variable</th>
284
+ <th>Value</th>
285
+ </tr>
286
+ <% env.sort_by { |k, v| k.to_s }.each { |key, val| %>
287
+ <tr>
288
+ <td><%=h key %></td>
289
+ <td class="code"><div><%=h val %></div></td>
290
+ </tr>
291
+ <% } %>
292
+ </table>
293
+ <div class="clear"></div>
294
+ </div> <!-- /RACK ENV -->
295
+
296
+ <p id="explanation">You're seeing this error because you use you have
297
+ enabled the <code>show_exceptions</code> option.</p>
298
+ </div> <!-- /WRAP -->
299
+ </body>
300
+ </html>
301
+ HTML
302
+ end
303
+ end
@@ -3,13 +3,14 @@ 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 = '0.8.9'
7
- s.date = '2009-01-13'
6
+ s.version = '0.10.1'
7
+ s.date = '2009-06-07'
8
8
 
9
9
  s.description = "Classy web-development dressed in a DSL"
10
10
  s.summary = "Classy web-development dressed in a DSL"
11
11
 
12
- s.authors = ["Blake Mizerany"]
12
+ s.authors = ["Blake Mizerany", "Ryan Tomayko", "Simon Rozet"]
13
+ s.email = "sinatrarb@googlegroups.com"
13
14
 
14
15
  # = MANIFEST =
15
16
  s.files = %w[
@@ -18,69 +19,42 @@ Gem::Specification.new do |s|
18
19
  LICENSE
19
20
  README.rdoc
20
21
  Rakefile
21
- compat/app_test.rb
22
- compat/application_test.rb
23
- compat/builder_test.rb
24
- compat/custom_error_test.rb
25
- compat/erb_test.rb
26
- compat/events_test.rb
27
- compat/filter_test.rb
28
- compat/haml_test.rb
29
- compat/helper.rb
30
- compat/mapped_error_test.rb
31
- compat/pipeline_test.rb
32
- compat/public/foo.xml
33
- compat/sass_test.rb
34
- compat/sessions_test.rb
35
- compat/streaming_test.rb
36
- compat/sym_params_test.rb
37
- compat/template_test.rb
38
- compat/use_in_file_templates_test.rb
39
- compat/views/foo.builder
40
- compat/views/foo.erb
41
- compat/views/foo.haml
42
- compat/views/foo.sass
43
- compat/views/foo_layout.erb
44
- compat/views/foo_layout.haml
45
- compat/views/layout_test/foo.builder
46
- compat/views/layout_test/foo.erb
47
- compat/views/layout_test/foo.haml
48
- compat/views/layout_test/foo.sass
49
- compat/views/layout_test/layout.builder
50
- compat/views/layout_test/layout.erb
51
- compat/views/layout_test/layout.haml
52
- compat/views/layout_test/layout.sass
53
- compat/views/no_layout/no_layout.builder
54
- compat/views/no_layout/no_layout.haml
55
22
  lib/sinatra.rb
56
23
  lib/sinatra/base.rb
57
- lib/sinatra/compat.rb
58
24
  lib/sinatra/images/404.png
59
25
  lib/sinatra/images/500.png
60
26
  lib/sinatra/main.rb
61
- lib/sinatra/test.rb
62
- lib/sinatra/test/rspec.rb
63
- lib/sinatra/test/spec.rb
64
- lib/sinatra/test/unit.rb
27
+ lib/sinatra/showexceptions.rb
65
28
  sinatra.gemspec
66
29
  test/base_test.rb
67
30
  test/builder_test.rb
31
+ test/contest.rb
68
32
  test/data/reload_app_file.rb
69
33
  test/erb_test.rb
34
+ test/extensions_test.rb
70
35
  test/filter_test.rb
71
36
  test/haml_test.rb
37
+ test/helper.rb
72
38
  test/helpers_test.rb
73
39
  test/mapped_error_test.rb
74
40
  test/middleware_test.rb
75
41
  test/options_test.rb
76
- test/reload_test.rb
42
+ test/render_backtrace_test.rb
77
43
  test/request_test.rb
44
+ test/response_test.rb
78
45
  test/result_test.rb
46
+ test/route_added_hook_test.rb
79
47
  test/routing_test.rb
80
48
  test/sass_test.rb
49
+ test/server_test.rb
81
50
  test/sinatra_test.rb
82
51
  test/static_test.rb
83
52
  test/templates_test.rb
53
+ test/views/error.builder
54
+ test/views/error.erb
55
+ test/views/error.haml
56
+ test/views/error.sass
57
+ test/views/foo/hello.test
84
58
  test/views/hello.builder
85
59
  test/views/hello.erb
86
60
  test/views/hello.haml
@@ -96,7 +70,9 @@ Gem::Specification.new do |s|
96
70
  s.test_files = s.files.select {|path| path =~ /^test\/.*_test.rb/}
97
71
 
98
72
  s.extra_rdoc_files = %w[README.rdoc LICENSE]
99
- s.add_dependency 'rack', '>= 0.9.0'
73
+ s.add_dependency 'rack', '>= 1.0'
74
+ s.add_development_dependency 'shotgun', '>= 0.3', '< 1.0'
75
+ s.add_development_dependency 'rack-test', '>= 0.3.0'
100
76
 
101
77
  s.has_rdoc = true
102
78
  s.homepage = "http://sinatra.rubyforge.org"