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
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
|
+
[![Build Status](https://travis-ci.org/alainravet/private_please.png?branch=master)](https://travis-ci.org/alainravet/private_please) -
|
2
|
+
[![Code Climate](https://codeclimate.com/github/alainravet/private_please.png)](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
|