private_please 0.0.3 → 0.0.4
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 +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"]
|