rack-insight 0.5.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.
Files changed (126) hide show
  1. data/.gitignore +13 -0
  2. data/.rspec +1 -0
  3. data/.simplecov +4 -0
  4. data/.travis.yml +8 -0
  5. data/CHANGELOG +58 -0
  6. data/Gemfile +3 -0
  7. data/Gemfile.lock +82 -0
  8. data/LICENSE +24 -0
  9. data/README.md +189 -0
  10. data/Rakefile +27 -0
  11. data/TODO +7 -0
  12. data/lib/rack-insight.rb +1 -0
  13. data/lib/rack/insight.rb +19 -0
  14. data/lib/rack/insight/app.rb +198 -0
  15. data/lib/rack/insight/config.rb +30 -0
  16. data/lib/rack/insight/database.rb +193 -0
  17. data/lib/rack/insight/enable-button.rb +43 -0
  18. data/lib/rack/insight/filtered_backtrace.rb +45 -0
  19. data/lib/rack/insight/instrumentation.rb +9 -0
  20. data/lib/rack/insight/instrumentation/backstage.rb +10 -0
  21. data/lib/rack/insight/instrumentation/client.rb +20 -0
  22. data/lib/rack/insight/instrumentation/instrument.rb +109 -0
  23. data/lib/rack/insight/instrumentation/package-definition.rb +58 -0
  24. data/lib/rack/insight/instrumentation/probe-definition.rb +20 -0
  25. data/lib/rack/insight/instrumentation/probe.rb +196 -0
  26. data/lib/rack/insight/instrumentation/setup.rb +32 -0
  27. data/lib/rack/insight/logger.rb +53 -0
  28. data/lib/rack/insight/options.rb +116 -0
  29. data/lib/rack/insight/panel.rb +135 -0
  30. data/lib/rack/insight/panel_app.rb +31 -0
  31. data/lib/rack/insight/panels-content.rb +22 -0
  32. data/lib/rack/insight/panels-header.rb +18 -0
  33. data/lib/rack/insight/panels/active_record_panel.rb +46 -0
  34. data/lib/rack/insight/panels/active_resource_panel.rb +48 -0
  35. data/lib/rack/insight/panels/active_resource_panel/query.rb +27 -0
  36. data/lib/rack/insight/panels/cache_panel.rb +68 -0
  37. data/lib/rack/insight/panels/cache_panel/panel_app.rb +46 -0
  38. data/lib/rack/insight/panels/cache_panel/stats.rb +90 -0
  39. data/lib/rack/insight/panels/log_panel.rb +53 -0
  40. data/lib/rack/insight/panels/memory_panel.rb +36 -0
  41. data/lib/rack/insight/panels/mongo_panel.rb +41 -0
  42. data/lib/rack/insight/panels/mongo_panel/mongo_extension.rb +24 -0
  43. data/lib/rack/insight/panels/mongo_panel/stats.rb +46 -0
  44. data/lib/rack/insight/panels/rails_info_panel.rb +19 -0
  45. data/lib/rack/insight/panels/redis_panel.rb +42 -0
  46. data/lib/rack/insight/panels/redis_panel/redis_extension.rb +23 -0
  47. data/lib/rack/insight/panels/redis_panel/stats.rb +50 -0
  48. data/lib/rack/insight/panels/request_variables_panel.rb +70 -0
  49. data/lib/rack/insight/panels/speedtracer_panel.rb +89 -0
  50. data/lib/rack/insight/panels/speedtracer_panel/profiling.rb +29 -0
  51. data/lib/rack/insight/panels/speedtracer_panel/trace-app.rb +52 -0
  52. data/lib/rack/insight/panels/speedtracer_panel/tracer.rb +213 -0
  53. data/lib/rack/insight/panels/sphinx_panel.rb +41 -0
  54. data/lib/rack/insight/panels/sphinx_panel/stats.rb +94 -0
  55. data/lib/rack/insight/panels/sql_panel.rb +53 -0
  56. data/lib/rack/insight/panels/sql_panel/panel_app.rb +37 -0
  57. data/lib/rack/insight/panels/sql_panel/query.rb +94 -0
  58. data/lib/rack/insight/panels/templates_panel.rb +58 -0
  59. data/lib/rack/insight/panels/templates_panel/rendering.rb +81 -0
  60. data/lib/rack/insight/panels/timer_panel.rb +40 -0
  61. data/lib/rack/insight/params_signature.rb +61 -0
  62. data/lib/rack/insight/path-filter.rb +23 -0
  63. data/lib/rack/insight/public/__insight__/bookmarklet.html +10 -0
  64. data/lib/rack/insight/public/__insight__/bookmarklet.js +223 -0
  65. data/lib/rack/insight/public/__insight__/insight.css +235 -0
  66. data/lib/rack/insight/public/__insight__/insight.js +127 -0
  67. data/lib/rack/insight/public/__insight__/jquery-1.3.2.js +4376 -0
  68. data/lib/rack/insight/public/__insight__/jquery.tablesorter.min.js +1 -0
  69. data/lib/rack/insight/public/__insight__/spinner.gif +0 -0
  70. data/lib/rack/insight/rack_static_bug_avoider.rb +16 -0
  71. data/lib/rack/insight/redirect_interceptor.rb +25 -0
  72. data/lib/rack/insight/render.rb +72 -0
  73. data/lib/rack/insight/request-recorder.rb +22 -0
  74. data/lib/rack/insight/rspec_matchers.rb +33 -0
  75. data/lib/rack/insight/toolbar.rb +69 -0
  76. data/lib/rack/insight/version.rb +7 -0
  77. data/lib/rack/insight/views/enable-button.html.erb +21 -0
  78. data/lib/rack/insight/views/error.html.erb +17 -0
  79. data/lib/rack/insight/views/headers_fragment.html.erb +20 -0
  80. data/lib/rack/insight/views/panels/active_record.html.erb +17 -0
  81. data/lib/rack/insight/views/panels/active_resource.html.erb +47 -0
  82. data/lib/rack/insight/views/panels/cache.html.erb +93 -0
  83. data/lib/rack/insight/views/panels/execute_sql.html.erb +32 -0
  84. data/lib/rack/insight/views/panels/explain_sql.html.erb +32 -0
  85. data/lib/rack/insight/views/panels/log.html.erb +21 -0
  86. data/lib/rack/insight/views/panels/mongo.html.erb +32 -0
  87. data/lib/rack/insight/views/panels/profile_sql.html.erb +32 -0
  88. data/lib/rack/insight/views/panels/rails_info.html.erb +19 -0
  89. data/lib/rack/insight/views/panels/redis.html.erb +46 -0
  90. data/lib/rack/insight/views/panels/request_variables.html.erb +25 -0
  91. data/lib/rack/insight/views/panels/speedtracer/serverevent.html.erb +10 -0
  92. data/lib/rack/insight/views/panels/speedtracer/servertrace.html.erb +12 -0
  93. data/lib/rack/insight/views/panels/speedtracer/traces.html.erb +18 -0
  94. data/lib/rack/insight/views/panels/sphinx.html.erb +32 -0
  95. data/lib/rack/insight/views/panels/sql.html.erb +43 -0
  96. data/lib/rack/insight/views/panels/templates.html.erb +6 -0
  97. data/lib/rack/insight/views/panels/timer.html.erb +19 -0
  98. data/lib/rack/insight/views/panels/view_cache.html.erb +19 -0
  99. data/lib/rack/insight/views/redirect.html.erb +16 -0
  100. data/lib/rack/insight/views/request_fragment.html.erb +25 -0
  101. data/lib/rack/insight/views/toolbar.html.erb +29 -0
  102. data/rack-insight.gemspec +40 -0
  103. data/spec/custom_matchers.rb +0 -0
  104. data/spec/fixtures/config.ru +8 -0
  105. data/spec/fixtures/dummy_panel.rb +2 -0
  106. data/spec/fixtures/sample_app.rb +72 -0
  107. data/spec/fixtures/star_trek_panel.rb +1 -0
  108. data/spec/insight_spec.rb +163 -0
  109. data/spec/instrumentation_spec.rb +188 -0
  110. data/spec/rack/insight/config_spec.rb +20 -0
  111. data/spec/rack/insight/panels/active_record_panel_spec.rb +43 -0
  112. data/spec/rack/insight/panels/active_resource_panel_spec.rb +40 -0
  113. data/spec/rack/insight/panels/cache_panel_spec.rb +178 -0
  114. data/spec/rack/insight/panels/log_panel_spec.rb +44 -0
  115. data/spec/rack/insight/panels/memory_panel_spec.rb +21 -0
  116. data/spec/rack/insight/panels/mongo_panel_spec_pending.rb +52 -0
  117. data/spec/rack/insight/panels/rails_info_panel_spec.rb +29 -0
  118. data/spec/rack/insight/panels/redis_panel_spec.rb +67 -0
  119. data/spec/rack/insight/panels/speedtracer_panel_spec.rb +86 -0
  120. data/spec/rack/insight/panels/sql_panel_spec.rb +146 -0
  121. data/spec/rack/insight/panels/templates_panel_spec.rb +86 -0
  122. data/spec/rack/insight/panels/timer_panel_spec.rb +38 -0
  123. data/spec/rcov.opts +1 -0
  124. data/spec/spec.opts +1 -0
  125. data/spec/spec_helper.rb +111 -0
  126. metadata +380 -0
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rack::Insight::Config do
4
+
5
+ context "configured with panel_load_paths" do
6
+ before(:each) do
7
+ Rack::Insight::Config.configure do |config|
8
+ # spec folder is in the load path during specs!
9
+ config[:panel_load_paths] << ['fixtures']
10
+ end
11
+ require 'fixtures/star_trek_panel'
12
+ reset_insight :panel_files => %w{star_trek_panel}
13
+ end
14
+ it "should use StarTrekPanel" do
15
+ app.insight_app.panel_classes.include?(StarTrekPanel).should be_true
16
+ get_via_rack "/"
17
+ end
18
+ end
19
+
20
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ module Rack::Insight
4
+ describe "ActiveRecordPanel" do
5
+ before do
6
+ mock_constant("ActiveRecord::Base")
7
+ reset_insight :panel_files => %w{active_record_panel}
8
+ end
9
+
10
+ def mock_model(name)
11
+ model = stub("model")
12
+ model.stub!(:name => name)
13
+ obj = stub(name)
14
+ obj.stub!(:base_class => model)
15
+ obj
16
+ end
17
+
18
+ describe "heading" do
19
+ it "displays the total number of instantiated AR objects" do
20
+ app.before_return do
21
+ mock_method_call("ActiveRecord::Base", "allocate", [], :class, mock_model("User"))
22
+ mock_method_call("ActiveRecord::Base", "allocate", [], :class, mock_model("Group"))
23
+ end
24
+
25
+ response = get_via_rack "/"
26
+ response.should have_heading("2 AR Objects")
27
+ end
28
+ end
29
+
30
+ describe "content" do
31
+ it "displays the count of instantiated objects for each class" do
32
+ app.before_return do
33
+ mock_method_call("ActiveRecord::Base", "allocate", [], :class, mock_model("User"))
34
+ mock_method_call("ActiveRecord::Base", "allocate", [], :class, mock_model("User"))
35
+ mock_method_call("ActiveRecord::Base", "allocate", [], :class, mock_model("Group"))
36
+ end
37
+ response = get_via_rack "/"
38
+ response.should have_row("#active_record", "User", "2")
39
+ response.should have_row("#active_record", "Group", "1")
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ module Rack::Insight
4
+ describe "ActiveResourcePanel" do
5
+ before do
6
+ mock_constant("ActiveResource::Connection")
7
+ reset_insight :panel_files => %w{active_resource_panel}
8
+ end
9
+
10
+ def mock_model(name)
11
+ model = stub("model")
12
+ model.stub!(:name => name)
13
+ obj = stub(name)
14
+ obj.stub!(:base_class => model)
15
+ obj
16
+ end
17
+
18
+ describe "heading" do
19
+ it "displays the total number of instantiated AR objects" do
20
+ app.before_return do
21
+ mock_method_call("ActiveResource::Connection", "request", [], :instance, "")
22
+ mock_method_call("ActiveResource::Connection", "request", [], :instance, "")
23
+ end
24
+
25
+ response = get_via_rack "/"
26
+ response.should have_heading("ARes: 2 Queries")
27
+ end
28
+ end
29
+
30
+ describe "content", :pending => true do
31
+ it "displays the count of instantiated objects for each class" do
32
+ app.before_return do
33
+ mock_method_call("ActiveResource::Connection", "request", [], :instance, "")
34
+ mock_method_call("ActiveResource::Connection", "request", [], :instance, "")
35
+ end
36
+ response = get_via_rack "/"
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,178 @@
1
+ require 'spec_helper'
2
+
3
+ module Rack::Insight
4
+ describe "CachePanel" do
5
+ before do
6
+ mock_constant("Rails")
7
+ mock_constant("Memcached")
8
+ mock_constant("MemCache")
9
+ reset_insight :panel_classes => [Rack::Insight::CachePanel]
10
+ end
11
+
12
+ describe "heading" do
13
+ it "displays the total memcache time" do
14
+ response = get_via_rack "/"
15
+ response.should have_heading("Cache: 0.00ms")
16
+ end
17
+ end
18
+
19
+ describe "content" do
20
+ describe "usage table" do
21
+ it "displays the total number of memcache calls" do
22
+ app.before_return do
23
+ mock_method_call("Memcached", "get", ["user:1"])
24
+ end
25
+ response = get_via_rack "/"
26
+
27
+ # This causes a bus error:
28
+ # response.should have_selector("th:content('Total Calls') + td", :content => "1")
29
+
30
+ response.should have_row("#cache_usage", "Total Calls", "1")
31
+ end
32
+
33
+ it "displays the total memcache time" do
34
+ response = get_via_rack "/"
35
+ response.should have_row("#cache_usage", "Total Time", "0.00ms")
36
+ end
37
+
38
+ it "dispays the number of memcache hits" do
39
+ app.before_return do
40
+ mock_method_call("Memcached", "get", ["user:1"])
41
+ end
42
+ response = get_via_rack "/"
43
+ response.should have_row("#cache_usage", "Hits", "0")
44
+ end
45
+
46
+ it "displays the number of memcache misses" do
47
+ app.before_return do
48
+ mock_method_call("Memcached", "get", ["user:1"])
49
+ end
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
+ app.before_return do
56
+ mock_method_call("Memcached", "get", ["user:1"])
57
+ end
58
+ response = get_via_rack "/"
59
+ response.should have_row("#cache_usage", "gets", "1")
60
+ end
61
+
62
+ it "displays the number of memcache sets" do
63
+
64
+ app.before_return do
65
+ mock_method_call("Memcached", "set", ["user:1"])
66
+ end
67
+ response = get_via_rack "/"
68
+ response.should have_row("#cache_usage", "sets", "1")
69
+ end
70
+
71
+ it "displays the number of memcache deletes" do
72
+ app.before_return do
73
+ mock_method_call("Memcached", "delete", ["user:1"])
74
+ end
75
+ response = get_via_rack "/"
76
+ response.should have_row("#cache_usage", "deletes", "1")
77
+ end
78
+
79
+ it "displays the number of memcache get_multis" do
80
+ app.before_return do
81
+ mock_method_call("MemCache", "get_multi", ["user:1", "user:2"])
82
+ end
83
+ response = get_via_rack "/"
84
+ response.should have_row("#cache_usage", "get_multis", "1")
85
+ end
86
+ end
87
+
88
+ describe "breakdown" do
89
+ it "displays each memcache operation" do
90
+ app.before_return do
91
+ mock_method_call("Memcached", "get", ["user:1"])
92
+ end
93
+ response = get_via_rack "/"
94
+ response.should have_row("#cache_breakdown", "get")
95
+ end
96
+
97
+ it "displays the time for each memcache call" do
98
+ app.before_return do
99
+ mock_method_call("Memcached", "get", ["user:1"])
100
+ end
101
+ response = get_via_rack "/"
102
+ response.should have_row("#cache_breakdown", "user:1", TIME_MS_REGEXP)
103
+ end
104
+
105
+ it "displays the keys for each memcache call" do
106
+ app.before_return do
107
+ mock_method_call("Memcached", "get", ["user:1"])
108
+ end
109
+ response = get_via_rack "/"
110
+ response.should have_row("#cache_breakdown", "user:1", "get")
111
+ end
112
+ end
113
+ end
114
+
115
+ describe "cache operations" do
116
+ before do
117
+ app.insight_app.secret_key = 'abc'
118
+ response = get_via_rack "/"
119
+ end
120
+
121
+
122
+ describe "expire_all" do
123
+ it "expires the cache keys" do
124
+ Rails.stub!(:cache => mock("cache"))
125
+ Rails.cache.should_receive(:delete).with("user:1")
126
+ Rails.cache.should_receive(:delete).with("user:2")
127
+ Rails.cache.should_receive(:delete).with("user:3")
128
+ Rails.cache.should_receive(:delete).with("user:4")
129
+
130
+ get_via_rack "/__insight__/delete_cache_list",
131
+ :keys_1 => "user:1", :keys_2 => "user:2", :keys_3 => "user:3", :keys_4 => "user:4",
132
+ :hash => Digest::SHA1.hexdigest("abc:user:1:user:2:user:3:user:4")
133
+ end
134
+
135
+ it "returns OK" do
136
+ Rails.stub!(:cache => mock("cache", :delete => nil))
137
+ response = get_via_rack "/__insight__/delete_cache_list",
138
+ :keys_1 => "user:1", :keys_2 => "user:2", :keys_3 => "user:3", :keys_4 => "user:4",
139
+ :hash => Digest::SHA1.hexdigest("abc:user:1:user:2:user:3:user:4")
140
+ response.should contain("OK")
141
+ end
142
+ end
143
+
144
+ describe "expire" do
145
+ it "expires the cache key" do
146
+ Rails.stub!(:cache => mock("cache"))
147
+ Rails.cache.should_receive(:delete).with("user:1")
148
+ get_via_rack "/__insight__/delete_cache", :key => "user:1",
149
+ :hash => Digest::SHA1.hexdigest("abc:user:1")
150
+ end
151
+
152
+ it "returns OK" do
153
+ Rails.stub!(:cache => mock("cache", :delete => nil))
154
+ response = get_via_rack "/__insight__/delete_cache", :key => "user:1",
155
+ :hash => Digest::SHA1.hexdigest("abc:user:1")
156
+ response.should contain("OK")
157
+ end
158
+ end
159
+
160
+ describe "view_cache" do
161
+ it "renders the cache key" do
162
+ Rails.stub!(:cache => mock("cache", :read => "cache body"))
163
+ response = get_via_rack "/__insight__/view_cache", :key => "user:1",
164
+ :hash => Digest::SHA1.hexdigest("abc:user:1")
165
+ response.should contain("cache body")
166
+ end
167
+
168
+ it "renders non-String cache values properly" do
169
+ Rails.stub!(:cache => mock("cache", :read => [1, 2]))
170
+ response = get_via_rack "/__insight__/view_cache", :key => "user:1",
171
+ :hash => Digest::SHA1.hexdigest("abc:user:1")
172
+ response.should contain("[1, 2]")
173
+ end
174
+ end
175
+
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ module Rack::Insight
4
+ describe "LogPanel" do
5
+ before do
6
+ reset_insight :panel_classes => [Rack::Insight::LogPanel]
7
+ end
8
+
9
+ describe "heading" do
10
+ it "displays 'Log'" do
11
+ response = get_via_rack "/"
12
+ response.should have_heading("Log")
13
+ end
14
+ end
15
+
16
+ describe "content" do
17
+ it "displays recorded log lines" do
18
+ app.before_return do
19
+ mock_method_call("Logger", "add", [0, "This is a logged message"])
20
+ end
21
+ response = get_via_rack "/"
22
+ response.should contain("This is a logged message")
23
+ response.should contain("DEBUG")
24
+ end
25
+ end
26
+
27
+ describe "Extended Logger" do
28
+ it "does still return true/false for #add if class Logger" do
29
+ #AS::BufferedLogger returns the added string, Logger returns true/false
30
+ LOGGER.add(0, "foo").should == true
31
+ end
32
+ end
33
+
34
+
35
+ describe "With no logger defined" do
36
+ it "does not err out" do
37
+ logger = LOGGER
38
+ Object.send :remove_const, :LOGGER
39
+ lambda{ load("rack/insight/panels/log_panel.rb") }.should_not raise_error
40
+ ::LOGGER = logger
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ module Rack::Insight
4
+ describe "MemoryPanel" do
5
+ before do
6
+ reset_insight :panel => [Rack::Insight::MemoryPanel]
7
+ end
8
+
9
+ describe "heading" do
10
+ it "displays the total memory" do
11
+ response = get_via_rack "/"
12
+ response.should have_heading(/\d+ KB total/)
13
+ end
14
+
15
+ it "displays the memory change during the request" do
16
+ response = get_via_rack "/"
17
+ response.should have_heading(/\d+ KB/)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ if defined? Mongo
4
+ module Rack::Insight
5
+ describe "MongoPanel" do
6
+ before do
7
+ MongoPanel.reset
8
+ reset_insight :panel_files => %w{mongo_panel}
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
52
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ module Rack::Insight
4
+ describe "RailsInfoPanel" do
5
+ before do
6
+ mock_constant("Rails::Info")
7
+ reset_insight :panel_classes => [Rack::Insight::RailsInfoPanel]
8
+
9
+ Rails::Info.stub!(:properties => [])
10
+ end
11
+
12
+ describe "heading" do
13
+ it "displays the Rails version" do
14
+ Rails.stub!(:version => "v2.3.0")
15
+ response = get_via_rack "/"
16
+ response.should have_heading("Rails v2.3.0")
17
+ end
18
+ end
19
+
20
+ describe "content" do
21
+ it "displays the Rails::Info properties" do
22
+ Rails.stub!(:version => "v2.3.0")
23
+ Rails::Info.stub!(:properties => [["Name", "Value"]])
24
+ response = get_via_rack "/"
25
+ response.should have_row("#rails_info", "Name", "Value")
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ module Rack::Insight
4
+ describe "RedisPanel" do
5
+ before do
6
+ reset_insight :panel_files => %w[redis_panel]
7
+ end
8
+
9
+ describe "heading" do
10
+ it "displays the total redis time" do
11
+ response = get_via_rack "/"
12
+ response.should have_heading("Redis: 0.00ms")
13
+ end
14
+ end
15
+
16
+ describe "content" do
17
+ describe "usage table" do
18
+ it "displays the total number of redis calls" do
19
+ RedisPanel.record(["get, user:1"], Kernel.caller) { }
20
+ response = get_via_rack "/"
21
+
22
+ # This causes a bus error:
23
+ # response.should have_selector("th:content('Total Calls') + td", :content => "1")
24
+
25
+ response.should have_row("#redis_usage", "Total Calls", "1")
26
+ end
27
+
28
+ it "displays the total redis time" do
29
+ response = get_via_rack "/"
30
+ response.should have_row("#redis_usage", "Total Time", "0.00ms")
31
+ end
32
+ end
33
+
34
+ describe "breakdown" do
35
+ it "displays each redis operation" do
36
+ RedisPanel.record(["get, user:1"], Kernel.caller) { }
37
+ response = get_via_rack "/"
38
+ response.should have_row("#redis_breakdown", "get")
39
+ end
40
+
41
+ it "displays the time for redis call" do
42
+ RedisPanel.record(["get, user:1"], Kernel.caller) { }
43
+ response = get_via_rack "/"
44
+ response.should have_row("#redis_breakdown", "user:1", TIME_MS_REGEXP)
45
+ end
46
+
47
+ it "displays the arguments for each redis call" do
48
+ RedisPanel.record(["get, user:1"], Kernel.caller) { }
49
+ response = get_via_rack "/"
50
+ response.should have_row("#redis_breakdown", "user:1", "get")
51
+ end
52
+
53
+ it "displays a link to show the backtrace when it's available" do
54
+ RedisPanel.record(["get, user:1"], Kernel.caller) { }
55
+ response = get_via_rack "/"
56
+ response.should have_row("#redis_breakdown", "user:1", "Show Backtrace")
57
+ end
58
+
59
+ it "does not display a link to show the backtrace when it's not available" do
60
+ RedisPanel.record(["get, user:1"], []) { }
61
+ response = get_via_rack "/"
62
+ response.should_not contain("Show Backtrace")
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end