rack-allocation_stats 0.1.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.
- checksums.yaml +7 -0
- data/demo_rack_apps/Rails_3.2.15/app/controllers/application_controller.rb +3 -0
- data/demo_rack_apps/Rails_3.2.15/app/controllers/projects_controller.rb +83 -0
- data/demo_rack_apps/Rails_3.2.15/app/controllers/tasks_controller.rb +83 -0
- data/demo_rack_apps/Rails_3.2.15/app/helpers/application_helper.rb +2 -0
- data/demo_rack_apps/Rails_3.2.15/app/helpers/projects_helper.rb +2 -0
- data/demo_rack_apps/Rails_3.2.15/app/helpers/tasks_helper.rb +2 -0
- data/demo_rack_apps/Rails_3.2.15/app/models/project.rb +4 -0
- data/demo_rack_apps/Rails_3.2.15/app/models/task.rb +4 -0
- data/demo_rack_apps/Rails_3.2.15/config/application.rb +63 -0
- data/demo_rack_apps/Rails_3.2.15/config/boot.rb +6 -0
- data/demo_rack_apps/Rails_3.2.15/config/environment.rb +5 -0
- data/demo_rack_apps/Rails_3.2.15/config/environments/development.rb +37 -0
- data/demo_rack_apps/Rails_3.2.15/config/environments/production.rb +67 -0
- data/demo_rack_apps/Rails_3.2.15/config/environments/test.rb +37 -0
- data/demo_rack_apps/Rails_3.2.15/config/initializers/backtrace_silencers.rb +7 -0
- data/demo_rack_apps/Rails_3.2.15/config/initializers/inflections.rb +15 -0
- data/demo_rack_apps/Rails_3.2.15/config/initializers/mime_types.rb +5 -0
- data/demo_rack_apps/Rails_3.2.15/config/initializers/secret_token.rb +7 -0
- data/demo_rack_apps/Rails_3.2.15/config/initializers/session_store.rb +8 -0
- data/demo_rack_apps/Rails_3.2.15/config/initializers/wrap_parameters.rb +14 -0
- data/demo_rack_apps/Rails_3.2.15/config/routes.rb +64 -0
- data/demo_rack_apps/Rails_3.2.15/db/migrate/20131104031828_create_projects.rb +11 -0
- data/demo_rack_apps/Rails_3.2.15/db/migrate/20131104031829_create_tasks.rb +11 -0
- data/demo_rack_apps/Rails_3.2.15/db/schema.rb +32 -0
- data/demo_rack_apps/Rails_3.2.15/db/seeds.rb +15 -0
- data/demo_rack_apps/Rails_3.2.15/test/functional/projects_controller_test.rb +49 -0
- data/demo_rack_apps/Rails_3.2.15/test/functional/tasks_controller_test.rb +49 -0
- data/demo_rack_apps/Rails_3.2.15/test/performance/browsing_test.rb +12 -0
- data/demo_rack_apps/Rails_3.2.15/test/test_helper.rb +13 -0
- data/demo_rack_apps/Rails_3.2.15/test/unit/helpers/projects_helper_test.rb +4 -0
- data/demo_rack_apps/Rails_3.2.15/test/unit/helpers/tasks_helper_test.rb +4 -0
- data/demo_rack_apps/Rails_3.2.15/test/unit/project_test.rb +7 -0
- data/demo_rack_apps/Rails_3.2.15/test/unit/task_test.rb +7 -0
- data/demo_rack_apps/Rails_4.0.1/app/controllers/application_controller.rb +5 -0
- data/demo_rack_apps/Rails_4.0.1/app/controllers/projects_controller.rb +74 -0
- data/demo_rack_apps/Rails_4.0.1/app/controllers/tasks_controller.rb +74 -0
- data/demo_rack_apps/Rails_4.0.1/app/helpers/application_helper.rb +2 -0
- data/demo_rack_apps/Rails_4.0.1/app/helpers/projects_helper.rb +2 -0
- data/demo_rack_apps/Rails_4.0.1/app/helpers/tasks_helper.rb +2 -0
- data/demo_rack_apps/Rails_4.0.1/app/models/project.rb +3 -0
- data/demo_rack_apps/Rails_4.0.1/app/models/task.rb +3 -0
- data/demo_rack_apps/Rails_4.0.1/config/application.rb +24 -0
- data/demo_rack_apps/Rails_4.0.1/config/boot.rb +4 -0
- data/demo_rack_apps/Rails_4.0.1/config/environment.rb +5 -0
- data/demo_rack_apps/Rails_4.0.1/config/environments/development.rb +29 -0
- data/demo_rack_apps/Rails_4.0.1/config/environments/production.rb +80 -0
- data/demo_rack_apps/Rails_4.0.1/config/environments/test.rb +36 -0
- data/demo_rack_apps/Rails_4.0.1/config/initializers/backtrace_silencers.rb +7 -0
- data/demo_rack_apps/Rails_4.0.1/config/initializers/filter_parameter_logging.rb +4 -0
- data/demo_rack_apps/Rails_4.0.1/config/initializers/inflections.rb +16 -0
- data/demo_rack_apps/Rails_4.0.1/config/initializers/mime_types.rb +5 -0
- data/demo_rack_apps/Rails_4.0.1/config/initializers/secret_token.rb +12 -0
- data/demo_rack_apps/Rails_4.0.1/config/initializers/session_store.rb +3 -0
- data/demo_rack_apps/Rails_4.0.1/config/initializers/wrap_parameters.rb +14 -0
- data/demo_rack_apps/Rails_4.0.1/config/routes.rb +60 -0
- data/demo_rack_apps/Rails_4.0.1/db/migrate/20131102201320_create_projects.rb +11 -0
- data/demo_rack_apps/Rails_4.0.1/db/migrate/20131102201321_create_tasks.rb +11 -0
- data/demo_rack_apps/Rails_4.0.1/db/schema.rb +32 -0
- data/demo_rack_apps/Rails_4.0.1/db/seeds.rb +15 -0
- data/demo_rack_apps/Rails_4.0.1/test/controllers/projects_controller_test.rb +49 -0
- data/demo_rack_apps/Rails_4.0.1/test/controllers/tasks_controller_test.rb +49 -0
- data/demo_rack_apps/Rails_4.0.1/test/helpers/projects_helper_test.rb +4 -0
- data/demo_rack_apps/Rails_4.0.1/test/helpers/tasks_helper_test.rb +4 -0
- data/demo_rack_apps/Rails_4.0.1/test/models/project_test.rb +7 -0
- data/demo_rack_apps/Rails_4.0.1/test/models/task_test.rb +7 -0
- data/demo_rack_apps/Rails_4.0.1/test/test_helper.rb +15 -0
- data/lib/rack/allocation_stats.rb +22 -0
- data/lib/rack/allocation_stats/action.rb +14 -0
- data/lib/rack/allocation_stats/call_app_directly.rb +14 -0
- data/lib/rack/allocation_stats/formatters/base.rb +11 -0
- data/lib/rack/allocation_stats/formatters/html.rb +23 -0
- data/lib/rack/allocation_stats/formatters/json.rb +12 -0
- data/lib/rack/allocation_stats/formatters/text.rb +33 -0
- data/lib/rack/allocation_stats/middleware.rb +62 -0
- data/lib/rack/allocation_stats/tracer.rb +80 -0
- data/spec/factories.rb +53 -0
- data/spec/hello_world_app.rb +21 -0
- data/spec/rack/allocation_stats_spec.rb +216 -0
- data/spec/sinatra_app.rb +10 -0
- data/spec/sinatra_templates_app.rb +85 -0
- data/spec/spec_helper.rb +55 -0
- data/spec/yajl_app.rb +20 -0
- data/spec/yaml_app.rb +20 -0
- metadata +169 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class TasksControllerTest < ActionController::TestCase
|
|
4
|
+
setup do
|
|
5
|
+
@task = tasks(:one)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
test "should get index" do
|
|
9
|
+
get :index
|
|
10
|
+
assert_response :success
|
|
11
|
+
assert_not_nil assigns(:tasks)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
test "should get new" do
|
|
15
|
+
get :new
|
|
16
|
+
assert_response :success
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
test "should create task" do
|
|
20
|
+
assert_difference('Task.count') do
|
|
21
|
+
post :create, task: { description: @task.description, name: @task.name, project_id: @task.project_id }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
assert_redirected_to task_path(assigns(:task))
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
test "should show task" do
|
|
28
|
+
get :show, id: @task
|
|
29
|
+
assert_response :success
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
test "should get edit" do
|
|
33
|
+
get :edit, id: @task
|
|
34
|
+
assert_response :success
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
test "should update task" do
|
|
38
|
+
patch :update, id: @task, task: { description: @task.description, name: @task.name, project_id: @task.project_id }
|
|
39
|
+
assert_redirected_to task_path(assigns(:task))
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
test "should destroy task" do
|
|
43
|
+
assert_difference('Task.count', -1) do
|
|
44
|
+
delete :destroy, id: @task
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
assert_redirected_to tasks_path
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ENV["RAILS_ENV"] ||= "test"
|
|
2
|
+
require File.expand_path('../../config/environment', __FILE__)
|
|
3
|
+
require 'rails/test_help'
|
|
4
|
+
|
|
5
|
+
class ActiveSupport::TestCase
|
|
6
|
+
ActiveRecord::Migration.check_pending!
|
|
7
|
+
|
|
8
|
+
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
|
|
9
|
+
#
|
|
10
|
+
# Note: You'll currently still have to declare fixtures explicitly in integration tests
|
|
11
|
+
# -- they do not yet inherit this setting
|
|
12
|
+
fixtures :all
|
|
13
|
+
|
|
14
|
+
# Add more helper methods to be used by all tests here...
|
|
15
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Copyright 2013 Google Inc. All Rights Reserved.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0, found in the LICENSE file.
|
|
3
|
+
|
|
4
|
+
require "bundler/setup"
|
|
5
|
+
require "rack"
|
|
6
|
+
require "allocation_stats"
|
|
7
|
+
|
|
8
|
+
require_relative "allocation_stats/action"
|
|
9
|
+
require_relative "allocation_stats/call_app_directly"
|
|
10
|
+
require_relative "allocation_stats/middleware"
|
|
11
|
+
require_relative "allocation_stats/tracer"
|
|
12
|
+
|
|
13
|
+
require_relative "allocation_stats/formatters/base"
|
|
14
|
+
require_relative "allocation_stats/formatters/html"
|
|
15
|
+
require_relative "allocation_stats/formatters/json"
|
|
16
|
+
require_relative "allocation_stats/formatters/text"
|
|
17
|
+
|
|
18
|
+
module Rack::AllocationStats
|
|
19
|
+
def self.new(app, options = {})
|
|
20
|
+
Middleware.new(app, options)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Copyright 2013 Google Inc. All Rights Reserved.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0, found in the LICENSE file.
|
|
3
|
+
|
|
4
|
+
module Rack::AllocationStats
|
|
5
|
+
class Action
|
|
6
|
+
def initialize(env, middleware)
|
|
7
|
+
@env = env
|
|
8
|
+
@request = Rack::Request.new(env)
|
|
9
|
+
@get_params = @request.GET.clone
|
|
10
|
+
@middleware = middleware
|
|
11
|
+
@stats = nil
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Copyright 2013 Google Inc. All Rights Reserved.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0, found in the LICENSE file.
|
|
3
|
+
|
|
4
|
+
module Rack::AllocationStats
|
|
5
|
+
class CallAppDirectly < Action
|
|
6
|
+
def act
|
|
7
|
+
@result = @middleware.call_app(@env)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def response
|
|
11
|
+
@result
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Copyright 2013 Google Inc. All Rights Reserved.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0, found in the LICENSE file.
|
|
3
|
+
|
|
4
|
+
module Rack::AllocationStats::Formatters
|
|
5
|
+
class Base
|
|
6
|
+
def initialize(tracer, allocations)
|
|
7
|
+
@tracer = tracer
|
|
8
|
+
@allocations = allocations
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Copyright 2013 Google Inc. All Rights Reserved.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0, found in the LICENSE file.
|
|
3
|
+
|
|
4
|
+
class Rack::AllocationStats::Formatters::HTML < Rack::AllocationStats::Formatters::Base
|
|
5
|
+
def format
|
|
6
|
+
interactive_dir = File.join(__dir__, "..", "interactive")
|
|
7
|
+
|
|
8
|
+
index_html_erb = ERB.new(File.read(File.join(interactive_dir, "index.html.erb")))
|
|
9
|
+
jquery_min_js = File.read(File.join(interactive_dir, "jquery-2.0.3.min.js"))
|
|
10
|
+
jquery_ui_min_js = File.read(File.join(interactive_dir, "jquery-ui-1.10.3.custom.min.js"))
|
|
11
|
+
underscore_min_js = File.read(File.join(interactive_dir, "underscore-min.js"))
|
|
12
|
+
allocations_js_erb = ERB.new(File.read(File.join(interactive_dir, "allocations.js.erb")))
|
|
13
|
+
allocations_js = allocations_js_erb.result(binding)
|
|
14
|
+
interactive_js = File.read(File.join(interactive_dir, "interactive.js"))
|
|
15
|
+
jquery_ui_min_css = File.read(File.join(interactive_dir, "jquery-ui-1.10.3.custom.min.css"))
|
|
16
|
+
style_css = File.read(File.join(interactive_dir, "style.css"))
|
|
17
|
+
|
|
18
|
+
allocating_gems = ["no gems allocated any objects"]
|
|
19
|
+
|
|
20
|
+
html_body = index_html_erb.result(binding)
|
|
21
|
+
return [html_body]
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Copyright 2013 Google Inc. All Rights Reserved.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0, found in the LICENSE file.
|
|
3
|
+
|
|
4
|
+
class Rack::AllocationStats::Formatters::JSON < Rack::AllocationStats::Formatters::Base
|
|
5
|
+
def format
|
|
6
|
+
allocations = @allocations.to_a.map do |group_key, allocations|
|
|
7
|
+
{ group_key: group_key, allocations: allocations }
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
return [Yajl::Encoder.encode(allocations)]
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Copyright 2013 Google Inc. All Rights Reserved.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0, found in the LICENSE file.
|
|
3
|
+
|
|
4
|
+
class Rack::AllocationStats::Formatters::Text < Rack::AllocationStats::Formatters::Base
|
|
5
|
+
def format
|
|
6
|
+
file_length = @allocations.inject(0) { |length, allocation| [allocation[0][0].length , length].max }
|
|
7
|
+
|
|
8
|
+
total_count = @tracer.stats.allocations.all.size
|
|
9
|
+
bytes = @tracer.stats.allocations.bytes.all.inject { |sum, e| sum + e }
|
|
10
|
+
sums = "Total: #{total_count} allocations; #{bytes} bytes\n\n"
|
|
11
|
+
|
|
12
|
+
body = []
|
|
13
|
+
|
|
14
|
+
if @tracer.gc_report
|
|
15
|
+
gc_report = @tracer.stats.gc_profiler_report + "\n\n"
|
|
16
|
+
body += [gc_report]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
running_total = 0
|
|
20
|
+
body + @allocations.map do |key, group|
|
|
21
|
+
sourcefile = key[0]
|
|
22
|
+
sourceline = key[1]
|
|
23
|
+
klass = key[2]
|
|
24
|
+
my_pct = (group.size * 1.0 / total_count) * 100
|
|
25
|
+
running_total += group.size
|
|
26
|
+
running_pct = (running_total * 1.0 / total_count) * 100
|
|
27
|
+
|
|
28
|
+
# TODO add a parameter to show/hide pct
|
|
29
|
+
#"%-#{file_length+4}s allocated %4d `%s` (%4.2f %4.2f)\n" % ["#{sourcefile}:#{sourceline}", group.size, klass, my_pct, running_pct]
|
|
30
|
+
"%-#{file_length+4}s allocated %4d `%s`\n" % ["#{sourcefile}:#{sourceline}", group.size, klass]
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Copyright 2013 Google Inc. All Rights Reserved.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0, found in the LICENSE file.
|
|
3
|
+
|
|
4
|
+
module Rack::AllocationStats
|
|
5
|
+
class Middleware
|
|
6
|
+
include Rack::Utils
|
|
7
|
+
|
|
8
|
+
def initialize(app, options = {})
|
|
9
|
+
@app = app
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def call(env)
|
|
13
|
+
@env = env
|
|
14
|
+
action = choose_action
|
|
15
|
+
action.act
|
|
16
|
+
action.response
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def call_app(env)
|
|
20
|
+
@app.call(env)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def choose_action
|
|
24
|
+
request = Rack::Request.new(@env)
|
|
25
|
+
if request.GET["ras"] && request.GET["ras"].has_key?("help")
|
|
26
|
+
@content_type = "text/plain"
|
|
27
|
+
help_text
|
|
28
|
+
elsif request.GET["ras"] && request.GET["ras"]["trace"]
|
|
29
|
+
@content_type = content_type(request.GET["ras"]["output"])
|
|
30
|
+
Tracer.new(@env, self)
|
|
31
|
+
else
|
|
32
|
+
CallAppDirectly.new(@env, self)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def content_type(output_type)
|
|
37
|
+
case output_type
|
|
38
|
+
when "interactive" then "text/html"
|
|
39
|
+
when "json" then "application/json"
|
|
40
|
+
else "text/plain"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def allocation_stats_response(body)
|
|
45
|
+
[200, headers(body), Array(body)]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def headers(body)
|
|
49
|
+
{
|
|
50
|
+
"Content-Type" => @content_type,
|
|
51
|
+
"Content-Length" => body.inject(0) { |len, part| len + bytesize(part) }.to_s
|
|
52
|
+
}
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def help_text
|
|
56
|
+
app = OpenStruct.new
|
|
57
|
+
app.body = [File.read(File.join(__dir__, "help.txt"))]
|
|
58
|
+
app.response = allocation_stats_response(app.body)
|
|
59
|
+
app
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Copyright 2013 Google Inc. All Rights Reserved.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0, found in the LICENSE file.
|
|
3
|
+
|
|
4
|
+
require 'yajl'
|
|
5
|
+
|
|
6
|
+
module Rack::AllocationStats
|
|
7
|
+
class Tracer < Action
|
|
8
|
+
include Rack::Utils
|
|
9
|
+
|
|
10
|
+
attr_reader :gc_report, :stats
|
|
11
|
+
|
|
12
|
+
def initialize(*args)
|
|
13
|
+
super
|
|
14
|
+
request = Rack::Request.new(@env)
|
|
15
|
+
|
|
16
|
+
# Once we're here, GET["ras"] better exist
|
|
17
|
+
@scope = request.GET["ras"]["scope"]
|
|
18
|
+
@times = (request.GET["ras"]["times"] || 1).to_i
|
|
19
|
+
@gc_report = request.GET["ras"]["gc_report"]
|
|
20
|
+
@output = (request.GET["ras"]["output"] || :columnar).to_sym
|
|
21
|
+
@alias_paths = request.GET["ras"]["alias_paths"] || false
|
|
22
|
+
@new_env = delete_custom_params(@env)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def act
|
|
26
|
+
@stats = AllocationStats.trace do
|
|
27
|
+
@times.times do
|
|
28
|
+
@middleware.call_app(@new_env)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def response
|
|
34
|
+
allocations = scoped_allocations
|
|
35
|
+
|
|
36
|
+
if @output == :interactive
|
|
37
|
+
allocations = allocations.all
|
|
38
|
+
@middleware.allocation_stats_response(Formatters::HTML.new(self, allocations).format)
|
|
39
|
+
elsif @output == :json
|
|
40
|
+
allocations = default_groups_and_sort(allocations)
|
|
41
|
+
@middleware.allocation_stats_response(Formatters::JSON.new(self, allocations).format)
|
|
42
|
+
else
|
|
43
|
+
allocations = default_groups_and_sort(allocations)
|
|
44
|
+
@middleware.allocation_stats_response(Formatters::Text.new(self, allocations).format)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def scoped_allocations
|
|
49
|
+
allocations = @stats.allocations(alias_paths: @alias_paths)
|
|
50
|
+
|
|
51
|
+
return allocations if @scope.nil?
|
|
52
|
+
|
|
53
|
+
if @scope == "."
|
|
54
|
+
return allocations.from_pwd
|
|
55
|
+
else
|
|
56
|
+
return allocations.from(@scope)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def default_groups_and_sort(allocations)
|
|
61
|
+
allocations.
|
|
62
|
+
group_by(:sourcefile, :sourceline, :class_plus).
|
|
63
|
+
sort_by_size.
|
|
64
|
+
all
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def delete_custom_params(env)
|
|
68
|
+
new_env = env
|
|
69
|
+
|
|
70
|
+
get_params = Rack::Request.new(new_env).GET
|
|
71
|
+
get_params.delete("ras")
|
|
72
|
+
|
|
73
|
+
new_env.delete("rack.request.query_string")
|
|
74
|
+
new_env.delete("rack.request.query_hash")
|
|
75
|
+
|
|
76
|
+
new_env["QUERY_STRING"] = build_query(get_params)
|
|
77
|
+
new_env
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
data/spec/factories.rb
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Copyright 2013 Google Inc. All Rights Reserved.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0, found in the LICENSE file.
|
|
3
|
+
|
|
4
|
+
FactoryGirl.define do
|
|
5
|
+
factory :allocation, class: AllocationStats::Allocation do
|
|
6
|
+
|
|
7
|
+
ignore do
|
|
8
|
+
object "A String"
|
|
9
|
+
sourcefile "foo/bar.rb"
|
|
10
|
+
sourceline 7
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
initialize_with { new(object) }
|
|
14
|
+
|
|
15
|
+
after(:build) do |allocation, evaluator|
|
|
16
|
+
allocation.instance_variable_set(:@sourcefile, evaluator.sourcefile)
|
|
17
|
+
allocation.instance_variable_set(:@sourceline, evaluator.sourceline)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# This might be overly complicated for now... but it was terribly fun to learn
|
|
22
|
+
# FactoryGirl's API, and I'll leave it for future use...
|
|
23
|
+
factory :stats, class: AllocationStats do
|
|
24
|
+
ignore do
|
|
25
|
+
size 5
|
|
26
|
+
files ["foo/bar.rb", "baz/quux.rb"]
|
|
27
|
+
sourceline 7
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
after(:build) do |stats, evaluator|
|
|
31
|
+
allocations = []
|
|
32
|
+
size = evaluator.size
|
|
33
|
+
files_count = evaluator.files.size
|
|
34
|
+
|
|
35
|
+
# 3 from 1st file
|
|
36
|
+
if size > 0
|
|
37
|
+
file = evaluator.files[0]
|
|
38
|
+
count = [size, 3].min
|
|
39
|
+
count.times { allocations << FactoryGirl.build(:allocation, sourcefile: file, sourceline: evaluator.sourceline) }
|
|
40
|
+
size -= count
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# more from 2nd file
|
|
44
|
+
if size > 0
|
|
45
|
+
file = evaluator.files[1 % files_count]
|
|
46
|
+
size.times { allocations << FactoryGirl.build(:allocation, sourcefile: file, sourceline: evaluator.sourceline) }
|
|
47
|
+
size -= count
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
stats.instance_variable_set(:@new_allocations, allocations)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Copyright 2013 Google Inc. All Rights Reserved.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0, found in the LICENSE file.
|
|
3
|
+
|
|
4
|
+
require "rack"
|
|
5
|
+
require "yaml"
|
|
6
|
+
|
|
7
|
+
class HelloWorldApp
|
|
8
|
+
FULL_PATH = __FILE__
|
|
9
|
+
|
|
10
|
+
attr_accessor :allocating_lines
|
|
11
|
+
|
|
12
|
+
def initialize
|
|
13
|
+
@allocating_lines = []
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def call(env)
|
|
17
|
+
a = "Ahhhhhhhhhhhhhhhhhhhhh"; @allocating_lines << __LINE__
|
|
18
|
+
#y = YAML.dump(["one string", "two string"]) # lots OF objects not from here
|
|
19
|
+
@allocating_lines << __LINE__; [200, {"Content-Type" => "text/html"}, ["Hello Rack!"]]
|
|
20
|
+
end
|
|
21
|
+
end
|