private_please 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -1
- data/.travis.yml +10 -0
- data/CHANGELOG +8 -0
- data/README.md +92 -42
- data/bin/pp_ruby +62 -0
- data/bin/ruby_pp +62 -0
- data/doc/dev_notes.txt +32 -0
- data/doc/fixtures/complex.rb +103 -0
- data/doc/fixtures/empty_class.rb +7 -0
- data/doc/fixtures/fixture_helper.rb +8 -0
- data/doc/fixtures/sample.rb +57 -0
- data/lib/private_please/candidate.rb +10 -2
- data/lib/private_please/report/table.rb +44 -0
- data/lib/private_please/report.rb +6 -0
- data/lib/private_please/reporter/base.rb +28 -0
- data/lib/private_please/reporter/helpers/options_helpers.rb +12 -0
- data/lib/private_please/reporter/helpers/text_table_helpers.rb +9 -0
- data/lib/private_please/{report/reporter.rb → reporter/simple_text.rb} +12 -18
- data/lib/private_please/reporter/templates/simple.txt.erb +77 -0
- data/lib/private_please/reporter.rb +8 -0
- data/lib/private_please/storage/methods_names.rb +1 -0
- data/lib/private_please/storage.rb +8 -0
- data/lib/private_please/tracking/extension.rb +3 -10
- data/lib/private_please/tracking/instrumentor.rb +13 -35
- data/lib/private_please/tracking/instruments_all_methods_below.rb +28 -0
- data/lib/private_please/tracking/instruments_automatically_all_methods_in_all_classes.rb +52 -0
- data/lib/private_please/tracking/line_change_tracker.rb +8 -18
- data/lib/private_please/tracking/utils.rb +34 -0
- data/lib/private_please/tracking.rb +48 -0
- data/lib/private_please/version.rb +1 -1
- data/lib/private_please.rb +27 -44
- data/private_please.gemspec +7 -1
- data/spec/{01_marking_candidate_methods_to_observe_spec.rb → 01_tracking_candidate_methods/explicitely_with_the_private_please_command_spec.rb} +35 -70
- data/spec/01_tracking_candidate_methods/systematically_in_auto_mode_spec.rb +187 -0
- data/spec/{02_logging_calls_on_candidate_methods_spec.rb → 03_logging_calls_on_candidate_methods_spec.rb} +2 -4
- data/spec/04_instrumented_program_activity_observation_result_spec.rb +2 -5
- data/spec/05_reporting/report_table_spec.rb +51 -0
- data/spec/06_at_exit_spec.rb +18 -0
- data/spec/fixtures/bug_22.rb +17 -0
- data/spec/fixtures/sample_class_for_report.rb +2 -0
- data/spec/sandbox/Gemfile +4 -0
- data/spec/sandbox/Gemfile.lock +14 -0
- data/spec/sandbox/README.txt +26 -0
- data/spec/sandbox/normal.rb +7 -0
- data/spec/sandbox/normal_prepended_with_require.rb +8 -0
- data/spec/spec_helper.rb +6 -2
- metadata +50 -13
- data/lib/private_please/report/templates/simple.txt.erb +0 -61
- data/lib/private_please/tracking/instruments_all_below.rb +0 -41
@@ -1,24 +1,14 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
1
2
|
require 'erb'
|
2
|
-
|
3
|
-
|
3
|
+
require File.dirname(__FILE__) + '/helpers/options_helpers'
|
4
|
+
require File.dirname(__FILE__) + '/helpers/text_table_helpers'
|
5
|
+
module PrivatePlease ; module Reporter
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
attr_reader :candidates_store, :calls_store,
|
8
|
-
:good_candidates, :bad_candidates,
|
9
|
-
:good_candidates_c, :bad_candidates_c,
|
10
|
-
:never_called_candidates, :never_called_candidates_c,
|
11
|
-
:building_time
|
12
|
-
|
13
|
-
|
14
|
-
def initialize(candidates_store, calls_store)
|
15
|
-
@candidates_store = candidates_store
|
16
|
-
@calls_store = calls_store
|
7
|
+
class SimpleText < Base
|
17
8
|
|
18
|
-
|
19
|
-
end
|
9
|
+
TEMPLATE_PATH = File.expand_path(File.dirname(__FILE__) + '/templates/simple.txt.erb')
|
20
10
|
|
21
|
-
def
|
11
|
+
def text
|
22
12
|
erb = ERB.new(File.read(TEMPLATE_PATH), 0, "%<>")
|
23
13
|
erb.result(binding)
|
24
14
|
end
|
@@ -29,7 +19,7 @@ module PrivatePlease ; module Report
|
|
29
19
|
start_time = Time.now
|
30
20
|
@bad_candidates = calls_store.external_calls .clone
|
31
21
|
@bad_candidates_c = calls_store.class_external_calls.clone
|
32
|
-
# TODO : optimize
|
22
|
+
# TODO : optimize (with Hamster?)
|
33
23
|
@good_candidates = calls_store.internal_calls .clone.remove(@bad_candidates)
|
34
24
|
@good_candidates_c= calls_store.class_internal_calls.clone.remove(@bad_candidates_c)
|
35
25
|
|
@@ -40,6 +30,9 @@ module PrivatePlease ; module Report
|
|
40
30
|
@never_called_candidates_c = candidates_store.class_methods.clone.
|
41
31
|
remove(@good_candidates_c).
|
42
32
|
remove(@bad_candidates_c )
|
33
|
+
[
|
34
|
+
@bad_candidates, @bad_candidates_c, @good_candidates, @good_candidates_c, @never_called_candidates, @never_called_candidates_c
|
35
|
+
].each {|arr| arr.reject!{|k, v| v.empty?}}
|
43
36
|
@building_time = Time.now - start_time
|
44
37
|
|
45
38
|
@candidates_classes_names = (candidates_store.instance_methods.classes_names +
|
@@ -49,4 +42,5 @@ module PrivatePlease ; module Report
|
|
49
42
|
@never_called_candidates_classes_names = (@never_called_candidates_c .classes_names + @never_called_candidates.classes_names).uniq.sort
|
50
43
|
end
|
51
44
|
end
|
45
|
+
|
52
46
|
end end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
====================================================================================
|
2
|
+
= PrivatePlease report : =
|
3
|
+
====================================================================================
|
4
|
+
% @candidates_classes_names .sort.each do |class_name|
|
5
|
+
%
|
6
|
+
% show_good_candidates_section = true
|
7
|
+
% show_bad_candidates_section = show_bad_candidates_section?
|
8
|
+
% show_never_candidates_section = show_never_called_candidates_section?
|
9
|
+
%
|
10
|
+
% if show_good_candidates_section
|
11
|
+
% good_candidates_table = table_for(
|
12
|
+
% names_from(class_name, good_candidates , prefix = "#"),
|
13
|
+
% names_from(class_name, good_candidates_c, prefix = "."))
|
14
|
+
% end
|
15
|
+
% if show_bad_candidates_section
|
16
|
+
% bad_candidates_table = table_for(
|
17
|
+
% names_from(class_name, bad_candidates , prefix = "#"),
|
18
|
+
% names_from(class_name, bad_candidates_c, prefix = "."))
|
19
|
+
% end
|
20
|
+
% if show_never_candidates_section
|
21
|
+
% never_called_candidates_table = table_for(
|
22
|
+
% names_from(class_name, never_called_candidates , prefix = "#"),
|
23
|
+
% names_from(class_name, never_called_candidates_c, prefix = "."))
|
24
|
+
% end
|
25
|
+
%
|
26
|
+
% # Always hide empty tables :
|
27
|
+
% ###########################
|
28
|
+
% show_good_candidates_section &&= !good_candidates_table.empty?
|
29
|
+
% show_bad_candidates_section &&= !bad_candidates_table.empty?
|
30
|
+
% show_never_candidates_section &&= !never_called_candidates_table.empty?
|
31
|
+
%
|
32
|
+
% nothing_to_show = !(show_good_candidates_section || show_bad_candidates_section || show_never_candidates_section)
|
33
|
+
% next if nothing_to_show && !show_empty_classes?
|
34
|
+
%
|
35
|
+
<%= class_name
|
36
|
+
%>
|
37
|
+
%
|
38
|
+
% if show_good_candidates_section
|
39
|
+
% t = good_candidates_table
|
40
|
+
|
41
|
+
* Good candidates : can be made private :
|
42
|
+
------------------------------------------
|
43
|
+
% cell_width = 3 + [38, t.longest_value_length].max
|
44
|
+
% t.rows.each do |inst_m, class_m|
|
45
|
+
<%= inst_m && inst_m.ljust(cell_width) %><%= class_m && class_m.ljust(cell_width) %>
|
46
|
+
% end
|
47
|
+
% end
|
48
|
+
%
|
49
|
+
% if show_bad_candidates_section
|
50
|
+
% t = bad_candidates_table
|
51
|
+
|
52
|
+
* Bad candidates : must stay public/protected:
|
53
|
+
. . . . . . . . . . . . . . . . . . . . .
|
54
|
+
% cell_width = 3 + [38, t.longest_value_length].max
|
55
|
+
% t.rows.each do |inst_m, class_m|
|
56
|
+
<%= inst_m && inst_m.ljust(cell_width) %><%= class_m && class_m.ljust(cell_width) %>
|
57
|
+
% end
|
58
|
+
% end
|
59
|
+
%
|
60
|
+
% if show_never_candidates_section
|
61
|
+
% t = never_called_candidates_table
|
62
|
+
|
63
|
+
* Methods that were never called :
|
64
|
+
. . . . . . . . . . . . . . . . . . . . .
|
65
|
+
% cell_width = 3 + [38, t.longest_value_length].max
|
66
|
+
% t.rows.each do |inst_m, class_m|
|
67
|
+
<%= inst_m && inst_m.ljust(cell_width) %><%= class_m && class_m.ljust(cell_width) %>
|
68
|
+
% end
|
69
|
+
% end
|
70
|
+
%
|
71
|
+
% end
|
72
|
+
|
73
|
+
====================================================================================
|
74
|
+
% if ENV['PP_OPTIONS']
|
75
|
+
Default display overriden :
|
76
|
+
$PP_OPTIONS = <%= ENV['PP_OPTIONS'].inspect %>
|
77
|
+
% end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module PrivatePlease
|
2
|
+
module Storage
|
3
|
+
end
|
4
|
+
end
|
5
|
+
require File.dirname(__FILE__) + '/storage/calls_store'
|
6
|
+
require File.dirname(__FILE__) + '/storage/candidates_store'
|
7
|
+
require File.dirname(__FILE__) + '/storage/methods_names'
|
8
|
+
require File.dirname(__FILE__) + '/storage/methods_names_bucket'
|
@@ -2,16 +2,9 @@ module PrivatePlease ; module Tracking
|
|
2
2
|
|
3
3
|
module Extension
|
4
4
|
|
5
|
-
def private_please
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
if parameterless_call
|
10
|
-
klass.send :include, PrivatePlease::Tracking::InstrumentsAllBelow
|
11
|
-
|
12
|
-
else
|
13
|
-
Instrumentor.instrument_instance_methods_for_pp_observation(klass, methods_to_observe)
|
14
|
-
end
|
5
|
+
def private_please
|
6
|
+
include PrivatePlease::Tracking::InstrumentsAllMethodsBelow
|
7
|
+
set_trace_func PrivatePlease::Tracking::LineChangeTracker::MY_TRACE_FUN
|
15
8
|
end
|
16
9
|
|
17
10
|
end
|
@@ -1,71 +1,49 @@
|
|
1
1
|
module PrivatePlease ; module Tracking
|
2
2
|
|
3
3
|
module Instrumentor
|
4
|
+
class << self
|
4
5
|
|
5
|
-
def
|
6
|
-
class_instance_methods = klass.instance_methods.collect(&:to_sym)
|
7
|
-
methods_to_observe = methods_to_observe.collect(&:to_sym)
|
8
|
-
# reject invalid methods names
|
9
|
-
methods_to_observe.reject! do |m|
|
10
|
-
already_defined_instance_method = class_instance_methods.include?(m)
|
11
|
-
invalid = !already_defined_instance_method
|
12
|
-
end
|
13
|
-
|
14
|
-
methods_to_observe.each do |method_name|
|
15
|
-
candidate = Candidate.for_instance_method(klass, method_name)
|
16
|
-
instrument_candidate_for_pp_observation(candidate) # end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
|
21
|
-
def self.instrument_candidate_for_pp_observation(candidate)
|
6
|
+
def add_call_tracking_code_to(candidate)
|
22
7
|
return if candidate.already_instrumented?
|
23
|
-
|
8
|
+
candidate.mark_as_instrumented
|
24
9
|
|
25
10
|
klass, method_name = candidate.klass, candidate.method_name
|
26
11
|
candidate.instance_method? ?
|
27
|
-
|
28
|
-
|
12
|
+
add_call_tracking_code_to_instance_method(klass, method_name) :
|
13
|
+
add_call_tracking_code_to_class_method( klass, method_name)
|
29
14
|
end
|
30
15
|
|
31
16
|
|
17
|
+
private
|
32
18
|
|
33
|
-
def
|
19
|
+
def add_call_tracking_code_to_class_method(klass, method_name)
|
34
20
|
orig_method = klass.singleton_class.instance_method(method_name)
|
35
21
|
klass.class_eval <<RUBY
|
36
22
|
define_singleton_method(method_name) do |*args, &blk| # def self.observed_method_i(..)
|
37
23
|
set_trace_func(nil) #don't track activity while here #
|
38
|
-
|
39
|
-
zelf_class=self #
|
40
|
-
candidate = PrivatePlease::Candidate.for_class_method(zelf_class, method_name)
|
41
|
-
PrivatePlease.after_method_call(candidate, LineChangeTracker.outside_class_method_call_detected?(zelf_class))
|
42
|
-
#
|
24
|
+
PrivatePlease::Tracking.after_singleton_method_call(method_name, self_class=self)
|
43
25
|
set_trace_func(LineChangeTracker::MY_TRACE_FUN) #
|
44
|
-
# make the call :
|
26
|
+
# make the original call : #
|
45
27
|
orig_method.bind(self).call(*args, &blk) # <call original method>
|
46
28
|
end # end
|
47
29
|
RUBY
|
48
30
|
end
|
49
|
-
private_class_method :instrument_class_method_with_pp_observation
|
50
31
|
|
51
32
|
|
52
|
-
def
|
33
|
+
def add_call_tracking_code_to_instance_method(klass, method_name)
|
53
34
|
orig_method = klass.instance_method(method_name)
|
54
35
|
klass.class_eval <<RUBY
|
55
36
|
define_method(method_name) do |*args, &blk| # def observed_method_i(..)
|
56
37
|
set_trace_func(nil) #don't track activity while here #
|
57
|
-
|
58
|
-
candidate = PrivatePlease::Candidate.for_instance_method(self.class, method_name)
|
59
|
-
PrivatePlease.after_method_call(candidate, LineChangeTracker.outside_instance_method_call_detected?(self)) #
|
60
|
-
#
|
38
|
+
PrivatePlease::Tracking.after_instance_method_call(method_name, self.class)
|
61
39
|
set_trace_func(LineChangeTracker::MY_TRACE_FUN) #
|
62
|
-
# make the call :
|
40
|
+
# make the original call : #
|
63
41
|
orig_method.bind(self).call(*args, &blk) # <call original method>
|
64
42
|
end # end
|
65
43
|
RUBY
|
66
44
|
end
|
67
|
-
private_class_method :instrument_instance_method_with_pp_observation
|
68
45
|
|
69
46
|
end
|
47
|
+
end
|
70
48
|
|
71
49
|
end end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module PrivatePlease ; module Tracking
|
2
|
+
|
3
|
+
module InstrumentsAllMethodsBelow
|
4
|
+
include PrivatePlease::Tracking::Extension
|
5
|
+
|
6
|
+
def self.included(base)
|
7
|
+
|
8
|
+
def base.singleton_method_added(method_name)
|
9
|
+
return if Utils.private_singleton_method?(self, method_name) \
|
10
|
+
|| Utils.singleton_method_defined_by_ancestor?(self, method_name)
|
11
|
+
|
12
|
+
candidate = Candidate.for_class_method(klass = self, method_name)
|
13
|
+
Instrumentor.add_call_tracking_code_to(candidate)
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def base.method_added(method_name)
|
18
|
+
return if Utils.private_instance_method?(self, method_name) \
|
19
|
+
|| Utils.instance_method_defined_by_ancestor?(self, method_name)
|
20
|
+
|
21
|
+
candidate = Candidate.for_instance_method(klass = self, method_name)
|
22
|
+
Instrumentor.add_call_tracking_code_to(candidate)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
|
2
|
+
class Class
|
3
|
+
|
4
|
+
def singleton_method_added(method_name)
|
5
|
+
return unless PrivatePlease.pp_automatic_mode_enabled?
|
6
|
+
|
7
|
+
return if PrivatePlease::Tracking::Utils.private_singleton_method?(self, method_name) \
|
8
|
+
|| PrivatePlease::Tracking::Utils.singleton_method_defined_by_ancestor?(self, method_name)
|
9
|
+
|
10
|
+
candidate = PrivatePlease::Candidate.for_class_method(klass = self, method_name)
|
11
|
+
PrivatePlease::Tracking::Instrumentor.add_call_tracking_code_to(candidate)
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
def method_added(method_name)
|
16
|
+
return unless PrivatePlease.pp_automatic_mode_enabled?
|
17
|
+
|
18
|
+
return if [:method_added].include?(method_name)
|
19
|
+
return if PrivatePlease::Tracking::Utils.private_instance_method?(self, method_name) \
|
20
|
+
|| PrivatePlease::Tracking::Utils.instance_method_defined_by_ancestor?(self, method_name)
|
21
|
+
|
22
|
+
candidate = PrivatePlease::Candidate.for_instance_method(klass = self, method_name)
|
23
|
+
PrivatePlease::Tracking::Instrumentor.add_call_tracking_code_to(candidate)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
class Module
|
30
|
+
|
31
|
+
def singleton_method_added(method_name)
|
32
|
+
return unless PrivatePlease.pp_automatic_mode_enabled?
|
33
|
+
|
34
|
+
return if [:included].include?(method_name) #&& !self.is_a?(Class)
|
35
|
+
return if PrivatePlease::Tracking::Utils.private_singleton_method?(self, method_name)
|
36
|
+
|
37
|
+
candidate = PrivatePlease::Candidate.for_class_method(klass = self, method_name)
|
38
|
+
PrivatePlease::Tracking::Instrumentor.add_call_tracking_code_to(candidate)
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
def method_added(method_name)
|
43
|
+
return unless PrivatePlease.pp_automatic_mode_enabled?
|
44
|
+
|
45
|
+
return if [:method_added, :singleton_method_added].include?(method_name)
|
46
|
+
return if PrivatePlease::Tracking::Utils.private_instance_method?(self, method_name)
|
47
|
+
|
48
|
+
candidate = PrivatePlease::Candidate.for_instance_method(klass = self, method_name)
|
49
|
+
PrivatePlease::Tracking::Instrumentor.add_call_tracking_code_to(candidate)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
@@ -2,8 +2,15 @@ module PrivatePlease ; module Tracking
|
|
2
2
|
|
3
3
|
class LineChangeTracker
|
4
4
|
class << self
|
5
|
+
|
5
6
|
attr_accessor :prev_prev_self, :prev_self, :curr_self
|
6
7
|
@@prev_self = @@curr_self = nil
|
8
|
+
|
9
|
+
alias :call_initiator :prev_self
|
10
|
+
|
11
|
+
def reset
|
12
|
+
prev_prev_self = prev_self = curr_self = nil
|
13
|
+
end
|
7
14
|
end
|
8
15
|
|
9
16
|
MY_TRACE_FUN = lambda do |event, file, line, id, binding, klass|
|
@@ -14,23 +21,6 @@ module PrivatePlease ; module Tracking
|
|
14
21
|
#puts "my : #{event} in #{file}/#{line} id:#{id} klass:#{klass} - self = #{(eval'self', binding).inspect}"
|
15
22
|
end
|
16
23
|
|
17
|
-
def self.outside_instance_method_call_detected?(zelf)
|
18
|
-
caller_class != zelf.class
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.outside_class_method_call_detected?(zelf_class)
|
22
|
-
caller_class != zelf_class
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def self.caller_class
|
28
|
-
call_initiator = LineChangeTracker.prev_self
|
29
|
-
(caller_is_class_method = call_initiator.is_a?(Class)) ?
|
30
|
-
call_initiator :
|
31
|
-
call_initiator.class
|
32
|
-
end
|
33
24
|
end
|
34
|
-
end end
|
35
25
|
|
36
|
-
|
26
|
+
end end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module PrivatePlease::Tracking
|
2
|
+
|
3
|
+
module Utils
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def private_instance_method?(klass, method_name)
|
7
|
+
klass.private_method_defined?(method_name)
|
8
|
+
end
|
9
|
+
|
10
|
+
def private_singleton_method?(klass, method_name)
|
11
|
+
klass.singleton_class.private_method_defined?(method_name)
|
12
|
+
end
|
13
|
+
|
14
|
+
def instance_method_defined_by_ancestor?(klass, method_name)
|
15
|
+
ancestor_of(klass).any? do |a|
|
16
|
+
a.method_defined?(method_name) || a.private_method_defined?(method_name)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def singleton_method_defined_by_ancestor?(klass, method_name)
|
21
|
+
ancestor_of(klass).any? do |a|
|
22
|
+
a.singleton_class.method_defined?(method_name) || a.singleton_class.private_method_defined?(method_name)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def ancestor_of(klass)
|
28
|
+
klass.ancestors - [klass]
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'private_please/tracking/line_change_tracker'
|
2
|
+
module PrivatePlease
|
3
|
+
module Tracking
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def after_instance_method_call(method_name, zelf_class)
|
8
|
+
store_call_to_tracked_method(
|
9
|
+
candidate = PrivatePlease::Candidate.for_instance_method(zelf_class, method_name),
|
10
|
+
is_outside_call = (caller_class != zelf_class)
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
def after_singleton_method_call(method_name, zelf_class)
|
15
|
+
store_call_to_tracked_method(
|
16
|
+
candidate = PrivatePlease::Candidate.for_class_method(zelf_class, method_name),
|
17
|
+
is_outside_call = (caller_class != zelf_class)
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def caller_class
|
24
|
+
call_initiator = LineChangeTracker.call_initiator
|
25
|
+
if call_initiator.nil?
|
26
|
+
#TODO : investigate why and how this happens
|
27
|
+
end
|
28
|
+
(caller_is_class_method = call_initiator.is_a?(Class)) ?
|
29
|
+
call_initiator :
|
30
|
+
call_initiator.class
|
31
|
+
end
|
32
|
+
|
33
|
+
def store_call_to_tracked_method(candidate, is_outside_call)
|
34
|
+
is_outside_call ?
|
35
|
+
PrivatePlease.calls_store.store_outside_call(candidate) :
|
36
|
+
PrivatePlease.calls_store.store_inside_call( candidate)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
require 'private_please/tracking/utils'
|
45
|
+
require 'private_please/tracking/instrumentor'
|
46
|
+
require 'private_please/tracking/extension'
|
47
|
+
require 'private_please/tracking/instruments_all_methods_below'
|
48
|
+
require 'private_please/tracking/instruments_automatically_all_methods_in_all_classes'
|
data/lib/private_please.rb
CHANGED
@@ -1,66 +1,49 @@
|
|
1
1
|
require 'private_please/version'
|
2
2
|
require 'private_please/ruby_backports'
|
3
3
|
require 'private_please/candidate'
|
4
|
-
require 'private_please/storage
|
5
|
-
require 'private_please/
|
6
|
-
require 'private_please/
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
require 'private_please/tracking/instrumentor'
|
12
|
-
require 'private_please/tracking/instruments_all_below'
|
4
|
+
require 'private_please/storage'
|
5
|
+
require 'private_please/report'
|
6
|
+
require 'private_please/reporter'
|
7
|
+
|
8
|
+
at_exit do
|
9
|
+
PrivatePlease.at_exit
|
10
|
+
end
|
13
11
|
|
14
12
|
module PrivatePlease
|
15
13
|
|
16
14
|
def self.install
|
17
15
|
Module.send :include, PrivatePlease::Tracking::Extension
|
16
|
+
PrivatePlease.pp_automatic_mode_enable
|
17
|
+
set_trace_func PrivatePlease::Tracking::LineChangeTracker::MY_TRACE_FUN
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
def self.after_method_call(candidate, outside_call)
|
25
|
-
outside_call ?
|
26
|
-
calls_store.store_outside_call(candidate) :
|
27
|
-
calls_store.store_inside_call(candidate)
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.remember_candidate(candidate)
|
31
|
-
candidates_store.store(candidate)
|
32
|
-
end
|
33
|
-
|
34
|
-
|
35
|
-
#--------------
|
36
|
-
# data & config containers :
|
37
|
-
#--------------
|
20
|
+
def self.pp_automatic_mode_enabled? ; !!$pp_automatic_mode_enabled end
|
21
|
+
def self.pp_automatic_mode_enable ; $pp_automatic_mode_enabled = true end
|
22
|
+
def self.pp_automatic_mode_disable ; $pp_automatic_mode_enabled = false end
|
38
23
|
|
39
|
-
|
40
|
-
|
24
|
+
# TODO : replace class methods by PP instance + instance methods
|
25
|
+
def self.calls_store
|
26
|
+
@@_calls_store ||= Storage::CallsStore.new
|
41
27
|
end
|
42
28
|
|
43
|
-
|
44
|
-
|
45
|
-
#--------------
|
46
|
-
|
47
|
-
def self.report
|
48
|
-
Report::Reporter.new(candidates_store, calls_store)
|
29
|
+
def self.candidates_store
|
30
|
+
@@_candidates_store ||= Storage::CandidatesStore.new
|
49
31
|
end
|
50
32
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
33
|
+
def self.reset
|
34
|
+
@@_candidates_store = @@_calls_store = nil
|
35
|
+
Tracking::LineChangeTracker.reset
|
36
|
+
set_trace_func nil
|
55
37
|
end
|
56
38
|
|
57
|
-
def self.
|
58
|
-
|
39
|
+
def self.at_exit
|
40
|
+
report = PrivatePlease::Reporter::SimpleText.new(PrivatePlease.candidates_store, PrivatePlease.calls_store)
|
41
|
+
unless $private_please_tests_are_running
|
42
|
+
$stdout.puts report.text
|
43
|
+
end
|
59
44
|
end
|
60
45
|
end
|
61
46
|
|
47
|
+
require 'private_please/tracking'
|
62
48
|
|
63
49
|
PrivatePlease.install
|
64
|
-
at_exit {
|
65
|
-
puts PrivatePlease.report.to_s
|
66
|
-
}
|
data/private_please.gemspec
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
2
|
+
if RUBY_VERSION == '1.8.7'
|
3
|
+
# avoid double-require of version.rb - see http://bit.ly/18lspBV
|
4
|
+
$:.unshift File.expand_path("../lib", __FILE__)
|
5
|
+
require "private_please/version"
|
6
|
+
else
|
7
|
+
require File.expand_path('../lib/private_please/version', __FILE__)
|
8
|
+
end
|
3
9
|
|
4
10
|
Gem::Specification.new do |gem|
|
5
11
|
gem.authors = ["Alain Ravet"]
|