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.
- data/.gitignore +13 -0
- data/.rspec +1 -0
- data/.simplecov +4 -0
- data/.travis.yml +8 -0
- data/CHANGELOG +58 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +82 -0
- data/LICENSE +24 -0
- data/README.md +189 -0
- data/Rakefile +27 -0
- data/TODO +7 -0
- data/lib/rack-insight.rb +1 -0
- data/lib/rack/insight.rb +19 -0
- data/lib/rack/insight/app.rb +198 -0
- data/lib/rack/insight/config.rb +30 -0
- data/lib/rack/insight/database.rb +193 -0
- data/lib/rack/insight/enable-button.rb +43 -0
- data/lib/rack/insight/filtered_backtrace.rb +45 -0
- data/lib/rack/insight/instrumentation.rb +9 -0
- data/lib/rack/insight/instrumentation/backstage.rb +10 -0
- data/lib/rack/insight/instrumentation/client.rb +20 -0
- data/lib/rack/insight/instrumentation/instrument.rb +109 -0
- data/lib/rack/insight/instrumentation/package-definition.rb +58 -0
- data/lib/rack/insight/instrumentation/probe-definition.rb +20 -0
- data/lib/rack/insight/instrumentation/probe.rb +196 -0
- data/lib/rack/insight/instrumentation/setup.rb +32 -0
- data/lib/rack/insight/logger.rb +53 -0
- data/lib/rack/insight/options.rb +116 -0
- data/lib/rack/insight/panel.rb +135 -0
- data/lib/rack/insight/panel_app.rb +31 -0
- data/lib/rack/insight/panels-content.rb +22 -0
- data/lib/rack/insight/panels-header.rb +18 -0
- data/lib/rack/insight/panels/active_record_panel.rb +46 -0
- data/lib/rack/insight/panels/active_resource_panel.rb +48 -0
- data/lib/rack/insight/panels/active_resource_panel/query.rb +27 -0
- data/lib/rack/insight/panels/cache_panel.rb +68 -0
- data/lib/rack/insight/panels/cache_panel/panel_app.rb +46 -0
- data/lib/rack/insight/panels/cache_panel/stats.rb +90 -0
- data/lib/rack/insight/panels/log_panel.rb +53 -0
- data/lib/rack/insight/panels/memory_panel.rb +36 -0
- data/lib/rack/insight/panels/mongo_panel.rb +41 -0
- data/lib/rack/insight/panels/mongo_panel/mongo_extension.rb +24 -0
- data/lib/rack/insight/panels/mongo_panel/stats.rb +46 -0
- data/lib/rack/insight/panels/rails_info_panel.rb +19 -0
- data/lib/rack/insight/panels/redis_panel.rb +42 -0
- data/lib/rack/insight/panels/redis_panel/redis_extension.rb +23 -0
- data/lib/rack/insight/panels/redis_panel/stats.rb +50 -0
- data/lib/rack/insight/panels/request_variables_panel.rb +70 -0
- data/lib/rack/insight/panels/speedtracer_panel.rb +89 -0
- data/lib/rack/insight/panels/speedtracer_panel/profiling.rb +29 -0
- data/lib/rack/insight/panels/speedtracer_panel/trace-app.rb +52 -0
- data/lib/rack/insight/panels/speedtracer_panel/tracer.rb +213 -0
- data/lib/rack/insight/panels/sphinx_panel.rb +41 -0
- data/lib/rack/insight/panels/sphinx_panel/stats.rb +94 -0
- data/lib/rack/insight/panels/sql_panel.rb +53 -0
- data/lib/rack/insight/panels/sql_panel/panel_app.rb +37 -0
- data/lib/rack/insight/panels/sql_panel/query.rb +94 -0
- data/lib/rack/insight/panels/templates_panel.rb +58 -0
- data/lib/rack/insight/panels/templates_panel/rendering.rb +81 -0
- data/lib/rack/insight/panels/timer_panel.rb +40 -0
- data/lib/rack/insight/params_signature.rb +61 -0
- data/lib/rack/insight/path-filter.rb +23 -0
- data/lib/rack/insight/public/__insight__/bookmarklet.html +10 -0
- data/lib/rack/insight/public/__insight__/bookmarklet.js +223 -0
- data/lib/rack/insight/public/__insight__/insight.css +235 -0
- data/lib/rack/insight/public/__insight__/insight.js +127 -0
- data/lib/rack/insight/public/__insight__/jquery-1.3.2.js +4376 -0
- data/lib/rack/insight/public/__insight__/jquery.tablesorter.min.js +1 -0
- data/lib/rack/insight/public/__insight__/spinner.gif +0 -0
- data/lib/rack/insight/rack_static_bug_avoider.rb +16 -0
- data/lib/rack/insight/redirect_interceptor.rb +25 -0
- data/lib/rack/insight/render.rb +72 -0
- data/lib/rack/insight/request-recorder.rb +22 -0
- data/lib/rack/insight/rspec_matchers.rb +33 -0
- data/lib/rack/insight/toolbar.rb +69 -0
- data/lib/rack/insight/version.rb +7 -0
- data/lib/rack/insight/views/enable-button.html.erb +21 -0
- data/lib/rack/insight/views/error.html.erb +17 -0
- data/lib/rack/insight/views/headers_fragment.html.erb +20 -0
- data/lib/rack/insight/views/panels/active_record.html.erb +17 -0
- data/lib/rack/insight/views/panels/active_resource.html.erb +47 -0
- data/lib/rack/insight/views/panels/cache.html.erb +93 -0
- data/lib/rack/insight/views/panels/execute_sql.html.erb +32 -0
- data/lib/rack/insight/views/panels/explain_sql.html.erb +32 -0
- data/lib/rack/insight/views/panels/log.html.erb +21 -0
- data/lib/rack/insight/views/panels/mongo.html.erb +32 -0
- data/lib/rack/insight/views/panels/profile_sql.html.erb +32 -0
- data/lib/rack/insight/views/panels/rails_info.html.erb +19 -0
- data/lib/rack/insight/views/panels/redis.html.erb +46 -0
- data/lib/rack/insight/views/panels/request_variables.html.erb +25 -0
- data/lib/rack/insight/views/panels/speedtracer/serverevent.html.erb +10 -0
- data/lib/rack/insight/views/panels/speedtracer/servertrace.html.erb +12 -0
- data/lib/rack/insight/views/panels/speedtracer/traces.html.erb +18 -0
- data/lib/rack/insight/views/panels/sphinx.html.erb +32 -0
- data/lib/rack/insight/views/panels/sql.html.erb +43 -0
- data/lib/rack/insight/views/panels/templates.html.erb +6 -0
- data/lib/rack/insight/views/panels/timer.html.erb +19 -0
- data/lib/rack/insight/views/panels/view_cache.html.erb +19 -0
- data/lib/rack/insight/views/redirect.html.erb +16 -0
- data/lib/rack/insight/views/request_fragment.html.erb +25 -0
- data/lib/rack/insight/views/toolbar.html.erb +29 -0
- data/rack-insight.gemspec +40 -0
- data/spec/custom_matchers.rb +0 -0
- data/spec/fixtures/config.ru +8 -0
- data/spec/fixtures/dummy_panel.rb +2 -0
- data/spec/fixtures/sample_app.rb +72 -0
- data/spec/fixtures/star_trek_panel.rb +1 -0
- data/spec/insight_spec.rb +163 -0
- data/spec/instrumentation_spec.rb +188 -0
- data/spec/rack/insight/config_spec.rb +20 -0
- data/spec/rack/insight/panels/active_record_panel_spec.rb +43 -0
- data/spec/rack/insight/panels/active_resource_panel_spec.rb +40 -0
- data/spec/rack/insight/panels/cache_panel_spec.rb +178 -0
- data/spec/rack/insight/panels/log_panel_spec.rb +44 -0
- data/spec/rack/insight/panels/memory_panel_spec.rb +21 -0
- data/spec/rack/insight/panels/mongo_panel_spec_pending.rb +52 -0
- data/spec/rack/insight/panels/rails_info_panel_spec.rb +29 -0
- data/spec/rack/insight/panels/redis_panel_spec.rb +67 -0
- data/spec/rack/insight/panels/speedtracer_panel_spec.rb +86 -0
- data/spec/rack/insight/panels/sql_panel_spec.rb +146 -0
- data/spec/rack/insight/panels/templates_panel_spec.rb +86 -0
- data/spec/rack/insight/panels/timer_panel_spec.rb +38 -0
- data/spec/rcov.opts +1 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +111 -0
- metadata +380 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Rack::Insight
|
|
4
|
+
describe "SpeedTracerPanel" do
|
|
5
|
+
before do
|
|
6
|
+
mock_constant("ActionView::Template")
|
|
7
|
+
reset_insight :panel_files => %w{speedtracer_panel}
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe "heading" do
|
|
11
|
+
it "lists traces" do
|
|
12
|
+
response = get_via_rack "/"
|
|
13
|
+
response.should have_heading("traces")
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def mock_template(path)
|
|
18
|
+
template = stub("ActionView::Template")
|
|
19
|
+
template.stub!(:virtual_path => path)
|
|
20
|
+
template
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe "content", :pending => "time to build good Speedtracer tests" do
|
|
24
|
+
it "displays the template paths" do
|
|
25
|
+
app.before_return do
|
|
26
|
+
mock_method_call("ActionView::Template", :render, [], :instance, mock_template("users/show"))
|
|
27
|
+
end
|
|
28
|
+
response = get_via_rack "/"
|
|
29
|
+
response.should contain("users/show")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "displays the template children" do
|
|
33
|
+
app.before_return do
|
|
34
|
+
mock_method_call("ActionView::Template", :render, [], :instance, mock_template("users/show")) do
|
|
35
|
+
mock_method_call("ActionView::Template", :render, [], :instance, mock_template("users/toolbar"))
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
response = get_via_rack "/"
|
|
39
|
+
response.should have_selector("li", :content => "users/show") do |li|
|
|
40
|
+
li.should contain("users/toolbar")
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context "for templates that rendered templates" do
|
|
45
|
+
it "displays the total time" do
|
|
46
|
+
app.before_return do
|
|
47
|
+
mock_method_call("ActionView::Template", :render, [], :instance, mock_template("users/show")) do
|
|
48
|
+
mock_method_call("ActionView::Template", :render, [], :instance, mock_template("users/toolbar"))
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
response = get_via_rack "/"
|
|
53
|
+
response.should have_selector("li", :content => "users/show") do |li|
|
|
54
|
+
li.should contain(TIME_MS_REGEXP)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "displays the exclusive time" do
|
|
59
|
+
app.before_return do
|
|
60
|
+
mock_method_call("ActionView::Template", :render, [], :instance, mock_template("users/show")) do
|
|
61
|
+
mock_method_call("ActionView::Template", :render, [], :instance, mock_template("users/toolbar"))
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
response = get_via_rack "/"
|
|
66
|
+
response.should have_selector("li", :content => "users/show") do |li|
|
|
67
|
+
li.should contain(/\d\.\d{2} exclusive/)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
context "for leaf templates" do
|
|
73
|
+
it "does not display the exclusive time" do
|
|
74
|
+
app.before_return do
|
|
75
|
+
mock_method_call("ActionView::Template", :render, [], :instance, mock_template("users/show"))
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
response = get_via_rack "/"
|
|
79
|
+
response.should contain("users/show") do |li|
|
|
80
|
+
li.should_not contain("exclusive")
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Rack::Insight
|
|
4
|
+
describe "SQLPanel" do
|
|
5
|
+
before do
|
|
6
|
+
mock_constant("ActiveRecord::ConnectionAdapters::MysqlAdapter")
|
|
7
|
+
reset_insight :panel_files => %w{sql_panel}
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe "heading" do
|
|
11
|
+
it "displays the total SQL query count" do
|
|
12
|
+
app.before_return do
|
|
13
|
+
mock_method_call("ActiveRecord::ConnectionAdapters::MysqlAdapter", "execute", ["SELECT NOW();"])
|
|
14
|
+
end
|
|
15
|
+
response = get_via_rack "/"
|
|
16
|
+
response.should have_heading("1 Queries")
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "displays the total SQL time" do
|
|
20
|
+
app.before_return do
|
|
21
|
+
mock_method_call("ActiveRecord::ConnectionAdapters::MysqlAdapter", "execute", ["SELECT NOW();"])
|
|
22
|
+
end
|
|
23
|
+
response = get_via_rack "/"
|
|
24
|
+
response.should have_heading(/Queries \(\d+\.\d{2}ms\)/)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe "content" do
|
|
29
|
+
it "displays each executed SQL query" do
|
|
30
|
+
app.before_return do
|
|
31
|
+
mock_method_call("ActiveRecord::ConnectionAdapters::MysqlAdapter", "execute", ["SELECT NOW();"])
|
|
32
|
+
end
|
|
33
|
+
response = get_via_rack "/"
|
|
34
|
+
response.should have_row("#sql", "SELECT NOW();")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "displays the time of each executed SQL query" do
|
|
38
|
+
app.before_return do
|
|
39
|
+
mock_method_call("ActiveRecord::ConnectionAdapters::MysqlAdapter", "execute", ["SELECT NOW();"])
|
|
40
|
+
end
|
|
41
|
+
response = get_via_rack "/"
|
|
42
|
+
response.should have_row("#sql", "SELECT NOW();", TIME_MS_REGEXP)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def stub_result(results = [[]])
|
|
47
|
+
columns = results.first
|
|
48
|
+
fields = columns.map { |c| stub("field", :name => c) }
|
|
49
|
+
rows = results[1..-1]
|
|
50
|
+
|
|
51
|
+
result = stub("result", :fetch_fields => fields)
|
|
52
|
+
result.stub!(:map).and_yield(rows)
|
|
53
|
+
return result
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def expect_query(sql, results)
|
|
57
|
+
conn = stub("connection")
|
|
58
|
+
mock_constant("ActiveRecord::Base")
|
|
59
|
+
ActiveRecord::Base.stub!(:connection => conn)
|
|
60
|
+
conn.should_receive(:execute).with(sql).and_return(stub_result(results))
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
describe "sql/execute" do
|
|
64
|
+
it "displays the query results" do
|
|
65
|
+
app.insight_app.secret_key = "abc"
|
|
66
|
+
expect_query "SELECT username FROM users",
|
|
67
|
+
[["username"],
|
|
68
|
+
["bryan"]]
|
|
69
|
+
|
|
70
|
+
response = get_via_rack "/__insight__/sql/execute", {:query => "SELECT username FROM users",
|
|
71
|
+
:hash => Digest::SHA1.hexdigest("abc:SELECT username FROM users")}, {:xhr => true}
|
|
72
|
+
response.should contain("SELECT username FROM users")
|
|
73
|
+
response.should be_ok
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "is forbidden when the hash is missing or wrong" do
|
|
77
|
+
app.insight_app.secret_key='abc'
|
|
78
|
+
|
|
79
|
+
lambda {
|
|
80
|
+
get_via_rack "/__insight__/sql/execute", {:query => "SELECT username FROM users",
|
|
81
|
+
:hash => "foobar"}, {:xhr => true}
|
|
82
|
+
}.should raise_error(SecurityError)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "is not available when the insight.secret_key is nil" do
|
|
86
|
+
app.insight_app.secret_key = nil
|
|
87
|
+
|
|
88
|
+
lambda {
|
|
89
|
+
get_via_rack "/__insight__/sql/execute", {:query => "SELECT username FROM users",
|
|
90
|
+
:hash => "6f286f55b75716e5c91f16d77d09fa73b353ebc1"}, {:xhr => true}
|
|
91
|
+
}.should raise_error(SecurityError)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "is not available when the insight.secret_key is an empty string" do
|
|
95
|
+
app.insight_app.secret_key = ""
|
|
96
|
+
|
|
97
|
+
lambda {
|
|
98
|
+
get_via_rack "/__insight__/sql/execute", {:query => "SELECT username FROM users",
|
|
99
|
+
:hash => "6f286f55b75716e5c91f16d77d09fa73b353ebc1"}, {:xhr => true}
|
|
100
|
+
}.should raise_error(SecurityError)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
describe "sql/explain" do
|
|
105
|
+
it "displays the query explain plan" do
|
|
106
|
+
app.insight_app.secret_key = "abc"
|
|
107
|
+
expect_query "EXPLAIN SELECT username FROM users",
|
|
108
|
+
[["table"],
|
|
109
|
+
["users"]]
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
response = get_via_rack "/__insight__/sql/explain", :query => "SELECT username FROM users",
|
|
113
|
+
:hash => Digest::SHA1.hexdigest("abc:SELECT username FROM users")
|
|
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
|
+
app.insight_app.secret_key='abc'
|
|
120
|
+
|
|
121
|
+
lambda {
|
|
122
|
+
get_via_rack "/__insight__/sql/explain", :query => "SELECT username FROM users",
|
|
123
|
+
:hash => "foobar"
|
|
124
|
+
}.should raise_error(SecurityError)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it "is not available when the insight.secret_key is nil" do
|
|
128
|
+
app.insight_app.secret_key=nil
|
|
129
|
+
|
|
130
|
+
lambda {
|
|
131
|
+
get_via_rack "/__insight__/sql/explain", :query => "SELECT username FROM users",
|
|
132
|
+
:hash => "6f286f55b75716e5c91f16d77d09fa73b353ebc1"
|
|
133
|
+
}.should raise_error(SecurityError)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it "is not available when the insight.secret_key is an empty string" do
|
|
137
|
+
app.insight_app.secret_key=""
|
|
138
|
+
|
|
139
|
+
lambda {
|
|
140
|
+
get_via_rack "/__insight__/sql/explain", :query => "SELECT username FROM users",
|
|
141
|
+
:hash => "6f286f55b75716e5c91f16d77d09fa73b353ebc1"
|
|
142
|
+
}.should raise_error(SecurityError)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Rack::Insight
|
|
4
|
+
describe "TemplatesPanel" do
|
|
5
|
+
before do
|
|
6
|
+
mock_constant("ActionView::Template")
|
|
7
|
+
reset_insight :panel_classes => [Rack::Insight::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
|
+
def mock_template(path)
|
|
18
|
+
template = stub("ActionView::Template")
|
|
19
|
+
template.stub!(:virtual_path => path)
|
|
20
|
+
template
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe "content" do
|
|
24
|
+
it "displays the template paths" do
|
|
25
|
+
app.before_return do
|
|
26
|
+
mock_method_call("ActionView::Template", :render, [], :instance, mock_template("users/show"))
|
|
27
|
+
end
|
|
28
|
+
response = get_via_rack "/"
|
|
29
|
+
response.should contain("users/show")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "displays the template children" do
|
|
33
|
+
app.before_return do
|
|
34
|
+
mock_method_call("ActionView::Template", :render, [], :instance, mock_template("users/show")) do
|
|
35
|
+
mock_method_call("ActionView::Template", :render, [], :instance, mock_template("users/toolbar"))
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
response = get_via_rack "/"
|
|
39
|
+
response.should have_selector("li", :content => "users/show") do |li|
|
|
40
|
+
li.should contain("users/toolbar")
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context "for templates that rendered templates" do
|
|
45
|
+
it "displays the total time" do
|
|
46
|
+
app.before_return do
|
|
47
|
+
mock_method_call("ActionView::Template", :render, [], :instance, mock_template("users/show")) do
|
|
48
|
+
mock_method_call("ActionView::Template", :render, [], :instance, mock_template("users/toolbar"))
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
response = get_via_rack "/"
|
|
53
|
+
response.should have_selector("li", :content => "users/show") do |li|
|
|
54
|
+
li.should contain(TIME_MS_REGEXP)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "displays the exclusive time" do
|
|
59
|
+
app.before_return do
|
|
60
|
+
mock_method_call("ActionView::Template", :render, [], :instance, mock_template("users/show")) do
|
|
61
|
+
mock_method_call("ActionView::Template", :render, [], :instance, mock_template("users/toolbar"))
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
response = get_via_rack "/"
|
|
66
|
+
response.should have_selector("li", :content => "users/show") do |li|
|
|
67
|
+
li.should contain(/\d\.\d{2} exclusive/)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
context "for leaf templates" do
|
|
73
|
+
it "does not display the exclusive time" do
|
|
74
|
+
app.before_return do
|
|
75
|
+
mock_method_call("ActionView::Template", :render, [], :instance, mock_template("users/show"))
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
response = get_via_rack "/"
|
|
79
|
+
response.should contain("users/show") do |li|
|
|
80
|
+
li.should_not contain("exclusive")
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Rack::Insight
|
|
4
|
+
describe "TimerPanel" do
|
|
5
|
+
before do
|
|
6
|
+
reset_insight :panel_classes => [Rack::Insight::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
|
data/spec/rcov.opts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
-x gems,spec\/
|
data/spec/spec.opts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
require "rubygems"
|
|
2
|
+
require "webrat"
|
|
3
|
+
require "rack/test"
|
|
4
|
+
|
|
5
|
+
RAILS_ENV = "test"
|
|
6
|
+
|
|
7
|
+
#$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__)) + '/lib'
|
|
8
|
+
#$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))
|
|
9
|
+
|
|
10
|
+
require "rack-insight"
|
|
11
|
+
require "fixtures/sample_app"
|
|
12
|
+
require "fixtures/dummy_panel"
|
|
13
|
+
require "rack/insight/rspec_matchers"
|
|
14
|
+
|
|
15
|
+
RSpec.configure do |config|
|
|
16
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
|
17
|
+
config.run_all_when_everything_filtered = true
|
|
18
|
+
config.filter_run :focus
|
|
19
|
+
|
|
20
|
+
# Run specs in random order to surface order dependencies. If you find an
|
|
21
|
+
# order dependency and want to debug it, you can fix the order by providing
|
|
22
|
+
# the seed, which is printed after each run.
|
|
23
|
+
# --seed 1234
|
|
24
|
+
# TODO: Turn this on. Currently off because the specs bleed, and will randomly fail when run randomly.
|
|
25
|
+
#config.order = 'random'
|
|
26
|
+
|
|
27
|
+
TIME_MS_REGEXP = /\d+\.\d{2}ms/
|
|
28
|
+
|
|
29
|
+
config.include Rack::Test::Methods
|
|
30
|
+
config.include Webrat::Matchers
|
|
31
|
+
config.include Rack::Insight::RspecMatchers
|
|
32
|
+
|
|
33
|
+
config.before do
|
|
34
|
+
Thread.current["rack-insight.logger"] = Rack::Insight::Logger.new(Logger::FATAL, "")
|
|
35
|
+
@added_constants = []
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
config.after do
|
|
39
|
+
@added_constants.each do |parent, added|
|
|
40
|
+
parent.send :remove_const, added
|
|
41
|
+
end
|
|
42
|
+
@added_constants.clear
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def reset_insight(options=nil)
|
|
46
|
+
system(*%w{rm -f rack-insight.sqlite})
|
|
47
|
+
|
|
48
|
+
Rack::Insight::Database.reset
|
|
49
|
+
|
|
50
|
+
app.prototype
|
|
51
|
+
app.insight_app.reset(options)
|
|
52
|
+
|
|
53
|
+
Rack::Insight.enable
|
|
54
|
+
|
|
55
|
+
set_cookie "rack-insight_enabled=1"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def reset_config(config_options = {:panel_load_paths => [File::join('rack', 'insight', 'panels')]})
|
|
59
|
+
Rack::Insight::Config.configure do |config|
|
|
60
|
+
# spec folder is in the load path during specs!
|
|
61
|
+
config[:panel_load_paths] = config_options[:panel_load_paths]
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def app
|
|
66
|
+
SampleApp
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def mock_constant(name)
|
|
70
|
+
parts = name.split("::")
|
|
71
|
+
klass = parts.pop
|
|
72
|
+
mod = parts.inject(Object) do |const, part|
|
|
73
|
+
begin
|
|
74
|
+
const.const_get(part)
|
|
75
|
+
rescue NameError
|
|
76
|
+
@added_constants << [const, part]
|
|
77
|
+
mod = Module.new
|
|
78
|
+
const.const_set(part.to_sym, mod)
|
|
79
|
+
mod
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
begin
|
|
83
|
+
mod.const_get(klass)
|
|
84
|
+
rescue NameError
|
|
85
|
+
mod.const_set(klass, Class.new)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def mock_method_call(context, method, args=[], kind=:instance, object=Object.new, &block)
|
|
90
|
+
mock_constant(context)
|
|
91
|
+
|
|
92
|
+
called_at = caller[0]
|
|
93
|
+
file, line, real_method = called_at.split(":")
|
|
94
|
+
called_at = [file,line,method].join(":")
|
|
95
|
+
|
|
96
|
+
block ||= proc {}
|
|
97
|
+
|
|
98
|
+
Rack::Insight::Instrumentation::Probe::ProbeRunner.probe_run(
|
|
99
|
+
object, context, kind, args, called_at, method, &block)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def rack_env(key, value)
|
|
103
|
+
@rack_env ||= {}
|
|
104
|
+
@rack_env[key] = value
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def get_via_rack(uri, params = {}, env = {}, &block)
|
|
108
|
+
env = env.merge(@rack_env) if @rack_env
|
|
109
|
+
get(uri, params, env, &block)
|
|
110
|
+
end
|
|
111
|
+
end
|