turbulence 1.2.4 → 1.4.0
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.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +51 -0
- data/CHANGELOG.md +227 -0
- data/Gemfile.lock +47 -24
- data/LICENSE.txt +7 -0
- data/README.md +100 -31
- data/bin/bule +1 -1
- data/docs/scatter-plot.png +0 -0
- data/docs/treemap.png +0 -0
- data/lib/turbulence/calculators/churn.rb +3 -1
- data/lib/turbulence/calculators/complexity.rb +4 -16
- data/lib/turbulence/cli_parser.rb +12 -1
- data/lib/turbulence/command_line_interface.rb +28 -3
- data/lib/turbulence/configuration.rb +10 -6
- data/lib/turbulence/generators/scatterplot.rb +10 -4
- data/lib/turbulence/generators/treemap.rb +14 -10
- data/lib/turbulence/scm/git.rb +1 -1
- data/lib/turbulence/version.rb +1 -1
- data/lib/turbulence.rb +1 -1
- data/spec/turbulence/calculators/churn_spec.rb +50 -62
- data/spec/turbulence/calculators/complexity_spec.rb +2 -5
- data/spec/turbulence/cli_parser_spec.rb +16 -6
- data/spec/turbulence/command_line_interface_spec.rb +59 -7
- data/spec/turbulence/configuration_spec.rb +11 -5
- data/spec/turbulence/generators/scatter_plot_spec.rb +49 -44
- data/spec/turbulence/generators/treemap_spec.rb +7 -7
- data/spec/turbulence/scm/git_spec.rb +7 -6
- data/spec/turbulence/scm/perforce_spec.rb +44 -40
- data/spec/turbulence/turbulence_spec.rb +4 -4
- data/template/highcharts-heatmap.js +23 -0
- data/template/highcharts-treemap.js +11 -0
- data/template/highcharts.js +28 -162
- data/template/treemap.html +121 -27
- data/template/turbulence.html +34 -12
- data/turbulence.gemspec +13 -9
- metadata +61 -29
- data/.travis.yml +0 -6
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'fileutils'
|
|
2
|
+
require 'json'
|
|
2
3
|
require 'launchy'
|
|
3
4
|
require 'optparse'
|
|
4
5
|
require 'forwardable'
|
|
@@ -14,6 +15,8 @@ class Turbulence
|
|
|
14
15
|
TEMPLATE_FILES = [
|
|
15
16
|
'turbulence.html',
|
|
16
17
|
'highcharts.js',
|
|
18
|
+
'highcharts-heatmap.js',
|
|
19
|
+
'highcharts-treemap.js',
|
|
17
20
|
'jquery.min.js',
|
|
18
21
|
'treemap.html',
|
|
19
22
|
].map do |filename|
|
|
@@ -31,16 +34,38 @@ class Turbulence
|
|
|
31
34
|
:directory,
|
|
32
35
|
:graph_type,
|
|
33
36
|
:exclusion_pattern,
|
|
37
|
+
:no_open,
|
|
38
|
+
:output_dir,
|
|
39
|
+
:json_output,
|
|
34
40
|
]
|
|
35
41
|
|
|
42
|
+
def output_path
|
|
43
|
+
output_dir || File.join(Dir.pwd, "turbulence")
|
|
44
|
+
end
|
|
45
|
+
|
|
36
46
|
def copy_templates_into(directory)
|
|
37
47
|
FileUtils.cp TEMPLATE_FILES, directory
|
|
38
48
|
end
|
|
39
49
|
|
|
40
50
|
def generate_bundle
|
|
41
|
-
|
|
51
|
+
if json_output
|
|
52
|
+
generate_json
|
|
53
|
+
else
|
|
54
|
+
generate_html
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def generate_json
|
|
59
|
+
# Suppress progress output for clean JSON
|
|
60
|
+
config.output = nil
|
|
61
|
+
turb = Turbulence.new(config)
|
|
62
|
+
puts JSON.pretty_generate(turb.metrics)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def generate_html
|
|
66
|
+
FileUtils.mkdir_p(output_path)
|
|
42
67
|
|
|
43
|
-
Dir.chdir(
|
|
68
|
+
Dir.chdir(output_path) do
|
|
44
69
|
turb = Turbulence.new(config)
|
|
45
70
|
|
|
46
71
|
generator = case graph_type
|
|
@@ -55,7 +80,7 @@ class Turbulence
|
|
|
55
80
|
end
|
|
56
81
|
|
|
57
82
|
def open_bundle
|
|
58
|
-
Launchy.open("file:///#{
|
|
83
|
+
Launchy.open("file:///#{output_path}/#{graph_type}.html")
|
|
59
84
|
end
|
|
60
85
|
end
|
|
61
86
|
end
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'ostruct'
|
|
2
|
-
|
|
3
1
|
class Turbulence
|
|
4
2
|
class Configuration
|
|
5
3
|
attr_accessor *[
|
|
@@ -11,13 +9,19 @@ class Turbulence
|
|
|
11
9
|
:exclusion_pattern,
|
|
12
10
|
:graph_type,
|
|
13
11
|
:output,
|
|
12
|
+
:output_dir,
|
|
13
|
+
:no_open,
|
|
14
|
+
:json_output,
|
|
14
15
|
]
|
|
15
16
|
|
|
16
17
|
def initialize
|
|
17
|
-
@directory
|
|
18
|
-
@graph_type
|
|
19
|
-
@scm_name
|
|
20
|
-
@output
|
|
18
|
+
@directory = Dir.pwd
|
|
19
|
+
@graph_type = 'turbulence'
|
|
20
|
+
@scm_name = 'Git'
|
|
21
|
+
@output = STDOUT
|
|
22
|
+
@output_dir = nil
|
|
23
|
+
@no_open = false
|
|
24
|
+
@json_output = false
|
|
21
25
|
end
|
|
22
26
|
|
|
23
27
|
# TODO: drop attr accessor and ivar once it stops getting set via Churn
|
|
@@ -4,8 +4,8 @@ class Turbulence
|
|
|
4
4
|
attr_reader :metrics_hash, :x_metric, :y_metric
|
|
5
5
|
|
|
6
6
|
def initialize(metrics_hash,
|
|
7
|
-
x_metric =
|
|
8
|
-
y_metric =
|
|
7
|
+
x_metric = :churn,
|
|
8
|
+
y_metric = :complexity)
|
|
9
9
|
@x_metric = x_metric
|
|
10
10
|
@y_metric = y_metric
|
|
11
11
|
@metrics_hash = metrics_hash
|
|
@@ -49,11 +49,17 @@ class Turbulence
|
|
|
49
49
|
def file_metrics_for_directory(metrics_hash)
|
|
50
50
|
metrics_hash.map do |filename, metrics|
|
|
51
51
|
{ :filename => filename,
|
|
52
|
-
:x => metrics[x_metric],
|
|
53
|
-
:y => metrics[y_metric]}
|
|
52
|
+
:x => ensure_minimum(metrics[x_metric]),
|
|
53
|
+
:y => ensure_minimum(metrics[y_metric])}
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
+
# Offset zero values slightly to avoid Highcharts tooltip detection
|
|
58
|
+
# issues at the chart edge (bug in Highcharts 2.x)
|
|
59
|
+
def ensure_minimum(value)
|
|
60
|
+
value.zero? ? 1 : value
|
|
61
|
+
end
|
|
62
|
+
|
|
57
63
|
def generate_results(metrics, ci)
|
|
58
64
|
File.open("cc.js", "w") do |f|
|
|
59
65
|
ci.copy_templates_into(Dir.pwd)
|
|
@@ -4,8 +4,8 @@ class Turbulence
|
|
|
4
4
|
attr_reader :metrics_hash, :x_metric, :y_metric
|
|
5
5
|
|
|
6
6
|
def initialize(metrics_hash,
|
|
7
|
-
x_metric =
|
|
8
|
-
y_metric =
|
|
7
|
+
x_metric = :churn,
|
|
8
|
+
y_metric = :complexity)
|
|
9
9
|
@x_metric = x_metric
|
|
10
10
|
@y_metric = y_metric
|
|
11
11
|
@metrics_hash = metrics_hash
|
|
@@ -21,16 +21,20 @@ class Turbulence
|
|
|
21
21
|
def build_js
|
|
22
22
|
clean_metrics_from_missing_data
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
# Build Highcharts treemap data format
|
|
25
|
+
data = @metrics_hash.map do |filename, metrics|
|
|
26
|
+
churn = metrics[@x_metric] || 0
|
|
27
|
+
complexity = metrics[@y_metric] || 0
|
|
28
|
+
# Ensure minimum value of 1 for churn to avoid zero-size boxes
|
|
29
|
+
churn = 1 if churn.zero?
|
|
30
|
+
{
|
|
31
|
+
name: filename,
|
|
32
|
+
value: churn,
|
|
33
|
+
colorValue: complexity
|
|
34
|
+
}
|
|
29
35
|
end
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
output
|
|
37
|
+
"var treemap_data = #{data.to_json};"
|
|
34
38
|
end
|
|
35
39
|
|
|
36
40
|
private
|
data/lib/turbulence/scm/git.rb
CHANGED
data/lib/turbulence/version.rb
CHANGED
data/lib/turbulence.rb
CHANGED
|
@@ -5,150 +5,138 @@ describe Turbulence::Calculators::Churn do
|
|
|
5
5
|
let(:config) { Turbulence::Configuration.new }
|
|
6
6
|
|
|
7
7
|
before do
|
|
8
|
-
calculator.
|
|
8
|
+
allow(calculator).to receive(:scm_log_command).and_return("")
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
describe "::for_these_files" do
|
|
12
12
|
it "yields up the filename and score for each file" do
|
|
13
13
|
files = ["lib/corey.rb", "lib/chad.rb"]
|
|
14
|
-
calculator.
|
|
15
|
-
[
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
]
|
|
19
|
-
}
|
|
14
|
+
allow(calculator).to receive(:changes_by_ruby_file).and_return([
|
|
15
|
+
["lib/corey.rb", 5],
|
|
16
|
+
["lib/chad.rb", 10]
|
|
17
|
+
])
|
|
20
18
|
yielded_files = []
|
|
21
19
|
calculator.for_these_files(files) do |filename, score|
|
|
22
20
|
yielded_files << [filename, score]
|
|
23
21
|
end
|
|
24
|
-
yielded_files.
|
|
25
|
-
["lib/chad.rb",10]]
|
|
22
|
+
expect(yielded_files).to match_array([["lib/corey.rb", 5], ["lib/chad.rb", 10]])
|
|
26
23
|
end
|
|
27
24
|
|
|
28
25
|
it "filters the results by the passed-in files" do
|
|
29
26
|
files = ["lib/corey.rb"]
|
|
30
|
-
calculator.
|
|
31
|
-
[
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
]
|
|
35
|
-
}
|
|
27
|
+
allow(calculator).to receive(:changes_by_ruby_file).and_return([
|
|
28
|
+
["lib/corey.rb", 5],
|
|
29
|
+
["lib/chad.rb", 10]
|
|
30
|
+
])
|
|
36
31
|
yielded_files = []
|
|
37
32
|
calculator.for_these_files(files) do |filename, score|
|
|
38
33
|
yielded_files << [filename, score]
|
|
39
34
|
end
|
|
40
|
-
yielded_files.
|
|
35
|
+
expect(yielded_files).to match_array([["lib/corey.rb", 5]])
|
|
41
36
|
end
|
|
42
37
|
end
|
|
43
38
|
|
|
44
39
|
describe "::scm_log_file_lines" do
|
|
45
40
|
it "returns just the file lines" do
|
|
46
|
-
calculator.
|
|
47
|
-
|
|
48
|
-
|
|
41
|
+
allow(calculator).to receive(:scm_log_command).and_return(
|
|
42
|
+
"\n\n\n\n10\t6\tlib/turbulence.rb\n\n\n\n17\t2\tlib/eddies.rb\n"
|
|
43
|
+
)
|
|
49
44
|
|
|
50
|
-
calculator.scm_log_file_lines.
|
|
45
|
+
expect(calculator.scm_log_file_lines).to match_array([
|
|
51
46
|
"10\t6\tlib/turbulence.rb",
|
|
52
47
|
"17\t2\tlib/eddies.rb"
|
|
53
|
-
]
|
|
48
|
+
])
|
|
54
49
|
end
|
|
55
50
|
end
|
|
56
51
|
|
|
57
52
|
describe "::counted_line_changes_by_file_by_commit" do
|
|
58
53
|
before do
|
|
59
|
-
calculator.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
]
|
|
64
|
-
}
|
|
54
|
+
allow(calculator).to receive(:scm_log_file_lines).and_return([
|
|
55
|
+
"10\t6\tlib/turbulence.rb",
|
|
56
|
+
"17\t2\tlib/eddies.rb"
|
|
57
|
+
])
|
|
65
58
|
end
|
|
66
59
|
|
|
67
60
|
it "sums up the line changes" do
|
|
68
|
-
calculator.counted_line_changes_by_file_by_commit.
|
|
61
|
+
expect(calculator.counted_line_changes_by_file_by_commit).to match_array([["lib/turbulence.rb", 16], ["lib/eddies.rb", 19]])
|
|
69
62
|
end
|
|
70
63
|
end
|
|
71
|
-
|
|
64
|
+
|
|
72
65
|
describe "::changes_by_ruby_file" do
|
|
73
66
|
before do
|
|
74
|
-
calculator.
|
|
75
|
-
[
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
]
|
|
84
|
-
}
|
|
67
|
+
allow(calculator).to receive(:ruby_files_changed_in_scm).and_return([
|
|
68
|
+
['lib/eddies.rb', 4],
|
|
69
|
+
['lib/turbulence.rb', 5],
|
|
70
|
+
['lib/turbulence.rb', 16],
|
|
71
|
+
['lib/eddies.rb', 2],
|
|
72
|
+
['lib/turbulence.rb', 7],
|
|
73
|
+
['lib/eddies.rb', 19],
|
|
74
|
+
['lib/eddies.rb', 28]
|
|
75
|
+
])
|
|
85
76
|
end
|
|
86
|
-
|
|
77
|
+
|
|
87
78
|
it "groups and sums churns, excluding the last" do
|
|
88
79
|
calculator.compute_mean = false
|
|
89
|
-
calculator.changes_by_ruby_file.
|
|
80
|
+
expect(calculator.changes_by_ruby_file).to match_array([['lib/eddies.rb', 25], ['lib/turbulence.rb', 21]])
|
|
90
81
|
end
|
|
91
82
|
|
|
92
83
|
it "interprets a single entry as zero churn" do
|
|
93
|
-
calculator.
|
|
94
|
-
[
|
|
95
|
-
|
|
96
|
-
]
|
|
97
|
-
}
|
|
84
|
+
allow(calculator).to receive(:ruby_files_changed_in_scm).and_return([
|
|
85
|
+
['lib/eddies.rb', 4],
|
|
86
|
+
])
|
|
98
87
|
calculator.compute_mean = false
|
|
99
|
-
calculator.changes_by_ruby_file.
|
|
88
|
+
expect(calculator.changes_by_ruby_file).to match_array([['lib/eddies.rb', 0]])
|
|
100
89
|
end
|
|
101
|
-
|
|
90
|
+
|
|
102
91
|
it "groups and takes the mean of churns, excluding the last" do
|
|
103
92
|
calculator.compute_mean = true
|
|
104
|
-
calculator.changes_by_ruby_file.
|
|
93
|
+
expect(calculator.changes_by_ruby_file).to match_array([['lib/eddies.rb', 8], ['lib/turbulence.rb', 10]])
|
|
105
94
|
calculator.compute_mean = false
|
|
106
95
|
end
|
|
107
96
|
end
|
|
108
97
|
|
|
109
98
|
describe "::calculate_mean_of_churn" do
|
|
110
99
|
it "handles zero sample size" do
|
|
111
|
-
calculator.calculate_mean_of_churn(8,0).
|
|
100
|
+
expect(calculator.calculate_mean_of_churn(8, 0)).to eq 8
|
|
112
101
|
end
|
|
113
102
|
|
|
114
|
-
it "returns original churn for sample size = 1"
|
|
115
|
-
calculator.calculate_mean_of_churn(8,1).
|
|
103
|
+
it "returns original churn for sample size = 1" do
|
|
104
|
+
expect(calculator.calculate_mean_of_churn(8, 1)).to eq 8
|
|
116
105
|
end
|
|
117
106
|
|
|
118
107
|
it "returns churn divided by sample size" do
|
|
119
|
-
calculator.calculate_mean_of_churn(25,3).
|
|
108
|
+
expect(calculator.calculate_mean_of_churn(25, 3)).to eq 8
|
|
120
109
|
end
|
|
121
|
-
|
|
122
110
|
end
|
|
123
111
|
|
|
124
112
|
context "Full stack tests" do
|
|
125
113
|
context "when one ruby file is given" do
|
|
126
114
|
context "with two log entries for file" do
|
|
127
115
|
before do
|
|
128
|
-
calculator.
|
|
116
|
+
allow(calculator).to receive(:scm_log_command).and_return(
|
|
129
117
|
"\n\n\n\n10\t6\tlib/turbulence.rb\n" +
|
|
130
|
-
|
|
131
|
-
|
|
118
|
+
"\n\n\n\n11\t7\tlib/turbulence.rb\n"
|
|
119
|
+
)
|
|
132
120
|
end
|
|
133
121
|
it "gives the line change count for the file" do
|
|
134
122
|
yielded_files = []
|
|
135
123
|
calculator.for_these_files(["lib/turbulence.rb"]) do |filename, score|
|
|
136
124
|
yielded_files << [filename, score]
|
|
137
125
|
end
|
|
138
|
-
yielded_files.
|
|
126
|
+
expect(yielded_files).to match_array([["lib/turbulence.rb", 16]])
|
|
139
127
|
end
|
|
140
128
|
context "with only one log entry for file" do
|
|
141
129
|
before do
|
|
142
|
-
calculator.
|
|
130
|
+
allow(calculator).to receive(:scm_log_command).and_return(
|
|
143
131
|
"\n\n\n\n10\t6\tlib/turbulence.rb\n"
|
|
144
|
-
|
|
132
|
+
)
|
|
145
133
|
end
|
|
146
134
|
it "shows zero churn for the file" do
|
|
147
135
|
yielded_files = []
|
|
148
136
|
calculator.for_these_files(["lib/turbulence.rb"]) do |filename, score|
|
|
149
137
|
yielded_files << [filename, score]
|
|
150
138
|
end
|
|
151
|
-
yielded_files.
|
|
139
|
+
expect(yielded_files).to match_array([["lib/turbulence.rb", 0]])
|
|
152
140
|
end
|
|
153
141
|
end
|
|
154
142
|
end
|
|
@@ -7,15 +7,12 @@ describe Turbulence::Calculators::Complexity do
|
|
|
7
7
|
describe "::for_these_files" do
|
|
8
8
|
it "yields up the filename and score for each file" do
|
|
9
9
|
files = ["lib/corey.rb", "lib/chad.rb"]
|
|
10
|
-
calculator.
|
|
11
|
-
filename.size
|
|
12
|
-
}
|
|
10
|
+
allow(calculator).to receive(:score_for_file) { |filename| filename.size }
|
|
13
11
|
yielded_files = []
|
|
14
12
|
calculator.for_these_files(files) do |filename, score|
|
|
15
13
|
yielded_files << [filename, score]
|
|
16
14
|
end
|
|
17
|
-
yielded_files.
|
|
18
|
-
["lib/chad.rb",11]]
|
|
15
|
+
expect(yielded_files).to match_array([["lib/corey.rb", 12], ["lib/chad.rb", 11]])
|
|
19
16
|
end
|
|
20
17
|
end
|
|
21
18
|
end
|
|
@@ -10,31 +10,41 @@ describe Turbulence::CommandLineInterface::ConfigParser do
|
|
|
10
10
|
|
|
11
11
|
it "sets directory" do
|
|
12
12
|
parse %w( path/to/compute )
|
|
13
|
-
config.directory.
|
|
13
|
+
expect(config.directory).to eq 'path/to/compute'
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
it "sets SCM name to 'Perforce'" do
|
|
17
17
|
parse %w( --scm p4 )
|
|
18
|
-
config.scm_name.
|
|
18
|
+
expect(config.scm_name).to eq 'Perforce'
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
it "sets commit range" do
|
|
22
22
|
parse %w( --churn-range f3e1d7a6..830b9d3d9f )
|
|
23
|
-
config.commit_range.
|
|
23
|
+
expect(config.commit_range).to eq 'f3e1d7a6..830b9d3d9f'
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
it "sets compute mean" do
|
|
27
27
|
parse %w( --churn-mean )
|
|
28
|
-
config.compute_mean.
|
|
28
|
+
expect(config.compute_mean).to be true
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
it "sets the exclusion pattern" do
|
|
32
32
|
parse %w( --exclude turbulence )
|
|
33
|
-
config.exclusion_pattern.
|
|
33
|
+
expect(config.exclusion_pattern).to eq 'turbulence'
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
it "sets the graph type" do
|
|
37
37
|
parse %w( --treemap )
|
|
38
|
-
config.graph_type.
|
|
38
|
+
expect(config.graph_type).to eq 'treemap'
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "sets no_open" do
|
|
42
|
+
parse %w( --no-open )
|
|
43
|
+
expect(config.no_open).to be true
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "sets output_dir" do
|
|
47
|
+
parse %w( --output spec/reports/turbulence )
|
|
48
|
+
expect(config.output_dir).to eq 'spec/reports/turbulence'
|
|
39
49
|
end
|
|
40
50
|
end
|
|
@@ -6,7 +6,9 @@ describe Turbulence::CommandLineInterface do
|
|
|
6
6
|
|
|
7
7
|
describe "::TEMPLATE_FILES" do
|
|
8
8
|
Turbulence::CommandLineInterface::TEMPLATE_FILES.each do |template_file|
|
|
9
|
-
File.
|
|
9
|
+
it "has #{File.basename(template_file)} in the template path" do
|
|
10
|
+
expect(File.dirname(template_file)).to eq Turbulence::CommandLineInterface::TURBULENCE_TEMPLATE_PATH
|
|
11
|
+
end
|
|
10
12
|
end
|
|
11
13
|
end
|
|
12
14
|
|
|
@@ -16,18 +18,68 @@ describe Turbulence::CommandLineInterface do
|
|
|
16
18
|
end
|
|
17
19
|
it "bundles the files" do
|
|
18
20
|
cli.generate_bundle
|
|
19
|
-
Dir.glob('turbulence/*').sort.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
expect(Dir.glob('turbulence/*').sort).to eq(["turbulence/cc.js",
|
|
22
|
+
"turbulence/highcharts-heatmap.js",
|
|
23
|
+
"turbulence/highcharts-treemap.js",
|
|
24
|
+
"turbulence/highcharts.js",
|
|
25
|
+
"turbulence/jquery.min.js",
|
|
26
|
+
"turbulence/treemap.html",
|
|
27
|
+
"turbulence/turbulence.html"])
|
|
24
28
|
end
|
|
25
29
|
|
|
26
30
|
it "passes along exclusion pattern" do
|
|
27
31
|
cli = Turbulence::CommandLineInterface.new(%w(--exclude turbulence), :output => nil)
|
|
28
32
|
cli.generate_bundle
|
|
29
33
|
lines = File.new('turbulence/cc.js').readlines
|
|
30
|
-
lines.any? { |l| l =~ /turbulence\.rb/ }.
|
|
34
|
+
expect(lines.any? { |l| l =~ /turbulence\.rb/ }).to be false
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "outputs to custom directory when --output is specified" do
|
|
38
|
+
custom_dir = 'tmp/custom_output'
|
|
39
|
+
FileUtils.remove_dir(custom_dir, true)
|
|
40
|
+
cli = Turbulence::CommandLineInterface.new(['--output', custom_dir], :output => nil)
|
|
41
|
+
cli.generate_bundle
|
|
42
|
+
expect(Dir.glob("#{custom_dir}/*").sort).to eq(["#{custom_dir}/cc.js",
|
|
43
|
+
"#{custom_dir}/highcharts-heatmap.js",
|
|
44
|
+
"#{custom_dir}/highcharts-treemap.js",
|
|
45
|
+
"#{custom_dir}/highcharts.js",
|
|
46
|
+
"#{custom_dir}/jquery.min.js",
|
|
47
|
+
"#{custom_dir}/treemap.html",
|
|
48
|
+
"#{custom_dir}/turbulence.html"])
|
|
49
|
+
FileUtils.remove_dir(custom_dir, true)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe "#generate_json" do
|
|
54
|
+
before do
|
|
55
|
+
Turbulence.instance_variable_set(:@config, nil)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "outputs valid JSON to stdout" do
|
|
59
|
+
cli = Turbulence::CommandLineInterface.new(%w(--json), :output => nil)
|
|
60
|
+
expect { cli.generate_bundle }.to output(/\{.*"complexity".*"churn".*\}/m).to_stdout
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "suppresses progress output" do
|
|
64
|
+
cli = Turbulence::CommandLineInterface.new(%w(--json), :output => nil)
|
|
65
|
+
expect { cli.generate_bundle }.not_to output(/calculating metric/).to_stdout
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
describe "#output_path" do
|
|
70
|
+
before do
|
|
71
|
+
# Reset the singleton config between tests
|
|
72
|
+
Turbulence.instance_variable_set(:@config, nil)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "defaults to ./turbulence when output_dir is not set" do
|
|
76
|
+
cli = Turbulence::CommandLineInterface.new(%w(.), :output => nil)
|
|
77
|
+
expect(cli.output_path).to eq(File.join(Dir.pwd, "turbulence"))
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "returns the custom output_dir when set" do
|
|
81
|
+
cli = Turbulence::CommandLineInterface.new(%w(--output custom/path), :output => nil)
|
|
82
|
+
expect(cli.output_path).to eq('custom/path')
|
|
31
83
|
end
|
|
32
84
|
end
|
|
33
85
|
end
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
require 'rspec'
|
|
2
|
+
require 'rspec/its'
|
|
2
3
|
require 'turbulence'
|
|
3
4
|
|
|
4
5
|
describe Turbulence::Configuration do
|
|
5
6
|
describe "defaults" do
|
|
6
|
-
its(:output)
|
|
7
|
-
its(:directory)
|
|
8
|
-
its(:graph_type)
|
|
9
|
-
its(:scm_name)
|
|
10
|
-
its(:scm)
|
|
7
|
+
its(:output) { should eq(STDOUT) }
|
|
8
|
+
its(:directory) { should eq(Dir.pwd) }
|
|
9
|
+
its(:graph_type) { should eq('turbulence') }
|
|
10
|
+
its(:scm_name) { should eq('Git') }
|
|
11
|
+
its(:scm) { should eq(Turbulence::Scm::Git) }
|
|
12
|
+
its(:no_open) { should eq(false) }
|
|
13
|
+
its(:output_dir) { should be_nil }
|
|
14
|
+
its(:commit_range) { should be_nil }
|
|
15
|
+
its(:compute_mean) { should be_nil }
|
|
16
|
+
its(:exclusion_pattern) { should be_nil }
|
|
11
17
|
end
|
|
12
18
|
end
|
|
13
19
|
|