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,43 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ class Rack::Bug
4
+ describe LogPanel do
5
+ before do
6
+ LogPanel.reset
7
+ rack_env "rack-bug.panel_classes", [LogPanel]
8
+ end
9
+
10
+ describe "heading" do
11
+ it "displays 'Log'" do
12
+ response = get_via_rack "/"
13
+ response.should have_heading("Log")
14
+ end
15
+ end
16
+
17
+ describe "content" do
18
+ it "displays recorded log lines" do
19
+ LogPanel.record("This is a logged message", 0)
20
+ response = get_via_rack "/"
21
+ response.should contain("This is a logged message")
22
+ response.should contain("DEBUG")
23
+ end
24
+ end
25
+
26
+ describe "Extended Logger" do
27
+ it "does still return true/false for #add if class Logger" do
28
+ #AS::BufferedLogger returns the added string, Logger returns true/false
29
+ LOGGER.add(0, "foo").should == true
30
+ end
31
+ end
32
+
33
+
34
+ describe "With no logger defined" do
35
+ it "does not err out" do
36
+ logger = LOGGER
37
+ Object.send :remove_const, :LOGGER
38
+ lambda{ load("rack/bug/panels/log_panel/logger_extension.rb") }.should_not raise_error
39
+ ::LOGGER = logger
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
3
+
4
+ class Rack::Bug
5
+ describe MemoryPanel do
6
+ before do
7
+ rack_env "rack-bug.panel_classes", [MemoryPanel]
8
+ end
9
+
10
+ describe "heading" do
11
+ it "displays the total memory" do
12
+ response = get_via_rack "/"
13
+ response.should have_heading(/\d+ KB total/)
14
+ end
15
+
16
+ it "displays the memory change during the request" do
17
+ response = get_via_rack "/"
18
+ response.should have_heading(/\d+ KB Δ/)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,51 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+ $LOADED_FEATURES << "mongo.rb" #avoid dependency on mongo
3
+
4
+ class Rack::Bug
5
+ describe MongoPanel do
6
+ before do
7
+ MongoPanel.reset
8
+ rack_env "rack-bug.panel_classes", [MongoPanel]
9
+ end
10
+
11
+ describe "heading" do
12
+ it "displays the total mongo time" do
13
+ response = get_via_rack "/"
14
+ response.should have_heading("Mongo: 0.00ms")
15
+ end
16
+ end
17
+
18
+ describe "content" do
19
+ describe "usage table" do
20
+ it "displays the total number of mongo calls" do
21
+ MongoPanel.record("db.user.user.find()") { }
22
+ response = get_via_rack "/"
23
+
24
+ # This causes a bus error:
25
+ # response.should have_selector("th:content('Total Calls') + td", :content => "1")
26
+
27
+ response.should have_row("#mongo_usage", "Total Calls", "1")
28
+ end
29
+
30
+ it "displays the total mongo time" do
31
+ response = get_via_rack "/"
32
+ response.should have_row("#mongo_usage", "Total Time", "0.00ms")
33
+ end
34
+ end
35
+
36
+ describe "breakdown" do
37
+ it "displays each mongo operation" do
38
+ MongoPanel.record("db.user.user.find()") { }
39
+ response = get_via_rack "/"
40
+ response.should have_row("#mongo_breakdown", "db.user.user.find()")
41
+ end
42
+
43
+ it "displays the time for mongo call" do
44
+ MongoPanel.record("db.user.user.find()") { }
45
+ response = get_via_rack "/"
46
+ response.should have_row("#mongo_breakdown", "db.user.user.find()", TIME_MS_REGEXP)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,40 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ class Rack::Bug
4
+ describe RailsInfoPanel do
5
+ before do
6
+ rack_env "rack-bug.panel_classes", [RailsInfoPanel]
7
+
8
+ unless defined?(Rails)
9
+ @added_rails = true
10
+ Object.const_set :Rails, Module.new
11
+ Rails::Info = Class.new do
12
+ def self.properties
13
+ []
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ after do
20
+ Object.send :remove_const, :Rails if @added_rails
21
+ end
22
+
23
+ describe "heading" do
24
+ it "displays the Rails version" do
25
+ Rails.stub!(:version => "v2.3.0")
26
+ response = get_via_rack "/"
27
+ response.should have_heading("Rails v2.3.0")
28
+ end
29
+ end
30
+
31
+ describe "content" do
32
+ it "displays the Rails::Info properties" do
33
+ Rails.stub!(:version => "v2.3.0")
34
+ Rails::Info.stub!(:properties => [["Name", "Value"]])
35
+ response = get_via_rack "/"
36
+ response.should have_row("#rails_info", "Name", "Value")
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,69 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+ $LOADED_FEATURES << "redis.rb" #avoid dependency on redis
3
+
4
+ class Rack::Bug
5
+ describe RedisPanel do
6
+ before do
7
+ RedisPanel.reset
8
+ rack_env "rack-bug.panel_classes", [RedisPanel]
9
+ end
10
+
11
+ describe "heading" do
12
+ it "displays the total redis time" do
13
+ response = get_via_rack "/"
14
+ response.should have_heading("Redis: 0.00ms")
15
+ end
16
+ end
17
+
18
+ describe "content" do
19
+ describe "usage table" do
20
+ it "displays the total number of redis calls" do
21
+ RedisPanel.record(["get, user:1"], Kernel.caller) { }
22
+ response = get_via_rack "/"
23
+
24
+ # This causes a bus error:
25
+ # response.should have_selector("th:content('Total Calls') + td", :content => "1")
26
+
27
+ response.should have_row("#redis_usage", "Total Calls", "1")
28
+ end
29
+
30
+ it "displays the total redis time" do
31
+ response = get_via_rack "/"
32
+ response.should have_row("#redis_usage", "Total Time", "0.00ms")
33
+ end
34
+ end
35
+
36
+ describe "breakdown" do
37
+ it "displays each redis operation" do
38
+ RedisPanel.record(["get, user:1"], Kernel.caller) { }
39
+ response = get_via_rack "/"
40
+ response.should have_row("#redis_breakdown", "get")
41
+ end
42
+
43
+ it "displays the time for redis call" do
44
+ RedisPanel.record(["get, user:1"], Kernel.caller) { }
45
+ response = get_via_rack "/"
46
+ response.should have_row("#redis_breakdown", "user:1", TIME_MS_REGEXP)
47
+ end
48
+
49
+ it "displays the arguments for each redis call" do
50
+ RedisPanel.record(["get, user:1"], Kernel.caller) { }
51
+ response = get_via_rack "/"
52
+ response.should have_row("#redis_breakdown", "user:1", "get")
53
+ end
54
+
55
+ it "displays a link to show the backtrace when it's available" do
56
+ RedisPanel.record(["get, user:1"], Kernel.caller) { }
57
+ response = get_via_rack "/"
58
+ response.should have_row("#redis_breakdown", "user:1", "Show Backtrace")
59
+ end
60
+
61
+ it "does not display a link to show the backtrace when it's not available" do
62
+ RedisPanel.record(["get, user:1"], []) { }
63
+ response = get_via_rack "/"
64
+ response.should_not contain("Show Backtrace")
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,146 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ class Rack::Bug
4
+ describe SQLPanel do
5
+ before do
6
+ SQLPanel.reset
7
+ rack_env "rack-bug.panel_classes", [SQLPanel]
8
+
9
+ unless defined?(ActiveRecord)
10
+ @added_rails = true
11
+ Object.const_set :ActiveRecord, Module.new
12
+ ActiveRecord.const_set :Base, Class.new
13
+ end
14
+ end
15
+
16
+ after do
17
+ Object.send :remove_const, :ActiveRecord if @added_active_record
18
+ end
19
+
20
+ describe "heading" do
21
+ it "displays the total SQL query count" do
22
+ SQLPanel.record("SELECT NOW();") { }
23
+ response = get_via_rack "/"
24
+ response.should have_heading("1 Queries")
25
+ end
26
+
27
+ it "displays the total SQL time" do
28
+ SQLPanel.record("SELECT NOW();") { }
29
+ response = get_via_rack "/"
30
+ response.should have_heading(/Queries \(\d+\.\d{2}ms\)/)
31
+ end
32
+ end
33
+
34
+ describe "content" do
35
+ it "displays each executed SQL query" do
36
+ SQLPanel.record("SELECT NOW();") { }
37
+ response = get_via_rack "/"
38
+ response.should have_row("#sql", "SELECT NOW();")
39
+ end
40
+
41
+ it "displays the time of each executed SQL query" do
42
+ SQLPanel.record("SELECT NOW();") { }
43
+ response = get_via_rack "/"
44
+ response.should have_row("#sql", "SELECT NOW();", TIME_MS_REGEXP)
45
+ end
46
+ end
47
+
48
+ def stub_result(results = [[]])
49
+ columns = results.first
50
+ fields = columns.map { |c| stub("field", :name => c) }
51
+ rows = results[1..-1]
52
+
53
+ result = stub("result", :fetch_fields => fields)
54
+ result.stub!(:each).and_yield(*rows)
55
+ return result
56
+ end
57
+
58
+ def expect_query(sql, results)
59
+ conn = stub("connection")
60
+ ActiveRecord::Base.stub!(:connection => conn)
61
+ conn.should_receive(:execute).with(sql).and_return(stub_result(results))
62
+ end
63
+
64
+ describe "execute_sql" do
65
+ it "displays the query results" do
66
+ rack_env "rack-bug.secret_key", "abc"
67
+ expect_query "SELECT username FROM users",
68
+ [["username"],
69
+ ["bryan"]]
70
+
71
+ response = get_via_rack "/__rack_bug__/execute_sql", {:query => "SELECT username FROM users",
72
+ :hash => "6f286f55b75716e5c91f16d77d09fa73b353ebc1"}, {:xhr => true}
73
+ response.should contain("SELECT username FROM users")
74
+ response.should be_ok
75
+ end
76
+
77
+ it "is forbidden when the hash is missing or wrong" do
78
+ rack_env "rack-bug.secret_key", 'abc'
79
+
80
+ lambda {
81
+ get_via_rack "/__rack_bug__/execute_sql", {:query => "SELECT username FROM users",
82
+ :hash => "foobar"}, {:xhr => true}
83
+ }.should raise_error(SecurityError)
84
+ end
85
+
86
+ it "is not available when the rack-bug.secret_key is nil" do
87
+ rack_env "rack-bug.secret_key", nil
88
+
89
+ lambda {
90
+ get_via_rack "/__rack_bug__/execute_sql", {:query => "SELECT username FROM users",
91
+ :hash => "6f286f55b75716e5c91f16d77d09fa73b353ebc1"}, {:xhr => true}
92
+ }.should raise_error(SecurityError)
93
+ end
94
+
95
+ it "is not available when the rack-bug.secret_key is an empty string" do
96
+ rack_env "rack-bug.secret_key", ""
97
+
98
+ lambda {
99
+ get_via_rack "/__rack_bug__/execute_sql", {:query => "SELECT username FROM users",
100
+ :hash => "6f286f55b75716e5c91f16d77d09fa73b353ebc1"}, {:xhr => true}
101
+ }.should raise_error(SecurityError)
102
+ end
103
+ end
104
+
105
+ describe "explain_sql" do
106
+ it "displays the query explain plan" do
107
+ rack_env "rack-bug.secret_key", "abc"
108
+ expect_query "EXPLAIN SELECT username FROM users",
109
+ [["table"],
110
+ ["users"]]
111
+
112
+ response = get_via_rack "/__rack_bug__/explain_sql", :query => "SELECT username FROM users",
113
+ :hash => "6f286f55b75716e5c91f16d77d09fa73b353ebc1"
114
+ response.should contain("SELECT username FROM users")
115
+ response.should be_ok
116
+ end
117
+
118
+ it "is forbidden when the hash is missing or wrong" do
119
+ rack_env "rack-bug.secret_key", 'abc'
120
+
121
+ lambda {
122
+ get_via_rack "/__rack_bug__/explain_sql", :query => "SELECT username FROM users",
123
+ :hash => "foobar"
124
+ }.should raise_error(SecurityError)
125
+ end
126
+
127
+ it "is not available when the rack-bug.secret_key is nil" do
128
+ rack_env "rack-bug.secret_key", nil
129
+
130
+ lambda {
131
+ get_via_rack "/__rack_bug__/explain_sql", :query => "SELECT username FROM users",
132
+ :hash => "6f286f55b75716e5c91f16d77d09fa73b353ebc1"
133
+ }.should raise_error(SecurityError)
134
+ end
135
+
136
+ it "is not available when the rack-bug.secret_key is an empty string" do
137
+ rack_env "rack-bug.secret_key", ""
138
+
139
+ lambda {
140
+ get_via_rack "/__rack_bug__/explain_sql", :query => "SELECT username FROM users",
141
+ :hash => "6f286f55b75716e5c91f16d77d09fa73b353ebc1"
142
+ }.should raise_error(SecurityError)
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,71 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ class Rack::Bug
4
+ describe TemplatesPanel do
5
+ before do
6
+ TemplatesPanel.reset
7
+ rack_env "rack-bug.panel_classes", [TemplatesPanel]
8
+ end
9
+
10
+ describe "heading" do
11
+ it "displays the total rendering time" do
12
+ response = get_via_rack "/"
13
+ response.should have_heading("Templates: 0.00ms")
14
+ end
15
+ end
16
+
17
+ describe "content" do
18
+ it "displays the template paths" do
19
+ TemplatesPanel.record("users/show") { }
20
+ response = get_via_rack "/"
21
+ response.should contain("users/show")
22
+ end
23
+
24
+ it "displays the template children" do
25
+ TemplatesPanel.record("users/show") do
26
+ TemplatesPanel.record("users/toolbar") { }
27
+ end
28
+
29
+ response = get_via_rack "/"
30
+ response.should have_selector("li", :content => "users/show") do |li|
31
+ li.should contain("users/toolbar")
32
+ end
33
+ end
34
+
35
+ context "for templates that rendered templates" do
36
+ it "displays the total time" do
37
+ TemplatesPanel.record("users/show") do
38
+ TemplatesPanel.record("users/toolbar") { }
39
+ end
40
+
41
+ response = get_via_rack "/"
42
+ response.should have_selector("li", :content => "users/show") do |li|
43
+ li.should contain(TIME_MS_REGEXP)
44
+ end
45
+ end
46
+
47
+ it "displays the exclusive time" do
48
+ TemplatesPanel.record("users/show") do
49
+ TemplatesPanel.record("users/toolbar") { }
50
+ end
51
+
52
+ response = get_via_rack "/"
53
+ response.should have_selector("li", :content => "users/show") do |li|
54
+ li.should contain(/\d\.\d{2} exclusive/)
55
+ end
56
+ end
57
+ end
58
+
59
+ context "for leaf templates" do
60
+ it "does not display the exclusive time" do
61
+ TemplatesPanel.record("users/show") { }
62
+
63
+ response = get_via_rack "/"
64
+ response.should contain("users/show") do |li|
65
+ li.should_not contain("exclusive")
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,38 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ class Rack::Bug
4
+ describe TimerPanel do
5
+ before do
6
+ rack_env "rack-bug.panel_classes", [TimerPanel]
7
+ end
8
+
9
+ describe "heading" do
10
+ it "displays the elapsed time" do
11
+ response = get_via_rack "/"
12
+ response.should have_heading(TIME_MS_REGEXP)
13
+ end
14
+ end
15
+
16
+ describe "content" do
17
+ it "displays the user CPU time" do
18
+ response = get_via_rack "/"
19
+ response.should have_row("#timer", "User CPU time", TIME_MS_REGEXP)
20
+ end
21
+
22
+ it "displays the system CPU time" do
23
+ response = get_via_rack "/"
24
+ response.should have_row("#timer", "System CPU time", TIME_MS_REGEXP)
25
+ end
26
+
27
+ it "displays the total CPU time" do
28
+ response = get_via_rack "/"
29
+ response.should have_row("#timer", "Total CPU time", TIME_MS_REGEXP)
30
+ end
31
+
32
+ it "displays the elapsed time" do
33
+ response = get_via_rack "/"
34
+ response.should have_row("#timer", "Elapsed time", TIME_MS_REGEXP)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,137 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Rack::Bug do
4
+ it "inserts the Rack::Bug toolbar" do
5
+ response = get "/"
6
+ response.should have_selector("div#rack_bug")
7
+ end
8
+
9
+ it "updates the Content-Length" do
10
+ response = get "/"
11
+ response["Content-Length"].should == response.body.size.to_s
12
+ end
13
+
14
+ it "serves the Rack::Bug assets under /__rack_bug__/" do
15
+ response = get "/__rack_bug__/bug.css"
16
+ response.should be_ok
17
+ end
18
+
19
+ it "modifies HTML responses with a charset" do
20
+ response = get "/", :content_type => "application/xhtml+xml; charset=utf-8"
21
+ response.should have_selector("div#rack_bug")
22
+ end
23
+
24
+ it "does not modify XMLHttpRequest responses" do
25
+ response = get "/", {}, { :xhr => true }
26
+ response.should_not have_selector("div#rack_bug")
27
+ end
28
+
29
+ it "modifies XHTML responses" do
30
+ response = get "/", :content_type => "application/xhtml+xml"
31
+ response.should have_selector("div#rack_bug")
32
+ end
33
+
34
+ it "does not modify non-HTML responses" do
35
+ response = get "/", :content_type => "text/csv"
36
+ response.should_not have_selector("div#rack_bug")
37
+ end
38
+
39
+ it "does not modify server errors" do
40
+ app.disable :raise_errors
41
+ response = get "/error"
42
+ app.enable :raise_errors
43
+ response.should_not have_selector("div#rack_bug")
44
+ end
45
+
46
+ context "redirected when not configured to intercept redirects" do
47
+ it "passes the redirect unmodified" do
48
+ response = get "/redirect"
49
+ response.status.should == 302
50
+ end
51
+
52
+ it "does not show the interception page" do
53
+ response = get "/redirect"
54
+ response.body.should_not contain("Location: /")
55
+ end
56
+
57
+ it "does not insert the toolbar" do
58
+ header 'cookie', ""
59
+ response = get "/redirect"
60
+ response.should_not have_selector("div#rack_bug")
61
+ end
62
+
63
+ it "does not insert the toolbar if even toolbar requested" do
64
+ response = get "/redirect"
65
+ response.should_not have_selector("div#rack_bug")
66
+ end
67
+ end
68
+
69
+ context "redirected when configured to intercept redirects" do
70
+ it "shows the interception page" do
71
+ response = get "/redirect", {}, "rack-bug.intercept_redirects" => true
72
+ response.should have_selector("div#rack_bug")
73
+ end
74
+
75
+ it "should provide a link to the target URL" do
76
+ response = get "/redirect", {}, "rack-bug.intercept_redirects" => true
77
+ response.should have_selector("a[href='/']")
78
+ end
79
+
80
+ it "inserts the toolbar if requested" do
81
+ response = get "/redirect", {}, "rack-bug.intercept_redirects" => true
82
+ response.should have_selector("div#rack_bug")
83
+ end
84
+
85
+ it "does not inserts the toolbar if not requested" do
86
+ header 'cookie', ""
87
+ response = get "/redirect", {}, "rack-bug.intercept_redirects" => true
88
+ response.should_not have_selector("div#rack_bug")
89
+ end
90
+ end
91
+
92
+ context "configured with an IP address restriction" do
93
+ before do
94
+ rack_env "rack-bug.ip_masks", [IPAddr.new("127.0.0.1/255.255.255.0")]
95
+ end
96
+
97
+ it "inserts the Rack::Bug toolbar when the IP matches" do
98
+ response = get_via_rack "/", {}, "REMOTE_ADDR" => "127.0.0.2"
99
+ response.should have_selector("div#rack_bug")
100
+ end
101
+
102
+ it "is disabled when the IP doesn't match" do
103
+ response = get_via_rack "/", {}, "REMOTE_ADDR" => "128.0.0.1"
104
+ response.should_not have_selector("div#rack_bug")
105
+ end
106
+
107
+ it "doesn't use any panels" do
108
+ DummyPanel.should_not_receive(:new)
109
+ rack_env "rack-bug.panel_classes", [DummyPanel]
110
+ get_via_rack "/", {}, "REMOTE_ADDR" => "128.0.0.1"
111
+ end
112
+ end
113
+
114
+ context "configured with a password" do
115
+ before do
116
+ rack_env "rack-bug.password", "secret"
117
+ end
118
+
119
+ it "inserts the Rack::Bug toolbar when the password matches" do
120
+ sha = "545049d1c5e2a6e0dfefd37f9a9e0beb95241935"
121
+ set_cookie ["rack_bug_enabled=1", "rack_bug_password=#{sha}"]
122
+ response = get_via_rack "/"
123
+ response.should have_selector("div#rack_bug")
124
+ end
125
+
126
+ it "is disabled when the password doesn't match" do
127
+ response = get_via_rack "/"
128
+ response.should_not have_selector("div#rack_bug")
129
+ end
130
+
131
+ it "doesn't use any panels" do
132
+ DummyPanel.should_not_receive(:new)
133
+ rack_env "rack-bug.panel_classes", [DummyPanel]
134
+ get_via_rack "/"
135
+ end
136
+ end
137
+ end
data/spec/rcov.opts ADDED
@@ -0,0 +1 @@
1
+ -x gems,spec\/
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,44 @@
1
+ require "rubygems"
2
+ require "spec"
3
+ require "webrat"
4
+ require "rack/test"
5
+
6
+ RAILS_ENV = "test"
7
+
8
+ $LOAD_PATH.unshift File.dirname(File.dirname(__FILE__)) + '/lib'
9
+ $LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))
10
+
11
+ require "rack/bug"
12
+ require "spec/fixtures/sample_app"
13
+ require "spec/fixtures/dummy_panel"
14
+ require "spec/custom_matchers"
15
+
16
+ Spec::Runner.configure do |config|
17
+ TIME_MS_REGEXP = /\d+\.\d{2}ms/
18
+
19
+ config.include Rack::Test::Methods
20
+ config.include Webrat::Matchers
21
+ config.include CustomMatchers
22
+
23
+ config.before do
24
+ # This allows specs to record data outside the request
25
+ Rack::Bug.enable
26
+
27
+ # Set the cookie that triggers Rack::Bug under normal conditions
28
+ set_cookie "rack_bug_enabled=1"
29
+ end
30
+
31
+ def app
32
+ SampleApp
33
+ end
34
+
35
+ def rack_env(key, value)
36
+ @rack_env ||= {}
37
+ @rack_env[key] = value
38
+ end
39
+
40
+ def get_via_rack(uri, params = {}, env = {}, &block)
41
+ env = env.merge(@rack_env) if @rack_env
42
+ get(uri, params, env, &block)
43
+ end
44
+ end