private_please 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/.ruby-version +1 -0
  2. data/CHANGELOG +6 -0
  3. data/README.md +51 -7
  4. data/TODO +11 -13
  5. data/lib/private_please/candidate.rb +41 -0
  6. data/lib/private_please/report/reporter.rb +52 -0
  7. data/lib/private_please/report/templates/simple.txt.erb +61 -0
  8. data/lib/private_please/ruby_backports.rb +22 -0
  9. data/lib/private_please/storage/calls_store.rb +41 -0
  10. data/lib/private_please/storage/candidates_store.rb +48 -0
  11. data/lib/private_please/storage/methods_names.rb +9 -0
  12. data/lib/private_please/storage/methods_names_bucket.rb +69 -0
  13. data/lib/private_please/tracking/extension.rb +19 -0
  14. data/lib/private_please/tracking/instrumentor.rb +71 -0
  15. data/lib/private_please/tracking/instruments_all_below.rb +41 -0
  16. data/lib/private_please/tracking/line_change_tracker.rb +36 -0
  17. data/lib/private_please/version.rb +1 -1
  18. data/lib/private_please.rb +33 -50
  19. data/private_please.gemspec +1 -0
  20. data/sample.rb +68 -0
  21. data/spec/01_marking_candidate_methods_to_observe_spec.rb +153 -0
  22. data/spec/02_logging_calls_on_candidate_methods_spec.rb +39 -0
  23. data/spec/04_instrumented_program_activity_observation_result_spec.rb +89 -0
  24. data/spec/fixtures/sample_class_for_report.rb +54 -0
  25. data/spec/fixtures/sample_class_with_all_calls_combinations.rb +69 -0
  26. data/spec/spec_helper.rb +52 -1
  27. data/spec/units/calls_store_spec.rb +15 -0
  28. data/spec/units/candidates_store_spec.rb +55 -0
  29. metadata +58 -28
  30. data/lib/private_please/candidates.rb +0 -37
  31. data/lib/private_please/configuration.rb +0 -21
  32. data/lib/private_please/line_change_tracker.rb +0 -19
  33. data/lib/private_please/recorder.rb +0 -34
  34. data/lib/private_please/report/template.txt.erb +0 -15
  35. data/lib/private_please/report.rb +0 -47
  36. data/spec/01_marking_methods_spec.rb +0 -30
  37. data/spec/02_calling_methods_spec.rb +0 -58
  38. data/spec/03_configuration_spec.rb +0 -52
  39. data/spec/04_at_exit_report_printing_spec.rb +0 -47
@@ -1,83 +1,66 @@
1
1
  require 'private_please/version'
2
- require 'private_please/configuration'
3
- require 'private_please/candidates'
4
- require 'private_please/recorder'
5
- require 'private_please/report'
6
- require 'private_please/line_change_tracker'
2
+ require 'private_please/ruby_backports'
3
+ require 'private_please/candidate'
4
+ require 'private_please/storage/calls_store'
5
+ require 'private_please/storage/candidates_store'
6
+ require 'private_please/storage/methods_names'
7
+ require 'private_please/storage/methods_names_bucket'
8
+ require 'private_please/report/reporter'
9
+ require 'private_please/tracking/line_change_tracker'
10
+ require 'private_please/tracking/extension'
11
+ require 'private_please/tracking/instrumentor'
12
+ require 'private_please/tracking/instruments_all_below'
7
13
 
8
14
  module PrivatePlease
9
15
 
10
- def private_please(*args)
11
- klass = self
12
- args.reject!{|m| !klass.instance_methods.include?(m.to_s)}
13
- storage.candidates[klass.to_s] += args
14
- args.each do |m|
15
- mark_method(m)
16
- end
16
+ def self.install
17
+ Module.send :include, PrivatePlease::Tracking::Extension
17
18
  end
18
19
 
19
20
  #--------------
20
21
  # config
21
22
  #--------------
22
- def activate(flag)
23
- config.activate(flag)
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)
24
28
  end
25
29
 
26
- def active?
27
- !!config.active
30
+ def self.remember_candidate(candidate)
31
+ candidates_store.store(candidate)
28
32
  end
29
33
 
34
+
30
35
  #--------------
31
- # partners :
36
+ # data & config containers :
32
37
  #--------------
33
- def recorder ; Recorder .instance end
34
- def storage ; Candidates .instance end
35
- def config ; Configuration.instance end
36
38
 
37
39
  def self.reset_before_new_test
38
- Recorder .reset_before_new_test
39
- Candidates .reset_before_new_test
40
- Configuration .reset_before_new_test
40
+ @@_calls_store = @@_candidates_store = nil
41
41
  end
42
42
 
43
43
  #--------------
44
44
  # report
45
45
  #--------------
46
- def report
47
- Report.build(storage)
46
+
47
+ def self.report
48
+ Report::Reporter.new(candidates_store, calls_store)
48
49
  end
49
50
 
50
51
  private
51
52
 
52
- def mark_method(name)
53
- self_class = self.class
54
- PrivatePlease.recorder.record_candidate(self_class, name)
55
- orig_method = instance_method(name)
56
- define_method(name) do |*args, &blk|
57
- set_trace_func(nil) #don't track activity while here
58
-
59
- self_class = self.class
60
- if PrivatePlease.active?
61
- call_initiator = LineChangeTracker.prev_self
62
- is_outside_call = call_initiator.class != self_class
63
- is_outside_call ?
64
- PrivatePlease.recorder.record_outside_call(self_class, name) :
65
- PrivatePlease.recorder.record_inside_call( self_class, name)
66
- end
67
-
68
- # make the call :
69
- set_trace_func(LineChangeTracker::MY_TRACE_FUN)
70
- orig_method.bind(self).call(*args, &blk)
71
- end
53
+ def self.calls_store
54
+ @@_calls_store ||= Storage::CallsStore.new
72
55
  end
73
56
 
57
+ def self.candidates_store
58
+ @@_candidates_store ||= Storage::CandidatesStore.new
59
+ end
74
60
  end
75
61
 
76
- Module.send :include, PrivatePlease
77
62
 
63
+ PrivatePlease.install
78
64
  at_exit {
79
- if PrivatePlease.active?
80
- puts '-'*888
81
- puts PrivatePlease.report.to_s
82
- end
65
+ puts PrivatePlease.report.to_s
83
66
  }
@@ -18,4 +18,5 @@ Gem::Specification.new do |gem|
18
18
  gem.add_development_dependency 'rake' # to run 'All specs' in Rubymine
19
19
  gem.add_development_dependency 'rspec'
20
20
  gem.add_development_dependency 'guard-rspec'
21
+ gem.add_development_dependency 'rb-fsevent'
21
22
  end
data/sample.rb ADDED
@@ -0,0 +1,68 @@
1
+ # require 'private_please'
2
+ require 'lib/private_please' # use the latest version
3
+
4
+ module ReportSample
5
+ ###########################################
6
+ class Simple # Internal calls : #
7
+ # -> called methods are _GOOD CANDIDATES_ #
8
+ def make_internal_calls ###########################################
9
+ instance_m_1 # i -> i
10
+ instance_m_3 # i -> i
11
+ self.class.class_m_1 # i -> C
12
+ self.class.class_m_2 # i -> C
13
+ self.class.c_make_internal_method_calls # i -> C --> C
14
+ end # +-> i
15
+
16
+ def self.c_make_internal_method_calls #
17
+ class_m_1 # C -> C
18
+ new.instance_m_2 # C -> i
19
+ end #
20
+ end
21
+
22
+ #######################################################
23
+ class AnotherClass # External calls (would fail if methods were private) #
24
+ private_please # -> called methods are _BAD CANDIDATES_ #
25
+ def make_external_calls #######################################################
26
+ Simple.new.instance_m_1 # i -> i
27
+ Simple .class_m_1 # i -> C
28
+ self.class.c_make_external_calls # i -> C -> i
29
+ end # -> C
30
+ def self.c_make_external_calls #
31
+ Simple.new.instance_m_1 # C -> i
32
+ Simple .class_m_1 # C -> C
33
+ Simple .class_m_2 # C -> C
34
+ end #
35
+ def call_the_candidate_from_inside_and_outside
36
+ make_external_calls
37
+ Simple.new.make_internal_calls
38
+ end
39
+ def never_called; end
40
+ def self.never_called_c; end
41
+ end
42
+
43
+ #-----------------------------------------------------------------------------------------------------------------------
44
+ class Simple
45
+ def self.not_a_candidate_c1;
46
+ class_m_2
47
+ end
48
+
49
+ private_please
50
+ def instance_m_1; end
51
+ def instance_m_2; end
52
+ def instance_m_3; end
53
+
54
+ def self.class_m_1;
55
+ class_m_2
56
+ end
57
+ def self.class_m_2; end
58
+
59
+ def never_called_1; end
60
+ def self.class_never_called_1; end
61
+ end
62
+ end unless defined?(ReportSample::Simple)
63
+ #-----------------------------------------------------------------------------------------------------------------------
64
+
65
+ ReportSample::Simple.new.make_internal_calls
66
+ ReportSample::AnotherClass.new.make_external_calls
67
+ ReportSample::AnotherClass.c_make_external_calls
68
+
@@ -0,0 +1,153 @@
1
+ require 'spec_helper'
2
+
3
+ describe PrivatePlease, 'collecting the details of candidate-methods to observe' do
4
+ module MarkingTest; end
5
+
6
+ let(:candidates_store) { PrivatePlease.storage }
7
+
8
+ # ----------------
9
+ context 'observing with `private_please(<method names>)`' do
10
+ # ----------------
11
+
12
+ it('stores the instance methods names in the candidates list, indexed by their owning class') do
13
+ class MarkingTest::Simple1
14
+ def foo ; 'foo' end
15
+ def bar ; 'bar' end
16
+ def buz ; 'bar' end
17
+ private_please :bar, 'buz' # <<-- what we test
18
+ end
19
+
20
+ assert_instance_methods_candidates 'MarkingTest::Simple1' =>[:bar, :buz]
21
+ end
22
+
23
+
24
+ it('does not work with class methods') do
25
+ class MarkingTest::Simple1b
26
+ def self.found ; 'I am a class method' end
27
+ private_please :found # <<-- class method => not observed
28
+ end
29
+
30
+ assert_instance_methods_candidates ({})
31
+ assert_class_methods_candidates ({})
32
+ end
33
+
34
+ it('ignores invalid candidates (method not found in the class)') do
35
+ class MarkingTest::Simple2
36
+ def found ; 'foo' end
37
+ private_please :found # <<-- valid
38
+ private_please :not_found_method # <<-- not found => INvalid
39
+ end
40
+
41
+ assert_instance_methods_candidates 'MarkingTest::Simple2' =>[:found]
42
+ end
43
+
44
+ it('ignores duplicates') do
45
+ class MarkingTest::Simple3
46
+ def found ; 'foo' end
47
+ private_please :found #
48
+ private_please :found # duplicate -> ignore
49
+ end
50
+
51
+ assert_instance_methods_candidates 'MarkingTest::Simple3' =>[:found]
52
+ end
53
+ end
54
+
55
+
56
+ # ----------------
57
+ context 'observing with `private_please()`' do
58
+ # ----------------
59
+
60
+ example 'all the instance methods defined after `private_please` are stored as candidates' do
61
+
62
+ class MarkingTest::Automatic1
63
+ def foo ; end # NO (too early)
64
+ private_please # ---> # <start observing>
65
+ def baz ; end # *
66
+ public # *
67
+ def qux ; end # *
68
+ def included ; end # * special name, but valid candidate (in classes).
69
+ end
70
+ assert_instance_methods_candidates 'MarkingTest::Automatic1' =>[:baz, :qux, :included]
71
+ assert_class_methods_candidates ({})
72
+ end
73
+
74
+
75
+ example 'all the class methods defined after `private_please` are stored as candidates' do
76
+ class MarkingTest::Automatic1b
77
+ def self.foo ; end # NO (too early)
78
+ private_please # ---> # <start observing>
79
+ def self.baz ; end # YES
80
+ public # *
81
+ def self.qux ; end # YES
82
+ def self.included ; end # * special name, but valid candidate (in classes).
83
+ end
84
+
85
+ assert_instance_methods_candidates ({})
86
+ assert_class_methods_candidates 'MarkingTest::Automatic1b' =>[:baz, :qux, :included]
87
+ end
88
+
89
+ example ('already private methods are ignored/not observed') do
90
+ class MarkingTest::Automatic1c
91
+ private_please # ---> # <start observing>
92
+ def self.baz ; end # YES
93
+ public # *
94
+ def qux ; end # YES
95
+ private #
96
+ def already_private ; end # NO
97
+ class << self
98
+ private
99
+ def class_already_private ; end # NO
100
+ end
101
+ end
102
+
103
+ assert_instance_methods_candidates 'MarkingTest::Automatic1c' =>[:qux]
104
+ assert_class_methods_candidates 'MarkingTest::Automatic1c' =>[:baz]
105
+ end
106
+
107
+
108
+ example 'method coming from an included module are observed too' do
109
+ #TODO : find a better way to instrument modules
110
+ #TODO : find a way to instrument modules automatically (? possible)
111
+
112
+ module Extra002 ; private_please end # <<=== Pre-instrument.
113
+ module Extra002::ClassMethods ; private_please end # <<=== Pre-instrument.
114
+
115
+ module Extra002 # Reopen the pre-instrumented
116
+ def im_from_module ; end # module.
117
+ def self.included(base) #
118
+ base.extend ClassMethods #
119
+ end #
120
+ module ClassMethods #
121
+ def cm_from_modulex ; end #
122
+ end #
123
+ end #
124
+ assert_instance_methods_candidates 'Extra002' =>[:im_from_module],
125
+ 'Extra002::ClassMethods' =>[:cm_from_module]
126
+ assert_class_methods_candidates ({})
127
+ end
128
+ end
129
+
130
+
131
+ # ----------------
132
+ context 'observing with `include PrivatePlease::Tracking::InstrumentsAllBelow`' do
133
+ # ----------------
134
+
135
+ example 'all the methods defined subsequently are stored as candidates' do
136
+
137
+ class MarkingTest::Automatic2
138
+ def foo ; end
139
+ def bar ; end
140
+ include PrivatePlease::Tracking::InstrumentsAllBelow # ---> # <start observing>
141
+ def baz ; end # YES
142
+ def self.class_m1; end # YES
143
+ protected #
144
+ def qux ; end # YES
145
+ end
146
+
147
+ assert_instance_methods_candidates 'MarkingTest::Automatic2' =>[:baz, :qux]
148
+ assert_class_methods_candidates 'MarkingTest::Automatic2' =>[:class_m1]
149
+ end
150
+
151
+ end
152
+
153
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe PrivatePlease, 'calling observed methods and logging calls in 2 categories : internal or external' do
4
+
5
+ before do
6
+ #-----------------------------------------------------------------------------------------------------------------------
7
+ require File.dirname(__FILE__) + '/fixtures/sample_class_with_all_calls_combinations'
8
+ #-----------------------------------------------------------------------------------------------------------------------
9
+ end
10
+
11
+
12
+ NO_CALLS_OBSERVED = {}
13
+
14
+ example ('pure internal calls are categorized correctly') do
15
+ CallsSample::Simple.new.make_internal_calls
16
+ assert_calls_detected :inside => {'CallsSample::Simple' => mnames_for([:instance_m_1, :instance_m_2])},
17
+ :outside => NO_CALLS_OBSERVED,
18
+ :inside_c => {'CallsSample::Simple' => mnames_for([:class_m_1, :class_m_2])},
19
+ :outside_c => NO_CALLS_OBSERVED
20
+ end
21
+
22
+ example ('pure external calls are categorized correctly') do
23
+ CallsSample::AnotherClass.new.make_external_calls
24
+ assert_calls_detected :inside => NO_CALLS_OBSERVED,
25
+ :outside => {'CallsSample::Simple' => mnames_for([:instance_m_1])},
26
+ :inside_c => {'CallsSample::Simple' => mnames_for([:class_m_2])},
27
+ :outside_c => {'CallsSample::Simple' => mnames_for([:class_m_1])}
28
+ end
29
+
30
+ example('when a method is called both from inside and from outside its class, it is recorded is both categories') do
31
+ CallsSample::AnotherClass.new.call_the_candidate_from_inside_and_outside
32
+ assert_calls_detected :inside => {'CallsSample::Simple' => mnames_for([:instance_m_1, :instance_m_2])},
33
+ :outside => {'CallsSample::Simple' => mnames_for([:instance_m_1])},
34
+ :inside_c => {'CallsSample::Simple' => mnames_for([:class_m_2, :class_m_1])},
35
+ :outside_c => {'CallsSample::Simple' => mnames_for([:class_m_1])}
36
+ end
37
+
38
+ #-----------------------------------------------------------------------------------------------------------------------
39
+ end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'PrivatePlease.report', 'observing an instrumented program activity' do
4
+
5
+ def run_the_instrumented_program
6
+ ActivityTest::Simple.new.tap do |o|
7
+ o.not_a_candidate_1
8
+ o.not_a_candidate_2
9
+ o.class.not_a_candidate_c1
10
+ o.bad_candidate_3
11
+ o.bad_candidate_6
12
+ o.class.bad_candidate_c3
13
+ end
14
+ ActivityTest::Simple2.new.bad_candidate_too
15
+ ActivityTest::Simple2 .bad_candidate_c_too
16
+ end
17
+
18
+ before do
19
+
20
+ module ActivityTest
21
+ class Simple
22
+ def not_a_candidate_1; bad_candidate_3 end
23
+ def not_a_candidate_2; good_candidate_7 end
24
+ def self.not_a_candidate_c1;
25
+ good_candidate_c2
26
+ end
27
+ private_please
28
+ def bad_candidate_3; good_candidate_4 end
29
+ def good_candidate_4; good_candidate_5 end
30
+ def good_candidate_5; bad_candidate_6 end
31
+ def bad_candidate_6; good_candidate_7 end
32
+ def good_candidate_7; end
33
+ def ignored_8 ; 'never called' end
34
+ def self.ignored_c9 ; 'never called' end
35
+ def self.good_candidate_c2; end
36
+ def self.bad_candidate_c3; end
37
+ end
38
+
39
+ class Simple2
40
+ private_please
41
+ def bad_candidate_too; end
42
+ def ignored_2; 'never called' end
43
+ def self.ignored_c3; 'never called' end
44
+ def self.bad_candidate_c_too; end
45
+ end
46
+ end unless defined?(ActivityTest::Simple)
47
+ end
48
+
49
+ # Note: test all in 1 go because testing in bits would fail, and it differs from real usage.
50
+ it 'obtains the right info by observing the program activity' do
51
+ run_the_instrumented_program
52
+ the_report = PrivatePlease.report
53
+ {
54
+ :good_candidates => the_report.good_candidates,
55
+ :good_candidates_c => the_report.good_candidates_c,
56
+ :bad_candidates => the_report.bad_candidates,
57
+ :bad_candidates_c => the_report.bad_candidates_c,
58
+ :ignored => the_report.never_called_candidates,
59
+ :ignored_c => the_report.never_called_candidates_c
60
+ }.should == {
61
+ :good_candidates => {
62
+ 'ActivityTest::Simple' => mnames_for([:good_candidate_4, :good_candidate_5, :good_candidate_7])
63
+ },
64
+ :good_candidates_c => {
65
+ 'ActivityTest::Simple' => mnames_for([:good_candidate_c2])
66
+ },
67
+ :bad_candidates => {
68
+ 'ActivityTest::Simple' => mnames_for([:bad_candidate_3, :bad_candidate_6]),
69
+ 'ActivityTest::Simple2' => mnames_for([:bad_candidate_too])
70
+ },
71
+ :bad_candidates_c => {
72
+ 'ActivityTest::Simple' => mnames_for([:bad_candidate_c3]),
73
+ 'ActivityTest::Simple2' => mnames_for([:bad_candidate_c_too])
74
+ },
75
+ :ignored => {
76
+ 'ActivityTest::Simple' => mnames_for([:ignored_8]),
77
+ 'ActivityTest::Simple2' => mnames_for([:ignored_2])
78
+ },
79
+ :ignored_c => {
80
+ 'ActivityTest::Simple' => mnames_for([:ignored_c9]),
81
+ 'ActivityTest::Simple2' => mnames_for([:ignored_c3])
82
+ }
83
+ }
84
+ puts the_report.to_s
85
+ puts "\n***report building time : #{the_report.building_time} sec."
86
+
87
+ end
88
+
89
+ end
@@ -0,0 +1,54 @@
1
+ module ReportSample
2
+ ###########################################
3
+ class Simple # Internal calls : #
4
+ # -> called methods are _GOOD CANDIDATES_ #
5
+ def make_internal_calls ###########################################
6
+ instance_m_1 # i -> i
7
+ self.class.class_m_1 # i -> C
8
+ self.class.c_make_internal_method_calls # i -> C --> C
9
+ end # +-> i
10
+
11
+ def self.c_make_internal_method_calls #
12
+ class_m_1 # C -> C
13
+ new.instance_m_2 # C -> i
14
+ end #
15
+ end
16
+
17
+ #######################################################
18
+ class AnotherClass # External calls (would fail if methods were private) #
19
+ # -> called methods are _BAD CANDIDATES_ #
20
+ def make_external_calls #######################################################
21
+ Simple.new.instance_m_1 # i -> i
22
+ Simple .class_m_1 # i -> C
23
+ self.class.c_make_external_calls # i -> C -> i
24
+ end # -> C
25
+ def self.c_make_external_calls #
26
+ Simple.new.instance_m_1 # C -> i
27
+ Simple .class_m_1 # C -> C
28
+ end #
29
+ def call_the_candidate_from_inside_and_outside
30
+ make_external_calls
31
+ Simple.new.make_internal_calls
32
+ end
33
+ end
34
+
35
+ #-----------------------------------------------------------------------------------------------------------------------
36
+ class Simple
37
+ def self.not_a_candidate_c1;
38
+ class_m_2
39
+ end
40
+
41
+ private_please
42
+ def instance_m_1; end
43
+ def instance_m_2; end
44
+
45
+ def self.class_m_1;
46
+ class_m_2
47
+ end
48
+ def self.class_m_2; end
49
+
50
+ def never_called_1; end
51
+ def self.class_never_called_1; end
52
+ end
53
+ end unless defined?(ReportSample::Simple)
54
+ #-----------------------------------------------------------------------------------------------------------------------
@@ -0,0 +1,69 @@
1
+ module CallsSample
2
+ ###########################################
3
+ class Simple # Internal calls : #
4
+ # -> called methods are _GOOD CANDIDATES_ #
5
+ def make_internal_calls ###########################################
6
+ instance_m_1 # i -> i
7
+ self.class.class_m_1 # i -> C
8
+ self.class.c_make_internal_method_calls # i -> C --> C
9
+ end # +-> i
10
+
11
+ def self.c_make_internal_method_calls #
12
+ class_m_1 # C -> C
13
+ new.instance_m_2 # C -> i
14
+ end #
15
+ end
16
+
17
+ #######################################################
18
+ class AnotherClass # External calls (would fail if methods were private) #
19
+ # -> called methods are _BAD CANDIDATES_ #
20
+ def make_external_calls #######################################################
21
+ Simple.new.instance_m_1 # i -> i
22
+ Simple .class_m_1 # i -> C
23
+ self.class.c_make_external_calls # i -> C -> i
24
+ end # -> C
25
+ def self.c_make_external_calls #
26
+ Simple.new.instance_m_1 # C -> i
27
+ Simple .class_m_1 # C -> C
28
+ end #
29
+ def call_the_candidate_from_inside_and_outside
30
+ make_external_calls
31
+ CallsSample::Simple.new.make_internal_calls
32
+ end
33
+ end
34
+
35
+ #-----------------------------------------------------------------------------------------------------------------------
36
+ module Extra ; private_please end # <<=== Pre-instrument.
37
+ module Extra::ClassMethods ; private_please end # <<=== Pre-instrument.
38
+
39
+ module Extra
40
+ def self.included(base)
41
+ base.extend(ClassMethods)
42
+ end
43
+ def an_instance_method ; end
44
+ module ClassMethods
45
+ def a_class_method_via_module_Extra ; end
46
+ end
47
+ end
48
+
49
+
50
+ class Simple
51
+ def self.not_a_candidate_c1;
52
+ class_m_2
53
+ end
54
+
55
+ private_please
56
+ include Extra
57
+ def instance_m_1; end
58
+ def instance_m_2; end
59
+
60
+ def self.class_m_1;
61
+ class_m_2
62
+ end
63
+ def self.class_m_2; end
64
+
65
+ def never_called_1; end
66
+ def self.class_never_called_1; end
67
+ end
68
+ #-----------------------------------------------------------------------------------------------------------------------
69
+ end unless defined?(CallsSample::Simple)
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,60 @@
1
- # This file was generated by the `rspec --init` command. Conventionally, all
1
+ # This file was (originally) generated by the `rspec --init` command. Conventionally, all
2
2
  # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
3
  # Require this file using `require "spec_helper"` to ensure that it is only
4
4
  # loaded once.
5
5
  #
6
6
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+
8
+ module PrivatePlease
9
+ def self.reset_before_new_test
10
+ PrivatePlease .reset_before_new_test
11
+ end
12
+ end
13
+
14
+ class Hash
15
+ def to_methods_names_bucket
16
+ PrivatePlease::Storage::MethodsNamesBucket.new.tap do |bucket|
17
+ each_pair do |class_name, method_names_as_a|
18
+ method_names_as_a.each do |method_name|
19
+ bucket.add_method_name(class_name, method_name)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ def assert_instance_methods_candidates(raw_expected)
27
+ expected = raw_expected.to_methods_names_bucket if raw_expected.is_a?(Hash)
28
+ PrivatePlease.candidates_store.instance_methods.should == expected
29
+ end
30
+
31
+ def assert_class_methods_candidates(raw_expected)
32
+ expected = raw_expected.to_methods_names_bucket if raw_expected.is_a?(Hash)
33
+ PrivatePlease.candidates_store.class_methods.should == expected
34
+ end
35
+
36
+
37
+
38
+ def assert_calls_detected(expected)
39
+ calls_db = PrivatePlease.calls_store
40
+ { :inside => calls_db.internal_calls,
41
+ :inside_c => calls_db.class_internal_calls,
42
+ :outside => calls_db.external_calls,
43
+ :outside_c => calls_db.class_external_calls
44
+ }.should == expected
45
+ end
46
+
47
+ NO_CALLS_OBSERVED = {}
48
+
49
+ def assert_no_calls_detected
50
+ assert_calls_detected :inside => NO_CALLS_OBSERVED, :outside => NO_CALLS_OBSERVED,
51
+ :inside_c => NO_CALLS_OBSERVED, :outside_c => NO_CALLS_OBSERVED
52
+ end
53
+
54
+ def mnames_for(args)
55
+ PrivatePlease::Storage::MethodsNames.new(Array(args))
56
+ end
57
+
7
58
  RSpec.configure do |config|
8
59
  config.treat_symbols_as_metadata_keys_with_true_values = true
9
60
  config.run_all_when_everything_filtered = true
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe PrivatePlease::Storage::CallsStore do
5
+
6
+ let(:calls_store ) { PrivatePlease::Storage::CallsStore.new }
7
+
8
+ context 'when fresh' do
9
+ it 'is empty (has no calls)' do
10
+ calls_store.internal_calls .should be_empty
11
+ calls_store.external_calls .should be_empty
12
+ end
13
+ end
14
+
15
+ end