gentooboontoo-rack-bug 0.3.0.edge

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.
Files changed (92) hide show
  1. data/.gitignore +3 -0
  2. data/History.txt +46 -0
  3. data/MIT-LICENSE.txt +19 -0
  4. data/README.md +120 -0
  5. data/Rakefile +23 -0
  6. data/Thorfile +113 -0
  7. data/lib/rack/bug/autoloading.rb +25 -0
  8. data/lib/rack/bug/filtered_backtrace.rb +38 -0
  9. data/lib/rack/bug/options.rb +89 -0
  10. data/lib/rack/bug/panel.rb +50 -0
  11. data/lib/rack/bug/panel_app.rb +33 -0
  12. data/lib/rack/bug/panels/active_record_panel/activerecord_extensions.rb +18 -0
  13. data/lib/rack/bug/panels/active_record_panel.rb +45 -0
  14. data/lib/rack/bug/panels/cache_panel/dalli_extension.rb +16 -0
  15. data/lib/rack/bug/panels/cache_panel/memcache_extension.rb +129 -0
  16. data/lib/rack/bug/panels/cache_panel/panel_app.rb +48 -0
  17. data/lib/rack/bug/panels/cache_panel/stats.rb +97 -0
  18. data/lib/rack/bug/panels/cache_panel.rb +51 -0
  19. data/lib/rack/bug/panels/log_panel/logger_extension.rb +24 -0
  20. data/lib/rack/bug/panels/log_panel.rb +56 -0
  21. data/lib/rack/bug/panels/memory_panel.rb +27 -0
  22. data/lib/rack/bug/panels/mongo_panel/mongo_extension.rb +27 -0
  23. data/lib/rack/bug/panels/mongo_panel/stats.rb +48 -0
  24. data/lib/rack/bug/panels/mongo_panel.rb +44 -0
  25. data/lib/rack/bug/panels/rails_info_panel.rb +23 -0
  26. data/lib/rack/bug/panels/redis_panel/redis_extension.rb +28 -0
  27. data/lib/rack/bug/panels/redis_panel/stats.rb +52 -0
  28. data/lib/rack/bug/panels/redis_panel.rb +44 -0
  29. data/lib/rack/bug/panels/request_variables_panel.rb +52 -0
  30. data/lib/rack/bug/panels/sphinx_panel/sphinx_extension.rb +25 -0
  31. data/lib/rack/bug/panels/sphinx_panel/stats.rb +96 -0
  32. data/lib/rack/bug/panels/sphinx_panel.rb +44 -0
  33. data/lib/rack/bug/panels/sql_panel/panel_app.rb +37 -0
  34. data/lib/rack/bug/panels/sql_panel/query.rb +63 -0
  35. data/lib/rack/bug/panels/sql_panel/sql_extension.rb +11 -0
  36. data/lib/rack/bug/panels/sql_panel.rb +55 -0
  37. data/lib/rack/bug/panels/templates_panel/actionview_extension.rb +12 -0
  38. data/lib/rack/bug/panels/templates_panel/rendering.rb +67 -0
  39. data/lib/rack/bug/panels/templates_panel/trace.rb +34 -0
  40. data/lib/rack/bug/panels/templates_panel.rb +47 -0
  41. data/lib/rack/bug/panels/timer_panel.rb +40 -0
  42. data/lib/rack/bug/params_signature.rb +63 -0
  43. data/lib/rack/bug/public/__rack_bug__/bookmarklet.html +10 -0
  44. data/lib/rack/bug/public/__rack_bug__/bookmarklet.js +217 -0
  45. data/lib/rack/bug/public/__rack_bug__/bug.css +220 -0
  46. data/lib/rack/bug/public/__rack_bug__/bug.js +84 -0
  47. data/lib/rack/bug/public/__rack_bug__/jquery-1.3.2.js +4376 -0
  48. data/lib/rack/bug/public/__rack_bug__/jquery.tablesorter.min.js +1 -0
  49. data/lib/rack/bug/public/__rack_bug__/spinner.gif +0 -0
  50. data/lib/rack/bug/rack_static_bug_avoider.rb +16 -0
  51. data/lib/rack/bug/redirect_interceptor.rb +27 -0
  52. data/lib/rack/bug/render.rb +67 -0
  53. data/lib/rack/bug/toolbar.rb +64 -0
  54. data/lib/rack/bug/views/error.html.erb +16 -0
  55. data/lib/rack/bug/views/panels/active_record.html.erb +17 -0
  56. data/lib/rack/bug/views/panels/cache.html.erb +93 -0
  57. data/lib/rack/bug/views/panels/execute_sql.html.erb +38 -0
  58. data/lib/rack/bug/views/panels/explain_sql.html.erb +38 -0
  59. data/lib/rack/bug/views/panels/log.html.erb +21 -0
  60. data/lib/rack/bug/views/panels/mongo.html.erb +32 -0
  61. data/lib/rack/bug/views/panels/profile_sql.html.erb +38 -0
  62. data/lib/rack/bug/views/panels/rails_info.html.erb +19 -0
  63. data/lib/rack/bug/views/panels/redis.html.erb +46 -0
  64. data/lib/rack/bug/views/panels/request_variables.html.erb +29 -0
  65. data/lib/rack/bug/views/panels/sphinx.html.erb +32 -0
  66. data/lib/rack/bug/views/panels/sql.html.erb +41 -0
  67. data/lib/rack/bug/views/panels/templates.html.erb +7 -0
  68. data/lib/rack/bug/views/panels/timer.html.erb +19 -0
  69. data/lib/rack/bug/views/panels/view_cache.html.erb +19 -0
  70. data/lib/rack/bug/views/redirect.html.erb +16 -0
  71. data/lib/rack/bug/views/toolbar.html.erb +42 -0
  72. data/lib/rack/bug.rb +82 -0
  73. data/rack-bug.gemspec +155 -0
  74. data/spec/custom_matchers.rb +21 -0
  75. data/spec/fixtures/config.ru +8 -0
  76. data/spec/fixtures/dummy_panel.rb +2 -0
  77. data/spec/fixtures/sample_app.rb +46 -0
  78. data/spec/rack/bug/panels/active_record_panel_spec.rb +30 -0
  79. data/spec/rack/bug/panels/cache_panel_spec.rb +167 -0
  80. data/spec/rack/bug/panels/log_panel_spec.rb +43 -0
  81. data/spec/rack/bug/panels/memory_panel_spec.rb +22 -0
  82. data/spec/rack/bug/panels/mongo_panel_spec.rb +51 -0
  83. data/spec/rack/bug/panels/rails_info_panel_spec.rb +40 -0
  84. data/spec/rack/bug/panels/redis_panel_spec.rb +69 -0
  85. data/spec/rack/bug/panels/sql_panel_spec.rb +146 -0
  86. data/spec/rack/bug/panels/templates_panel_spec.rb +71 -0
  87. data/spec/rack/bug/panels/timer_panel_spec.rb +38 -0
  88. data/spec/rack/bug_spec.rb +137 -0
  89. data/spec/rcov.opts +1 -0
  90. data/spec/spec.opts +1 -0
  91. data/spec/spec_helper.rb +44 -0
  92. metadata +245 -0
@@ -0,0 +1,41 @@
1
+ <h3>SQL Queries</h3>
2
+ <table class="sortable">
3
+ <thead>
4
+ <tr>
5
+ <th class="time">Time&nbsp;(ms)</th>
6
+ <th class="query">Query</th>
7
+ <th class="backtrace"></th>
8
+ <th class="actions"></th>
9
+ </tr>
10
+ </thead>
11
+ <tbody>
12
+ <% i = 1 %>
13
+ <% queries.each do |query| %>
14
+ <tr>
15
+ <td><%= query.human_time %></td>
16
+ <td class="syntax">
17
+ <%= query.sql %>
18
+ <div class='opts'>
19
+ <% if query.has_backtrace? %>
20
+ <a href="#" class="reveal_backtrace">Show Backtrace</a>
21
+ <% end %>
22
+ <% if query.inspectable? && query.has_backtrace? %>
23
+ |
24
+ <% end %>
25
+ <% if query.inspectable? %>
26
+ <a href="/__rack_bug__/execute_sql?<%= signed_params("query" => query.sql, "time" => query.time) %>" class="remote_call">SELECT</a> |
27
+ <a href="/__rack_bug__/explain_sql?<%= signed_params("query" => query.sql, "time" => query.time) %>" class="remote_call">EXPLAIN</a> |
28
+ <a href="/__rack_bug__/profile_sql?<%= signed_params("query" => query.sql, "time" => query.time) %>" class="remote_call">Profile</a>
29
+ <% end %>
30
+ </div>
31
+ <ul style="display:none" class='backtrace'>
32
+ <% query.filtered_backtrace.each do |line| %>
33
+ <li><%=h line %></li>
34
+ <% end %>
35
+ </ul>
36
+ </td>
37
+ </tr>
38
+ <% i += 1 %>
39
+ <% end %>
40
+ </tbody>
41
+ </table>
@@ -0,0 +1,7 @@
1
+ <h3>Templates</h3>
2
+
3
+ <ul>
4
+ <% template_trace.root.children.each do |child| %>
5
+ <%= child.html %>
6
+ <% end %>
7
+ </ul>
@@ -0,0 +1,19 @@
1
+ <h3>Resource Usage</h3>
2
+ <table class="sortable">
3
+ <thead>
4
+ <tr>
5
+ <th>Key</th>
6
+ <th>Value</th>
7
+ </tr>
8
+ </thead>
9
+ <tbody>
10
+ <% i = 1 %>
11
+ <% measurements.each do |key, val| %>
12
+ <tr>
13
+ <td><%=h key %></td>
14
+ <td><%=h val %></td>
15
+ </tr>
16
+ <% i += 1 %>
17
+ <% end %>
18
+ </tbody>
19
+ </table>
@@ -0,0 +1,19 @@
1
+ <a class="back" href="">&laquo;&nbsp;Back</a>
2
+
3
+ <h3>Cache Read</h3>
4
+
5
+ <dl>
6
+ <dt>Key</dt>
7
+ <dd><pre><%=h key %></pre></dd>
8
+
9
+ <dt>Time</dt>
10
+ <dd><%=h "%.2f" % (0.0 * 1_000) %>ms</dd>
11
+ </dl>
12
+
13
+ <p>
14
+ <% if value.is_a?(String )%>
15
+ <%=h value %>
16
+ <% else %>
17
+ <%=h value.inspect %>
18
+ <% end %>
19
+ </p>
@@ -0,0 +1,16 @@
1
+ <html>
2
+ <head>
3
+ </head>
4
+ <body>
5
+ <h1>Redirect</h1>
6
+
7
+ <p>Location: <a href="<%= redirect_to %>"><%= redirect_to %></a></p>
8
+
9
+ <p class="notice">
10
+ Rack::Bug has intercepted a redirect to the above URL for debug viewing
11
+ purposes. You can click the above link to continue with the redirect as
12
+ normal. If you'd like to disable this feature, set the Rack::Bug
13
+ <code>internal_redirects</code> option to <code>false</code>.
14
+ </p>
15
+ </body>
16
+ </html>
@@ -0,0 +1,42 @@
1
+ <script type="text/javascript" charset="utf-8">
2
+ if (typeof jQuery == 'undefined') {
3
+ var jquery_url = '/__rack_bug__/jquery-1.3.2.js';
4
+ document.write(unescape('%3Cscript src="' + jquery_url + '" type="text/javascript"%3E%3C/script%3E'));
5
+ }
6
+ </script>
7
+ <script type="text/javascript" src="/__rack_bug__/jquery.tablesorter.min.js"></script>
8
+ <script type="text/javascript" src="/__rack_bug__/bug.js"></script>
9
+ <style type="text/css" media="screen">
10
+ @import url(/__rack_bug__/bug.css);
11
+ </style>
12
+
13
+ <div id="rack_bug" class="rb_top">
14
+ <div id="rack_bug_toolbar">
15
+ <ul class="panels">
16
+ <li id="rb_debug_button">Rack::Bug</li>
17
+
18
+ <% panels.each do |panel| %>
19
+ <li>
20
+ <% if panel.has_content? %>
21
+ <a href="#" class="<%= panel.name %>">
22
+ <%= panel.heading %>
23
+ </a>
24
+ <% else %>
25
+ <%= panel.heading %>
26
+ <% end %>
27
+ </li>
28
+ <% end %>
29
+ </ul>
30
+ </div>
31
+
32
+ <% panels.each do |panel| %>
33
+ <% if panel.has_content? %>
34
+ <div class="panel_content" id="<%= panel.name %>">
35
+ <a href="" class="rack_bug_close">Close</a>
36
+ <%= panel.content %>
37
+ </div>
38
+ <% end %>
39
+ <% end %>
40
+
41
+ <div id="rack_bug_debug_window" class="panel_content"></div>
42
+ </div>
data/lib/rack/bug.rb ADDED
@@ -0,0 +1,82 @@
1
+ require "ipaddr"
2
+ require "digest"
3
+ require "rack"
4
+ require "digest/sha1"
5
+ require "rack/bug/autoloading"
6
+
7
+ class Rack::Bug
8
+ include Options
9
+
10
+ VERSION = "0.3.0"
11
+
12
+ class SecurityError < StandardError
13
+ end
14
+
15
+ def self.enable
16
+ Thread.current["rack-bug.enabled"] = true
17
+ end
18
+
19
+ def self.disable
20
+ Thread.current["rack-bug.enabled"] = false
21
+ end
22
+
23
+ def self.enabled?
24
+ Thread.current["rack-bug.enabled"] == true
25
+ end
26
+
27
+ def initialize(app, options = {}, &block)
28
+ @app = asset_server(app)
29
+ initialize_options options
30
+ instance_eval(&block) if block_given?
31
+
32
+ @toolbar = Toolbar.new(RedirectInterceptor.new(@app))
33
+ end
34
+
35
+
36
+ def call(env)
37
+ env.replace @default_options.merge(env)
38
+ @env = env
39
+ @original_request = Rack::Request.new(@env)
40
+
41
+ if toolbar_requested? && ip_authorized? && password_authorized? && toolbar_xhr?
42
+ @toolbar.call(env)
43
+ else
44
+ @app.call(env)
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def toolbar_xhr?
51
+ !@original_request.xhr? || @original_request.path =~ /^\/__rack_bug__/
52
+ end
53
+
54
+ def asset_server(app)
55
+ RackStaticBugAvoider.new(app, Rack::Static.new(app, :urls => ["/__rack_bug__"], :root => public_path))
56
+ end
57
+
58
+ def public_path
59
+ ::File.expand_path(::File.dirname(__FILE__) + "/bug/public")
60
+ end
61
+
62
+ def toolbar_requested?
63
+ @original_request.cookies["rack_bug_enabled"]
64
+ end
65
+
66
+ def ip_authorized?
67
+ return true unless options["rack-bug.ip_masks"]
68
+
69
+ options["rack-bug.ip_masks"].any? do |ip_mask|
70
+ ip_mask.include?(IPAddr.new(@original_request.ip))
71
+ end
72
+ end
73
+
74
+ def password_authorized?
75
+ return true unless options["rack-bug.password"]
76
+
77
+ expected_sha = Digest::SHA1.hexdigest ["rack_bug", options["rack-bug.password"]].join(":")
78
+ actual_sha = @original_request.cookies["rack_bug_password"]
79
+
80
+ actual_sha == expected_sha
81
+ end
82
+ end
data/rack-bug.gemspec ADDED
@@ -0,0 +1,155 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{gentooboontoo-rack-bug}
5
+ s.version = "0.3.0.edge"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Bryan Helmkamp"]
9
+ s.date = %q{2012-02-15}
10
+ s.email = %q{bryan@brynary.com}
11
+ s.extra_rdoc_files = [
12
+ "README.md",
13
+ "MIT-LICENSE.txt"
14
+ ]
15
+ s.files = [
16
+ ".gitignore",
17
+ "History.txt",
18
+ "MIT-LICENSE.txt",
19
+ "README.md",
20
+ "Rakefile",
21
+ "Thorfile",
22
+ "lib/rack/bug.rb",
23
+ "lib/rack/bug/autoloading.rb",
24
+ "lib/rack/bug/filtered_backtrace.rb",
25
+ "lib/rack/bug/options.rb",
26
+ "lib/rack/bug/panel.rb",
27
+ "lib/rack/bug/panel_app.rb",
28
+ "lib/rack/bug/panels/active_record_panel.rb",
29
+ "lib/rack/bug/panels/active_record_panel/activerecord_extensions.rb",
30
+ "lib/rack/bug/panels/cache_panel.rb",
31
+ "lib/rack/bug/panels/cache_panel/dalli_extension.rb",
32
+ "lib/rack/bug/panels/cache_panel/memcache_extension.rb",
33
+ "lib/rack/bug/panels/cache_panel/panel_app.rb",
34
+ "lib/rack/bug/panels/cache_panel/stats.rb",
35
+ "lib/rack/bug/panels/log_panel.rb",
36
+ "lib/rack/bug/panels/log_panel/logger_extension.rb",
37
+ "lib/rack/bug/panels/memory_panel.rb",
38
+ "lib/rack/bug/panels/mongo_panel.rb",
39
+ "lib/rack/bug/panels/mongo_panel/mongo_extension.rb",
40
+ "lib/rack/bug/panels/mongo_panel/stats.rb",
41
+ "lib/rack/bug/panels/rails_info_panel.rb",
42
+ "lib/rack/bug/panels/redis_panel.rb",
43
+ "lib/rack/bug/panels/redis_panel/redis_extension.rb",
44
+ "lib/rack/bug/panels/redis_panel/stats.rb",
45
+ "lib/rack/bug/panels/request_variables_panel.rb",
46
+ "lib/rack/bug/panels/sphinx_panel.rb",
47
+ "lib/rack/bug/panels/sphinx_panel/sphinx_extension.rb",
48
+ "lib/rack/bug/panels/sphinx_panel/stats.rb",
49
+ "lib/rack/bug/panels/sql_panel.rb",
50
+ "lib/rack/bug/panels/sql_panel/panel_app.rb",
51
+ "lib/rack/bug/panels/sql_panel/query.rb",
52
+ "lib/rack/bug/panels/sql_panel/sql_extension.rb",
53
+ "lib/rack/bug/panels/templates_panel.rb",
54
+ "lib/rack/bug/panels/templates_panel/actionview_extension.rb",
55
+ "lib/rack/bug/panels/templates_panel/rendering.rb",
56
+ "lib/rack/bug/panels/templates_panel/trace.rb",
57
+ "lib/rack/bug/panels/timer_panel.rb",
58
+ "lib/rack/bug/params_signature.rb",
59
+ "lib/rack/bug/public/__rack_bug__/bookmarklet.html",
60
+ "lib/rack/bug/public/__rack_bug__/bookmarklet.js",
61
+ "lib/rack/bug/public/__rack_bug__/bug.css",
62
+ "lib/rack/bug/public/__rack_bug__/bug.js",
63
+ "lib/rack/bug/public/__rack_bug__/jquery-1.3.2.js",
64
+ "lib/rack/bug/public/__rack_bug__/jquery.tablesorter.min.js",
65
+ "lib/rack/bug/public/__rack_bug__/spinner.gif",
66
+ "lib/rack/bug/rack_static_bug_avoider.rb",
67
+ "lib/rack/bug/redirect_interceptor.rb",
68
+ "lib/rack/bug/render.rb",
69
+ "lib/rack/bug/toolbar.rb",
70
+ "lib/rack/bug/views/error.html.erb",
71
+ "lib/rack/bug/views/panels/active_record.html.erb",
72
+ "lib/rack/bug/views/panels/cache.html.erb",
73
+ "lib/rack/bug/views/panels/execute_sql.html.erb",
74
+ "lib/rack/bug/views/panels/explain_sql.html.erb",
75
+ "lib/rack/bug/views/panels/log.html.erb",
76
+ "lib/rack/bug/views/panels/mongo.html.erb",
77
+ "lib/rack/bug/views/panels/profile_sql.html.erb",
78
+ "lib/rack/bug/views/panels/rails_info.html.erb",
79
+ "lib/rack/bug/views/panels/redis.html.erb",
80
+ "lib/rack/bug/views/panels/request_variables.html.erb",
81
+ "lib/rack/bug/views/panels/sphinx.html.erb",
82
+ "lib/rack/bug/views/panels/sql.html.erb",
83
+ "lib/rack/bug/views/panels/templates.html.erb",
84
+ "lib/rack/bug/views/panels/timer.html.erb",
85
+ "lib/rack/bug/views/panels/view_cache.html.erb",
86
+ "lib/rack/bug/views/redirect.html.erb",
87
+ "lib/rack/bug/views/toolbar.html.erb",
88
+ "rack-bug.gemspec",
89
+ "spec/custom_matchers.rb",
90
+ "spec/fixtures/config.ru",
91
+ "spec/fixtures/dummy_panel.rb",
92
+ "spec/fixtures/sample_app.rb",
93
+ "spec/rack/bug/panels/active_record_panel_spec.rb",
94
+ "spec/rack/bug/panels/cache_panel_spec.rb",
95
+ "spec/rack/bug/panels/log_panel_spec.rb",
96
+ "spec/rack/bug/panels/memory_panel_spec.rb",
97
+ "spec/rack/bug/panels/mongo_panel_spec.rb",
98
+ "spec/rack/bug/panels/rails_info_panel_spec.rb",
99
+ "spec/rack/bug/panels/redis_panel_spec.rb",
100
+ "spec/rack/bug/panels/sql_panel_spec.rb",
101
+ "spec/rack/bug/panels/templates_panel_spec.rb",
102
+ "spec/rack/bug/panels/timer_panel_spec.rb",
103
+ "spec/rack/bug_spec.rb",
104
+ "spec/rcov.opts",
105
+ "spec/spec.opts",
106
+ "spec/spec_helper.rb"
107
+ ]
108
+ s.homepage = %q{http://github.com/brynary/rack-bug}
109
+ s.require_paths = ["lib"]
110
+ s.rubyforge_project = %q{rack-bug}
111
+ s.rubygems_version = %q{1.3.7}
112
+ s.summary = %q{Debugging toolbar for Rack applications implemented as middleware}
113
+ s.test_files = [
114
+ "spec/custom_matchers.rb",
115
+ "spec/fixtures/dummy_panel.rb",
116
+ "spec/fixtures/sample_app.rb",
117
+ "spec/rack/bug/panels/active_record_panel_spec.rb",
118
+ "spec/rack/bug/panels/cache_panel_spec.rb",
119
+ "spec/rack/bug/panels/log_panel_spec.rb",
120
+ "spec/rack/bug/panels/memory_panel_spec.rb",
121
+ "spec/rack/bug/panels/mongo_panel_spec.rb",
122
+ "spec/rack/bug/panels/rails_info_panel_spec.rb",
123
+ "spec/rack/bug/panels/redis_panel_spec.rb",
124
+ "spec/rack/bug/panels/sql_panel_spec.rb",
125
+ "spec/rack/bug/panels/templates_panel_spec.rb",
126
+ "spec/rack/bug/panels/timer_panel_spec.rb",
127
+ "spec/rack/bug_spec.rb",
128
+ "spec/spec_helper.rb"
129
+ ]
130
+
131
+ if s.respond_to? :specification_version then
132
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
133
+ s.specification_version = 3
134
+
135
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
136
+ s.add_runtime_dependency(%q<rack>, [">= 1.0"])
137
+ s.add_development_dependency(%q<webrat>, [">= 0"])
138
+ s.add_development_dependency(%q<rspec>, [">= 0"])
139
+ s.add_development_dependency(%q<sinatra>, [">= 0"])
140
+ s.add_development_dependency(%q<git>, [">= 0"])
141
+ else
142
+ s.add_dependency(%q<rack>, [">= 1.0"])
143
+ s.add_dependency(%q<webrat>, [">= 0"])
144
+ s.add_dependency(%q<rspec>, [">= 0"])
145
+ s.add_dependency(%q<sinatra>, [">= 0"])
146
+ s.add_dependency(%q<git>, [">= 0"])
147
+ end
148
+ else
149
+ s.add_dependency(%q<rack>, [">= 1.0"])
150
+ s.add_dependency(%q<webrat>, [">= 0"])
151
+ s.add_dependency(%q<rspec>, [">= 0"])
152
+ s.add_dependency(%q<sinatra>, [">= 0"])
153
+ s.add_dependency(%q<git>, [">= 0"])
154
+ end
155
+ end
@@ -0,0 +1,21 @@
1
+ module CustomMatchers
2
+ def have_row(container, key, value = nil)
3
+ simple_matcher("contain row") do |response|
4
+ if value
5
+ response.should have_selector("#{container} tr", :content => key) do |row|
6
+ row.should contain(value)
7
+ end
8
+ else
9
+ response.should have_selector("#{container} tr", :content => key)
10
+ end
11
+ end
12
+ end
13
+
14
+ def have_heading(text)
15
+ simple_matcher("have heading") do |response|
16
+ response.should have_selector("#rack_bug_toolbar li") do |heading|
17
+ heading.should contain(text)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,8 @@
1
+ require "rubygems"
2
+
3
+ $LOAD_PATH.unshift File.dirname(__FILE__)
4
+ require "sample_app"
5
+
6
+ #Example usage, but moved inside sample app for easier testing
7
+ #use Rack::Bug, :password => "secret"
8
+ run SampleApp
@@ -0,0 +1,2 @@
1
+ class DummyPanel < Rack::Bug::Panel
2
+ end
@@ -0,0 +1,46 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../../lib'
2
+ require "rack/bug"
3
+
4
+ require "sinatra/base"
5
+ require 'logger'
6
+
7
+ RAILS_ENV = "development" unless defined?(RAILS_ENV)
8
+ log_to = RAILS_ENV == "test" ? StringIO.new : STDOUT
9
+ LOGGER = Logger.new(log_to)
10
+
11
+ class SampleApp < Sinatra::Base
12
+ use Rack::Bug#, :intercept_redirects => true, :password => 'secret'
13
+ set :environment, 'test'
14
+
15
+ configure :test do
16
+ set :raise_errors, true
17
+ end
18
+
19
+ get "/redirect" do
20
+ redirect "/"
21
+ end
22
+
23
+ get "/error" do
24
+ raise "Error!"
25
+ end
26
+
27
+ get "/" do
28
+ if params[:content_type]
29
+ headers["Content-Type"] = params[:content_type]
30
+ end
31
+ LOGGER.error "I am a log message"
32
+ <<-HTML
33
+ <html>
34
+ <head>
35
+ </head>
36
+ <body>
37
+ <p>Hello</p>
38
+ <p><a href="__rack_bug__/bookmarklet.html">Page with bookmarklet for enabling Rack::Bug</a></p>
39
+ <p><a href="/redirect">Page with a redirect - turn on intercept_redirects to see Rack::Bug catch it</a></p>
40
+ <p><a href="/error">Page with an error to check rack-bug not rescuing errors</a></p>
41
+ </body>
42
+ </html>
43
+ HTML
44
+ end
45
+
46
+ end
@@ -0,0 +1,30 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ class Rack::Bug
4
+ describe ActiveRecordPanel do
5
+ before do
6
+ ActiveRecordPanel.reset
7
+ rack_env "rack-bug.panel_classes", [ActiveRecordPanel]
8
+ end
9
+
10
+ describe "heading" do
11
+ it "displays the total number of instantiated AR objects" do
12
+ ActiveRecordPanel.record("User")
13
+ ActiveRecordPanel.record("Group")
14
+ response = get_via_rack "/"
15
+ response.should have_heading("2 AR Objects")
16
+ end
17
+ end
18
+
19
+ describe "content" do
20
+ it "displays the count of instantiated objects for each class" do
21
+ ActiveRecordPanel.record("User")
22
+ ActiveRecordPanel.record("User")
23
+ ActiveRecordPanel.record("Group")
24
+ response = get_via_rack "/"
25
+ response.should have_row("#active_record", "User", "2")
26
+ response.should have_row("#active_record", "Group", "1")
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,167 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ class Rack::Bug
4
+ describe CachePanel do
5
+ before do
6
+ CachePanel.reset
7
+ rack_env "rack-bug.panel_classes", [CachePanel]
8
+ unless defined?(Rails)
9
+ @added_rails = true
10
+ Object.const_set :Rails, Module.new
11
+ end
12
+ end
13
+
14
+ after do
15
+ Object.send :remove_const, :Rails if @added_rails
16
+ end
17
+
18
+ describe "heading" do
19
+ it "displays the total memcache time" do
20
+ response = get_via_rack "/"
21
+ response.should have_heading("Cache: 0.00ms")
22
+ end
23
+ end
24
+
25
+ describe "content" do
26
+ describe "usage table" do
27
+ it "displays the total number of memcache calls" do
28
+ CachePanel.record(:get, "user:1") { }
29
+ response = get_via_rack "/"
30
+
31
+ # This causes a bus error:
32
+ # response.should have_selector("th:content('Total Calls') + td", :content => "1")
33
+
34
+ response.should have_row("#cache_usage", "Total Calls", "1")
35
+ end
36
+
37
+ it "displays the total memcache time" do
38
+ response = get_via_rack "/"
39
+ response.should have_row("#cache_usage", "Total Time", "0.00ms")
40
+ end
41
+
42
+ it "dispays the number of memcache hits" do
43
+ CachePanel.record(:get, "user:1") { }
44
+ response = get_via_rack "/"
45
+ response.should have_row("#cache_usage", "Hits", "0")
46
+ end
47
+
48
+ it "displays the number of memcache misses" do
49
+ CachePanel.record(:get, "user:1") { }
50
+ response = get_via_rack "/"
51
+ response.should have_row("#cache_usage", "Misses", "1")
52
+ end
53
+
54
+ it "displays the number of memcache gets" do
55
+ CachePanel.record(:get, "user:1") { }
56
+ response = get_via_rack "/"
57
+ response.should have_row("#cache_usage", "gets", "1")
58
+ end
59
+
60
+ it "displays the number of memcache sets" do
61
+ CachePanel.record(:set, "user:1") { }
62
+ response = get_via_rack "/"
63
+ response.should have_row("#cache_usage", "sets", "1")
64
+ end
65
+
66
+ it "displays the number of memcache deletes" do
67
+ CachePanel.record(:delete, "user:1") { }
68
+ response = get_via_rack "/"
69
+ response.should have_row("#cache_usage", "deletes", "1")
70
+ end
71
+
72
+ it "displays the number of memcache get_multis" do
73
+ CachePanel.record(:get_multi, "user:1", "user:2") { }
74
+ response = get_via_rack "/"
75
+ response.should have_row("#cache_usage", "get_multis", "1")
76
+ end
77
+ end
78
+
79
+ describe "breakdown" do
80
+ it "displays each memcache operation" do
81
+ CachePanel.record(:get, "user:1") { }
82
+ response = get_via_rack "/"
83
+ response.should have_row("#cache_breakdown", "get")
84
+ end
85
+
86
+ it "displays the time for each memcache call" do
87
+ CachePanel.record(:get, "user:1") { }
88
+ response = get_via_rack "/"
89
+ response.should have_row("#cache_breakdown", "user:1", TIME_MS_REGEXP)
90
+ end
91
+
92
+ it "displays the keys for each memcache call" do
93
+ CachePanel.record(:get, "user:1") { }
94
+ response = get_via_rack "/"
95
+ response.should have_row("#cache_breakdown", "user:1", "get")
96
+ end
97
+ end
98
+ end
99
+
100
+ describe "expire_all" do
101
+ before do
102
+ rack_env "rack-bug.secret_key", 'abc'
103
+ end
104
+
105
+ it "expires the cache keys" do
106
+ Rails.stub!(:cache => mock("cache"))
107
+ Rails.cache.should_receive(:delete).with("user:1")
108
+ Rails.cache.should_receive(:delete).with("user:2")
109
+ Rails.cache.should_receive(:delete).with("user:3")
110
+ Rails.cache.should_receive(:delete).with("user:4")
111
+
112
+ get_via_rack "/__rack_bug__/delete_cache_list",
113
+ :keys_1 => "user:1", :keys_2 => "user:2", :keys_3 => "user:3", :keys_4 => "user:4",
114
+ :hash => "c367b76e0199c308862a3afd8fba32b8715e7976"
115
+ end
116
+
117
+ it "returns OK" do
118
+ Rails.stub!(:cache => mock("cache", :delete => nil))
119
+ response = get_via_rack "/__rack_bug__/delete_cache_list",
120
+ :keys_1 => "user:1", :keys_2 => "user:2", :keys_3 => "user:3", :keys_4 => "user:4",
121
+ :hash => "c367b76e0199c308862a3afd8fba32b8715e7976"
122
+ response.should contain("OK")
123
+ end
124
+ end
125
+
126
+ describe "expire" do
127
+ before do
128
+ rack_env "rack-bug.secret_key", 'abc'
129
+ end
130
+
131
+ it "expires the cache key" do
132
+ Rails.stub!(:cache => mock("cache"))
133
+ Rails.cache.should_receive(:delete).with("user:1")
134
+ get_via_rack "/__rack_bug__/delete_cache", :key => "user:1",
135
+ :hash => "f87215442d312d8e42cf51e6b66fc3eb3d59ac74"
136
+ end
137
+
138
+ it "returns OK" do
139
+ Rails.stub!(:cache => mock("cache", :delete => nil))
140
+ response = get_via_rack "/__rack_bug__/delete_cache", :key => "user:1",
141
+ :hash => "f87215442d312d8e42cf51e6b66fc3eb3d59ac74"
142
+ response.should contain("OK")
143
+ end
144
+ end
145
+
146
+ describe "view_cache" do
147
+ before do
148
+ rack_env "rack-bug.secret_key", 'abc'
149
+ end
150
+
151
+ it "renders the cache key" do
152
+ Rails.stub!(:cache => mock("cache", :read => "cache body"))
153
+ response = get_via_rack "/__rack_bug__/view_cache", :key => "user:1",
154
+ :hash => "f87215442d312d8e42cf51e6b66fc3eb3d59ac74"
155
+ response.should contain("cache body")
156
+ end
157
+
158
+ it "renders non-String cache values properly" do
159
+ Rails.stub!(:cache => mock("cache", :read => [1, 2]))
160
+ response = get_via_rack "/__rack_bug__/view_cache", :key => "user:1",
161
+ :hash => "f87215442d312d8e42cf51e6b66fc3eb3d59ac74"
162
+ response.should contain("[1, 2]")
163
+ end
164
+ end
165
+
166
+ end
167
+ end