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
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
v0.0.4
|
2
|
+
- `private_please :foo, :bar` syntax is removed.
|
3
|
+
- auto-mode via `$ pp_ruby`
|
4
|
+
- improved report format (2 columns, empty sections are hidden, ..)
|
5
|
+
- report can be customized with PP_OPTIONS
|
6
|
+
- tested with 3 Ruby and 2 JRuby versions (Travis CI)
|
7
|
+
- big code cleanup (development)
|
8
|
+
|
1
9
|
v0.0.3
|
2
10
|
- private_please without parameters observes all the methods defined afterwards
|
3
11
|
- PP is active once you require the gem
|
data/README.md
CHANGED
@@ -1,70 +1,120 @@
|
|
1
|
-
|
1
|
+
[](https://travis-ci.org/alainravet/private_please) -
|
2
|
+
[](https://codeclimate.com/github/alainravet/private_please)
|
3
|
+
tested with Ruby (1.8.7, 1.9.3, and 2.0.0) and JRuby(1.8 and 1.9 mode) - see [.travis.yml](.travis.yml)
|
2
4
|
|
3
|
-
|
5
|
+
## TL;DR :
|
6
|
+
Given this code
|
7
|
+
```ruby
|
8
|
+
# file : big_code
|
9
|
+
class BigCode
|
10
|
+
def long_method # the only method that should be public
|
11
|
+
_part_1
|
12
|
+
_part_2
|
13
|
+
end
|
4
14
|
|
5
|
-
|
15
|
+
# PROBLEM : Those 2 methods were extracted and should be private
|
16
|
+
def _part_1
|
17
|
+
# ....
|
18
|
+
end
|
19
|
+
def _part_2
|
20
|
+
# ....
|
21
|
+
end
|
22
|
+
end
|
23
|
+
BigCode.new.long_method
|
24
|
+
```
|
25
|
+
When you run this command
|
26
|
+
```
|
27
|
+
$ pp_ruby big_code
|
28
|
+
^^^
|
29
|
+
```
|
30
|
+
Then the methods usage is tracked while the program runs and this findings report is output:
|
31
|
+
```
|
32
|
+
====================================================================================
|
33
|
+
= PrivatePlease report : =
|
34
|
+
====================================================================================
|
35
|
+
BigCode
|
6
36
|
|
7
|
-
|
37
|
+
* Good candidates : can be made private :
|
38
|
+
------------------------------------------
|
39
|
+
#_part_2
|
40
|
+
#_part_1
|
8
41
|
|
9
|
-
|
42
|
+
====================================================================================
|
43
|
+
```
|
10
44
|
|
11
|
-
##
|
45
|
+
## Installation
|
46
|
+
```
|
47
|
+
$ gem install private_please
|
48
|
+
```
|
12
49
|
|
13
|
-
|
50
|
+
## Usage : the 2 modes (auto and manual)
|
14
51
|
|
15
|
-
|
52
|
+
You can use *private_please* (*PP*) in either **auto-mode** or in **manual mode**.
|
53
|
+
Optionally you can customize the report contents with the env. variable ```PP_OPTIONS```.
|
16
54
|
|
17
|
-
|
18
|
-
|
19
|
-
# ...
|
20
|
-
end
|
55
|
+
- in **auto-mode** (the example above in TL;DR), you simply run your program with ```pp_ruby``` (instead of ```ruby```) and all your code is inspected by *PP* while it runs.
|
56
|
+
- in **manual mode** you must manually instrument (==add code to) each file you want *PP* to track and inspect.
|
21
57
|
|
22
|
-
private_please # step 2 : start observing
|
23
58
|
|
24
|
-
|
25
|
-
|
26
|
-
part_2
|
27
|
-
end
|
28
|
-
def part_1 ; end # only called by #do_the_thing => should be private (case #2)
|
29
|
-
def part_2 ; end # only called by #do_the_thing => should be private (case #2)
|
59
|
+
### Auto-mode
|
60
|
+
PP will run the program and track all the classes and methods that are defined.
|
30
61
|
|
31
|
-
|
32
|
-
|
62
|
+
How to :
|
63
|
+
- step 1 : use ```pp_ruby``` instead of ```ruby```.
|
33
64
|
|
34
|
-
|
35
|
-
|
65
|
+
Example :
|
66
|
+
```
|
67
|
+
$ bundle exec pp_ruby -Ilib normal.rb
|
68
|
+
^^^
|
36
69
|
```
|
37
|
-
A report is automatically printed
|
38
|
-
For the code above, the report would be :
|
70
|
+
A report is automatically printed when the program exits
|
39
71
|
|
40
|
-
====================================================================================
|
41
|
-
= PrivatePlease report : =
|
42
|
-
====================================================================================
|
43
72
|
|
44
|
-
|
45
|
-
|
46
|
-
**********************************************************
|
73
|
+
### Manual mode
|
74
|
+
You tell PP which classes and which methods to track.
|
47
75
|
|
48
|
-
|
49
|
-
|
76
|
+
How to :
|
77
|
+
- step 1 : Instrument your Ruby code
|
78
|
+
- step 2 : launch program as usual, with ```ruby```.
|
79
|
+
|
80
|
+
|
81
|
+
Example :
|
82
|
+
#### step 1 : Instrument your code
|
83
|
+
```ruby
|
84
|
+
# load PP
|
85
|
+
require 'private_please' <<<<<<< ADD THIS (only 1x in the whole program)
|
86
|
+
PrivatePlease.pp_automatic_mode_disable <<<<<<< " " " " " " " " "
|
50
87
|
|
51
|
-
|
52
|
-
#part_2
|
88
|
+
class BigCode
|
53
89
|
|
54
|
-
|
55
|
-
|
90
|
+
private_please << ~~ JUST ADD THIS in every file you want PP to inspect
|
91
|
+
<<
|
92
|
+
<< Meaning : "track the code below"
|
56
93
|
|
57
|
-
|
94
|
+
def long_method # the only method that should be public
|
95
|
+
_part_1
|
96
|
+
_part_2
|
97
|
+
end
|
58
98
|
|
59
|
-
|
60
|
-
|
99
|
+
def _part_1
|
100
|
+
# ....
|
101
|
+
end
|
102
|
+
def _part_2
|
103
|
+
# ....
|
104
|
+
end
|
105
|
+
end
|
61
106
|
|
62
|
-
|
107
|
+
BigCode.new.long_method
|
108
|
+
```
|
63
109
|
|
64
|
-
|
110
|
+
####step 2 : run you code normally
|
111
|
+
```
|
112
|
+
$ ruby big_code.rb
|
113
|
+
```
|
65
114
|
|
66
115
|
|
67
116
|
## Contributing
|
117
|
+
**Please respect and reuse the current code style and formatting**
|
68
118
|
|
69
119
|
1. Fork it
|
70
120
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
data/bin/pp_ruby
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# ----------------------------------------------------------------------------------- #
|
4
|
+
# Effects : inject PrivatePlease tracking in the command #
|
5
|
+
# ----------------------------------------------------------------------------------- #
|
6
|
+
# $ pp_ruby normal.rb #
|
7
|
+
# $ bundle exec pp_ruby normal.rb #
|
8
|
+
# become #
|
9
|
+
# $ ruby -rubygems -e "require 'private_please' ; load 'normal.rb'" #
|
10
|
+
# $ bundle exec ruby -e "require 'private_please' ; load 'normal.rb'" #
|
11
|
+
# ----------------------------------------------------------------------------------- #
|
12
|
+
|
13
|
+
|
14
|
+
########################
|
15
|
+
# Extract command parts :
|
16
|
+
########################
|
17
|
+
|
18
|
+
switches, filename, arguments = [], nil, []
|
19
|
+
loop do
|
20
|
+
case ARGV[0]
|
21
|
+
when '-r' then switches << ARGV.shift << ARGV.shift
|
22
|
+
when '-e' then switches << ARGV.shift << ARGV.shift.inspect
|
23
|
+
when /^-\S/ then switches << ARGV.shift
|
24
|
+
else break
|
25
|
+
end
|
26
|
+
end
|
27
|
+
filename = ARGV.shift
|
28
|
+
arguments = ARGV
|
29
|
+
|
30
|
+
|
31
|
+
######################
|
32
|
+
# Assemble new command :
|
33
|
+
######################
|
34
|
+
|
35
|
+
# ? called with `bundle exec ruby .....`
|
36
|
+
in_bundler_mode = !!defined?(Bundler)
|
37
|
+
|
38
|
+
program = in_bundler_mode ?
|
39
|
+
'bundle exec ruby' :
|
40
|
+
'ruby'
|
41
|
+
|
42
|
+
command = if filename
|
43
|
+
rubygems_or_not = in_bundler_mode ? nil : " -rubygems"
|
44
|
+
[ program,
|
45
|
+
switches,
|
46
|
+
%|#{rubygems_or_not} -e "require 'private_please' ; load '#{filename}'"| ,
|
47
|
+
arguments
|
48
|
+
]
|
49
|
+
else
|
50
|
+
[ program,
|
51
|
+
switches,
|
52
|
+
arguments
|
53
|
+
]
|
54
|
+
end.flatten.compact.join(' ')
|
55
|
+
|
56
|
+
|
57
|
+
#############################
|
58
|
+
# Execute transformed command :
|
59
|
+
#############################
|
60
|
+
|
61
|
+
puts "Executing: #{command}"
|
62
|
+
puts `#{command}`
|
data/bin/ruby_pp
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# ----------------------------------------------------------------------------------- #
|
4
|
+
# Effects : inject PrivatePlease tracking in the command #
|
5
|
+
# ----------------------------------------------------------------------------------- #
|
6
|
+
# $ pp_ruby normal.rb #
|
7
|
+
# $ bundle exec pp_ruby normal.rb #
|
8
|
+
# become #
|
9
|
+
# $ ruby -rubygems -e "require 'private_please' ; load 'normal.rb'" #
|
10
|
+
# $ bundle exec ruby -e "require 'private_please' ; load 'normal.rb'" #
|
11
|
+
# ----------------------------------------------------------------------------------- #
|
12
|
+
|
13
|
+
|
14
|
+
########################
|
15
|
+
# Extract command parts :
|
16
|
+
########################
|
17
|
+
|
18
|
+
switches, filename, arguments = [], nil, []
|
19
|
+
loop do
|
20
|
+
case ARGV[0]
|
21
|
+
when '-r' then switches << ARGV.shift << ARGV.shift
|
22
|
+
when '-e' then switches << ARGV.shift << ARGV.shift.inspect
|
23
|
+
when /^-\S/ then switches << ARGV.shift
|
24
|
+
else break
|
25
|
+
end
|
26
|
+
end
|
27
|
+
filename = ARGV.shift
|
28
|
+
arguments = ARGV
|
29
|
+
|
30
|
+
|
31
|
+
######################
|
32
|
+
# Assemble new command :
|
33
|
+
######################
|
34
|
+
|
35
|
+
# ? called with `bundle exec ruby .....`
|
36
|
+
in_bundler_mode = !!defined?(Bundler)
|
37
|
+
|
38
|
+
program = in_bundler_mode ?
|
39
|
+
'bundle exec ruby' :
|
40
|
+
'ruby'
|
41
|
+
|
42
|
+
command = if filename
|
43
|
+
rubygems_or_not = in_bundler_mode ? nil : " -rubygems"
|
44
|
+
[ program,
|
45
|
+
switches,
|
46
|
+
%|#{rubygems_or_not} -e "require 'private_please' ; load '#{filename}'"| ,
|
47
|
+
arguments
|
48
|
+
]
|
49
|
+
else
|
50
|
+
[ program,
|
51
|
+
switches,
|
52
|
+
arguments
|
53
|
+
]
|
54
|
+
end.flatten.compact.join(' ')
|
55
|
+
|
56
|
+
|
57
|
+
#############################
|
58
|
+
# Execute transformed command :
|
59
|
+
#############################
|
60
|
+
|
61
|
+
puts "Executing: #{command}"
|
62
|
+
puts `#{command}`
|
data/doc/dev_notes.txt
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
Q: Where is the TODO list :
|
2
|
+
A: https://github.com/alainravet/private_please/issues?state=open
|
3
|
+
|
4
|
+
How to run the tests :
|
5
|
+
========================
|
6
|
+
|
7
|
+
$ cd <project root>
|
8
|
+
$ bundle exec rspec
|
9
|
+
or
|
10
|
+
$ bundle exec guard # (see https://github.com/alainravet/private_please/issues/10)
|
11
|
+
|
12
|
+
|
13
|
+
How to test on multiple versions of Ruby :
|
14
|
+
============================================
|
15
|
+
# install rbenv + multiple versions of Ruby
|
16
|
+
# install the rbenv-each plugin
|
17
|
+
$ rbenv each -v bundle exec ruby -Ilib rspec
|
18
|
+
|
19
|
+
|
20
|
+
How to run the latest PP code on a custom Ruby code sample :
|
21
|
+
======================================================
|
22
|
+
|
23
|
+
$ cd <project root>
|
24
|
+
$ bundle exec ruby -Ilib doc/fixtures/complex.rb
|
25
|
+
|
26
|
+
How to display more than the list of methods that can be made private ?
|
27
|
+
======================================================
|
28
|
+
|
29
|
+
$ export PP_OPTIONS="--show-bad-candidates --show-never-called"
|
30
|
+
$ bundle exec ruby -Ilib doc/fixtures/complex.rb
|
31
|
+
or
|
32
|
+
$ PP_OPTIONS="--show-bad-candidates --show-never-called" bundle exec ruby -Ilib doc/fixtures/complex.rb
|
@@ -0,0 +1,103 @@
|
|
1
|
+
load File.dirname(__FILE__) + '/fixture_helper.rb'
|
2
|
+
|
3
|
+
module ComplexReport
|
4
|
+
|
5
|
+
class Class1
|
6
|
+
def initialize
|
7
|
+
super
|
8
|
+
end
|
9
|
+
def sole_entry_point
|
10
|
+
instance_m_1
|
11
|
+
self.class.class_m_1
|
12
|
+
self.class.c_make_internal_method_calls
|
13
|
+
end
|
14
|
+
|
15
|
+
def instance_m_1; end
|
16
|
+
def instance_m_2; end
|
17
|
+
|
18
|
+
def self.class_m_1;
|
19
|
+
class_m_2
|
20
|
+
end
|
21
|
+
def self.class_m_2; end
|
22
|
+
|
23
|
+
|
24
|
+
def self.c_make_internal_method_calls
|
25
|
+
class_m_1
|
26
|
+
new.instance_m_2
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
#-----------------------------------------------------------------------------------------------------------------------
|
33
|
+
|
34
|
+
ComplexReport::Class1.new.sole_entry_point
|
35
|
+
|
36
|
+
module ComplexReport
|
37
|
+
###########################################
|
38
|
+
class Simple # Internal calls : #
|
39
|
+
# -> called methods are _GOOD CANDIDATES_ #
|
40
|
+
def make_internal_calls ###########################################
|
41
|
+
instance_m_1 # i -> i
|
42
|
+
self.class.class_m_1 # i -> C
|
43
|
+
self.class.c_make_internal_method_calls # i -> C --> C
|
44
|
+
end # +-> i
|
45
|
+
|
46
|
+
def self.c_make_internal_method_calls #
|
47
|
+
class_m_1 # C -> C
|
48
|
+
new.instance_m_2 # C -> i
|
49
|
+
end #
|
50
|
+
end
|
51
|
+
|
52
|
+
#######################################################
|
53
|
+
class AnotherClass # External calls (would fail if methods were private) #
|
54
|
+
# -> called methods are _BAD CANDIDATES_ #
|
55
|
+
def make_external_calls #######################################################
|
56
|
+
Simple.new.instance_m_1 # i -> i
|
57
|
+
Simple .class_m_1 # i -> C
|
58
|
+
self.class.c_make_external_calls # i -> C -> i
|
59
|
+
end # -> C
|
60
|
+
def self.c_make_external_calls #
|
61
|
+
Simple.new.instance_m_1 # C -> i
|
62
|
+
Simple .class_m_1 # C -> C
|
63
|
+
end #
|
64
|
+
def call_the_candidate_from_inside_and_outside
|
65
|
+
make_external_calls
|
66
|
+
Simple.new.make_internal_calls
|
67
|
+
Simple.a_class_method_via_module_Extra
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
#-----------------------------------------------------------------------------------------------------------------------
|
72
|
+
module Extra
|
73
|
+
def self.included(base)
|
74
|
+
base.extend(ClassMethods)
|
75
|
+
end
|
76
|
+
def im_never_called ; raise; end
|
77
|
+
module ClassMethods
|
78
|
+
def a_class_method_via_module_Extra ; end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
class Simple
|
84
|
+
def self.not_a_candidate_c1;
|
85
|
+
class_m_2
|
86
|
+
end
|
87
|
+
|
88
|
+
include Extra
|
89
|
+
def instance_m_1; end
|
90
|
+
def instance_m_2; end
|
91
|
+
|
92
|
+
def self.class_m_1;
|
93
|
+
class_m_2
|
94
|
+
end
|
95
|
+
def self.class_m_2; end
|
96
|
+
|
97
|
+
def never_called_1; end
|
98
|
+
def self.class_never_called_1; end
|
99
|
+
end
|
100
|
+
#-----------------------------------------------------------------------------------------------------------------------
|
101
|
+
end
|
102
|
+
|
103
|
+
ComplexReport::AnotherClass.new.call_the_candidate_from_inside_and_outside
|
@@ -0,0 +1,57 @@
|
|
1
|
+
load File.dirname(__FILE__) + '/fixture_helper.rb'
|
2
|
+
|
3
|
+
module ReportSample
|
4
|
+
###########################################
|
5
|
+
class Simple # Internal calls : #
|
6
|
+
# -> called methods are _GOOD CANDIDATES_ #
|
7
|
+
def make_internal_calls ###########################################
|
8
|
+
instance_m_1 # i -> i
|
9
|
+
self.class.class_m_1 # i -> C
|
10
|
+
self.class.c_make_internal_method_calls # i -> C --> C
|
11
|
+
end # +-> i
|
12
|
+
|
13
|
+
def self.c_make_internal_method_calls #
|
14
|
+
class_m_1 # C -> C
|
15
|
+
new.instance_m_2 # C -> i
|
16
|
+
end #
|
17
|
+
end
|
18
|
+
|
19
|
+
#######################################################
|
20
|
+
class AnotherClass # External calls (would fail if methods were private) #
|
21
|
+
# -> called methods are _BAD CANDIDATES_ #
|
22
|
+
def make_external_calls #######################################################
|
23
|
+
Simple.new.instance_m_1 # i -> i
|
24
|
+
Simple .class_m_1 # i -> C
|
25
|
+
self.class.c_make_external_calls # i -> C -> i
|
26
|
+
end # -> C
|
27
|
+
def self.c_make_external_calls #
|
28
|
+
Simple.new.instance_m_1 # C -> i
|
29
|
+
Simple .class_m_1 # C -> C
|
30
|
+
end #
|
31
|
+
def call_the_candidate_from_inside_and_outside
|
32
|
+
make_external_calls
|
33
|
+
Simple.new.make_internal_calls
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
#-----------------------------------------------------------------------------------------------------------------------
|
38
|
+
class Simple
|
39
|
+
def self.not_a_candidate_c1;
|
40
|
+
class_m_2
|
41
|
+
end
|
42
|
+
|
43
|
+
def instance_m_1; end
|
44
|
+
def instance_m_2; end
|
45
|
+
|
46
|
+
def self.class_m_1;
|
47
|
+
class_m_2
|
48
|
+
end
|
49
|
+
def self.class_m_2; end
|
50
|
+
|
51
|
+
def never_called_1; end
|
52
|
+
def self.class_never_called_1; end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
#-----------------------------------------------------------------------------------------------------------------------
|
56
|
+
|
57
|
+
ReportSample::Simple.new.make_internal_calls
|
@@ -28,13 +28,21 @@ module PrivatePlease
|
|
28
28
|
alias_method :instance_method?, :is_instance_method
|
29
29
|
|
30
30
|
def already_instrumented?
|
31
|
-
|
31
|
+
instrumented_candidates_store.stored?(self)
|
32
32
|
end
|
33
33
|
|
34
|
+
#----------------------------------------------------------------------------
|
35
|
+
# SUGAR:
|
36
|
+
#----------------------------------------------------------------------------
|
37
|
+
|
38
|
+
def mark_as_instrumented
|
39
|
+
instrumented_candidates_store.store(self)
|
40
|
+
end
|
41
|
+
|
34
42
|
#----------------------------------------------------------------------------
|
35
43
|
private
|
36
44
|
|
37
|
-
def
|
45
|
+
def instrumented_candidates_store
|
38
46
|
PrivatePlease.candidates_store
|
39
47
|
end
|
40
48
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module PrivatePlease::Report
|
2
|
+
|
3
|
+
class Table
|
4
|
+
|
5
|
+
def initialize(col_1, col_2)
|
6
|
+
@col_1, @col_2 = col_1, col_2
|
7
|
+
|
8
|
+
prepare_data
|
9
|
+
end
|
10
|
+
|
11
|
+
#----------------------------------------------------------------------------
|
12
|
+
# QUERIES:
|
13
|
+
#----------------------------------------------------------------------------
|
14
|
+
|
15
|
+
attr_reader :col_1,
|
16
|
+
:col_2,
|
17
|
+
:rows,
|
18
|
+
:longest_value_length
|
19
|
+
|
20
|
+
def empty?
|
21
|
+
col_1.empty? && col_2.empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
#----------------------------------------------------------------------------
|
25
|
+
# COMMANDS:
|
26
|
+
#----------------------------------------------------------------------------
|
27
|
+
|
28
|
+
# none (immutable)
|
29
|
+
|
30
|
+
#----------------------------------------------------------------------------
|
31
|
+
private
|
32
|
+
|
33
|
+
def prepare_data
|
34
|
+
@longest_value_length = [col_1 + col_2].flatten.map(&:length).max || 0
|
35
|
+
|
36
|
+
# pad whichever column is shorter
|
37
|
+
@col_1[@col_2.length-1] ||= nil unless @col_2.empty?
|
38
|
+
@col_2[@col_1.length-1] ||= nil unless @col_1.empty?
|
39
|
+
|
40
|
+
@rows = @col_1.zip(@col_2)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module PrivatePlease ; module Reporter
|
2
|
+
|
3
|
+
class Base
|
4
|
+
|
5
|
+
attr_reader :candidates_store, :calls_store,
|
6
|
+
:good_candidates, :bad_candidates,
|
7
|
+
:good_candidates_c, :bad_candidates_c,
|
8
|
+
:never_called_candidates, :never_called_candidates_c,
|
9
|
+
:building_time
|
10
|
+
|
11
|
+
|
12
|
+
def initialize(candidates_store, calls_store)
|
13
|
+
@candidates_store = candidates_store
|
14
|
+
@calls_store = calls_store
|
15
|
+
|
16
|
+
start_time = Time.now
|
17
|
+
prepare_report_data
|
18
|
+
@building_time = Time.now - start_time
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def prepare_report_data
|
24
|
+
raise "prepare_report_data() ot implemented in the child class"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
|
2
|
+
def show_never_called_candidates_section?
|
3
|
+
ENV['PP_OPTIONS'] =~ /--show-never-called/
|
4
|
+
end
|
5
|
+
|
6
|
+
def show_bad_candidates_section?
|
7
|
+
ENV['PP_OPTIONS'] =~ /--show-bad-candidates/
|
8
|
+
end
|
9
|
+
|
10
|
+
def show_empty_classes?
|
11
|
+
ENV['PP_OPTIONS'] =~ /--show-empty-classes/
|
12
|
+
end
|