turbulence 0.0.9 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +0 -8
- data/Gemfile.lock +26 -23
- data/README.md +15 -4
- data/Rakefile +1 -0
- data/bin/bule +5 -4
- data/lib/turbulence/calculators/churn.rb +29 -14
- data/lib/turbulence/calculators/complexity.rb +3 -4
- data/lib/turbulence/checks_environment.rb +2 -5
- data/lib/turbulence/command_line_interface.rb +40 -11
- data/lib/turbulence/scatter_plot_generator.rb +47 -13
- data/lib/turbulence/scm/git.rb +17 -0
- data/lib/turbulence/scm/perforce.rb +90 -0
- data/lib/turbulence/version.rb +1 -1
- data/lib/turbulence.rb +27 -20
- data/spec/turbulence/calculators/churn_spec.rb +63 -11
- data/spec/turbulence/checks_environoment_spec.rb +11 -0
- data/spec/turbulence/command_line_interface_spec.rb +36 -6
- data/spec/turbulence/scatter_splot_generator_spec.rb +97 -0
- data/spec/turbulence/scm/git_spec.rb +29 -0
- data/spec/turbulence/scm/perforce_spec.rb +148 -0
- data/spec/turbulence/turbulence_spec.rb +15 -0
- data/turbulence.gemspec +4 -2
- data/win_rakefile_location_fix.rb +8 -0
- metadata +41 -35
- data/.DS_Store +0 -0
- data/cc.js +0 -1
- data/highcharts.js +0 -162
- data/jquery.min.js +0 -16
- data/turbulence.html +0 -81
@@ -3,7 +3,7 @@ require 'turbulence/calculators/churn'
|
|
3
3
|
describe Turbulence::Calculators::Churn do
|
4
4
|
let(:calculator) { Turbulence::Calculators::Churn }
|
5
5
|
before do
|
6
|
-
calculator.stub(:
|
6
|
+
calculator.stub(:scm_log_command) { "" }
|
7
7
|
end
|
8
8
|
|
9
9
|
describe "::for_these_files" do
|
@@ -11,8 +11,8 @@ describe Turbulence::Calculators::Churn do
|
|
11
11
|
files = ["lib/corey.rb", "lib/chad.rb"]
|
12
12
|
calculator.stub(:changes_by_ruby_file) {
|
13
13
|
[
|
14
|
-
[
|
15
|
-
[
|
14
|
+
["lib/corey.rb", 5],
|
15
|
+
["lib/chad.rb", 10]
|
16
16
|
]
|
17
17
|
}
|
18
18
|
yielded_files = []
|
@@ -27,8 +27,8 @@ describe Turbulence::Calculators::Churn do
|
|
27
27
|
files = ["lib/corey.rb"]
|
28
28
|
calculator.stub(:changes_by_ruby_file) {
|
29
29
|
[
|
30
|
-
[
|
31
|
-
[
|
30
|
+
["lib/corey.rb", 5],
|
31
|
+
["lib/chad.rb", 10]
|
32
32
|
]
|
33
33
|
}
|
34
34
|
yielded_files = []
|
@@ -39,13 +39,13 @@ describe Turbulence::Calculators::Churn do
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
describe "::
|
42
|
+
describe "::scm_log_file_lines" do
|
43
43
|
it "returns just the file lines" do
|
44
|
-
calculator.stub(:
|
44
|
+
calculator.stub(:scm_log_command) do
|
45
45
|
"\n\n\n\n10\t6\tlib/turbulence.rb\n\n\n\n17\t2\tlib/eddies.rb\n"
|
46
46
|
end
|
47
47
|
|
48
|
-
calculator.
|
48
|
+
calculator.scm_log_file_lines.should =~ [
|
49
49
|
"10\t6\tlib/turbulence.rb",
|
50
50
|
"17\t2\tlib/eddies.rb"
|
51
51
|
]
|
@@ -54,7 +54,7 @@ describe Turbulence::Calculators::Churn do
|
|
54
54
|
|
55
55
|
describe "::counted_line_changes_by_file_by_commit" do
|
56
56
|
before do
|
57
|
-
calculator.stub(:
|
57
|
+
calculator.stub(:scm_log_file_lines) {
|
58
58
|
[
|
59
59
|
"10\t6\tlib/turbulence.rb",
|
60
60
|
"17\t2\tlib/eddies.rb"
|
@@ -66,12 +66,64 @@ describe Turbulence::Calculators::Churn do
|
|
66
66
|
calculator.counted_line_changes_by_file_by_commit.should =~ [["lib/turbulence.rb", 16], ["lib/eddies.rb", 19]]
|
67
67
|
end
|
68
68
|
end
|
69
|
+
|
70
|
+
describe "::changes_by_ruby_file" do
|
71
|
+
before do
|
72
|
+
calculator.stub(:ruby_files_changed_in_scm) {
|
73
|
+
[
|
74
|
+
['lib/eddies.rb', 4],
|
75
|
+
['lib/turbulence.rb', 5],
|
76
|
+
['lib/turbulence.rb', 16],
|
77
|
+
['lib/eddies.rb', 2],
|
78
|
+
['lib/turbulence.rb', 7],
|
79
|
+
['lib/eddies.rb', 19],
|
80
|
+
['lib/eddies.rb', 28]
|
81
|
+
]
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
it "groups and sums churns, excluding the last" do
|
86
|
+
calculator.compute_mean = false
|
87
|
+
calculator.changes_by_ruby_file.should =~ [ ['lib/eddies.rb', 25], ['lib/turbulence.rb', 21]]
|
88
|
+
end
|
89
|
+
|
90
|
+
it "interprets a single entry as zero churn" do
|
91
|
+
calculator.stub(:ruby_files_changed_in_scm) {
|
92
|
+
[
|
93
|
+
['lib/eddies.rb', 4],
|
94
|
+
]
|
95
|
+
}
|
96
|
+
calculator.compute_mean = false
|
97
|
+
calculator.changes_by_ruby_file.should =~ [ ['lib/eddies.rb', 0] ]
|
98
|
+
end
|
99
|
+
|
100
|
+
it "groups and takes the mean of churns, excluding the last" do
|
101
|
+
calculator.compute_mean = true
|
102
|
+
calculator.changes_by_ruby_file.should =~ [ ['lib/eddies.rb', 8], ['lib/turbulence.rb', 10]]
|
103
|
+
calculator.compute_mean = false
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "::calculate_mean_of_churn" do
|
108
|
+
it "handles zero sample size" do
|
109
|
+
calculator.calculate_mean_of_churn(8,0).should == 8
|
110
|
+
end
|
111
|
+
|
112
|
+
it "returns original churn for sample size = 1" do
|
113
|
+
calculator.calculate_mean_of_churn(8,1).should == 8
|
114
|
+
end
|
115
|
+
|
116
|
+
it "returns churn divided by sample size" do
|
117
|
+
calculator.calculate_mean_of_churn(25,3).should == 8
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
69
121
|
|
70
122
|
context "Full stack tests" do
|
71
123
|
context "when one ruby file is given" do
|
72
124
|
context "with two log entries for file" do
|
73
125
|
before do
|
74
|
-
calculator.stub(:
|
126
|
+
calculator.stub(:scm_log_command) do
|
75
127
|
"\n\n\n\n10\t6\tlib/turbulence.rb\n" +
|
76
128
|
"\n\n\n\n11\t7\tlib/turbulence.rb\n"
|
77
129
|
end
|
@@ -85,7 +137,7 @@ describe Turbulence::Calculators::Churn do
|
|
85
137
|
end
|
86
138
|
context "with only one log entry for file" do
|
87
139
|
before do
|
88
|
-
calculator.stub(:
|
140
|
+
calculator.stub(:scm_log_command) do
|
89
141
|
"\n\n\n\n10\t6\tlib/turbulence.rb\n"
|
90
142
|
end
|
91
143
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'turbulence/scm/git'
|
3
|
+
require 'turbulence'
|
4
|
+
|
5
|
+
describe Turbulence::ChecksEnvironment do
|
6
|
+
|
7
|
+
it "should determine if the current directory is a git repository" do
|
8
|
+
Turbulence::Calculators::Churn.scm = Turbulence::Scm::Git
|
9
|
+
Turbulence::ChecksEnvironment.scm_repo?(Dir.pwd).should be_true
|
10
|
+
end
|
11
|
+
end
|
@@ -1,16 +1,46 @@
|
|
1
|
+
require 'rspec'
|
1
2
|
require 'turbulence'
|
2
3
|
|
3
4
|
describe Turbulence::CommandLineInterface do
|
4
|
-
let(:cli) { Turbulence::CommandLineInterface.new(
|
5
|
-
describe "
|
6
|
-
|
7
|
-
|
5
|
+
let(:cli) { Turbulence::CommandLineInterface.new(%w(.)) }
|
6
|
+
describe "::TEMPLATE_FILES" do
|
7
|
+
Turbulence::CommandLineInterface::TEMPLATE_FILES.each do |template_file|
|
8
|
+
File.dirname(template_file).should == Turbulence::CommandLineInterface::TURBULENCE_TEMPLATE_PATH
|
8
9
|
end
|
9
10
|
end
|
10
11
|
describe "#generate_bundle" do
|
12
|
+
before do
|
13
|
+
FileUtils.remove_dir("turbulence", true)
|
14
|
+
end
|
11
15
|
it "bundles the files" do
|
12
|
-
cli.generate_bundle
|
13
|
-
Dir.glob('turbulence/*').should eq(["turbulence/cc.js", "turbulence/highcharts.js", "turbulence/jquery.min.js", "turbulence/turbulence.html"])
|
16
|
+
cli.generate_bundle
|
17
|
+
Dir.glob('turbulence/*').sort.should eq(["turbulence/cc.js", "turbulence/highcharts.js", "turbulence/jquery.min.js", "turbulence/turbulence.html"])
|
18
|
+
end
|
19
|
+
|
20
|
+
it "passes along exclusion pattern" do
|
21
|
+
cli = Turbulence::CommandLineInterface.new(%w(--exclude turbulence))
|
22
|
+
cli.generate_bundle
|
23
|
+
lines = File.new('turbulence/cc.js').readlines
|
24
|
+
lines.any? { |l| l =~ /turbulence\.rb/ }.should be_false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
describe "command line options" do
|
28
|
+
let(:cli_churn_range) { Turbulence::CommandLineInterface.new(%w(--churn-range f3e1d7a6..830b9d3d9f path/to/compute)) }
|
29
|
+
let(:cli_churn_mean) { Turbulence::CommandLineInterface.new(%w(--churn-mean .)) }
|
30
|
+
let(:cli_exclusion_pattern) { Turbulence::CommandLineInterface.new(%w(--exclude turbulence)) }
|
31
|
+
|
32
|
+
it "sets churn range" do
|
33
|
+
cli_churn_range.directory.should == 'path/to/compute'
|
34
|
+
Turbulence::Calculators::Churn.commit_range.should == 'f3e1d7a6..830b9d3d9f'
|
35
|
+
end
|
36
|
+
|
37
|
+
it "sets churn mean" do
|
38
|
+
cli_churn_mean.directory.should == '.'
|
39
|
+
Turbulence::Calculators::Churn.compute_mean.should be_true
|
40
|
+
end
|
41
|
+
|
42
|
+
it "sets the exclusion pattern" do
|
43
|
+
cli_exclusion_pattern.exclusion_pattern.should == 'turbulence'
|
14
44
|
end
|
15
45
|
end
|
16
46
|
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'turbulence'
|
2
|
+
|
3
|
+
describe Turbulence::ScatterPlotGenerator do
|
4
|
+
context "with both Metrics" do
|
5
|
+
it "generates JavaScript" do
|
6
|
+
generator = Turbulence::ScatterPlotGenerator.new(
|
7
|
+
"foo.rb" => {
|
8
|
+
Turbulence::Calculators::Churn => 1,
|
9
|
+
Turbulence::Calculators::Complexity => 2
|
10
|
+
}
|
11
|
+
)
|
12
|
+
generator.to_js.should =~ /var directorySeries/
|
13
|
+
generator.to_js.should =~ /\"filename\"\:\"foo.rb\"/
|
14
|
+
generator.to_js.should =~ /\"x\":1/
|
15
|
+
generator.to_js.should =~ /\"y\":2/
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "with a missing Metric" do
|
20
|
+
it "generates JavaScript" do
|
21
|
+
generator = Turbulence::ScatterPlotGenerator.new(
|
22
|
+
"foo.rb" => {
|
23
|
+
Turbulence::Calculators::Churn => 1
|
24
|
+
}
|
25
|
+
)
|
26
|
+
generator.to_js.should == 'var directorySeries = {};'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#clean_metrics_from_missing_data" do
|
31
|
+
let(:spg) {Turbulence::ScatterPlotGenerator.new({})}
|
32
|
+
|
33
|
+
it "removes entries with missing churn" do
|
34
|
+
spg.stub(:metrics_hash).and_return("foo.rb" => {
|
35
|
+
Turbulence::Calculators::Complexity => 88.3})
|
36
|
+
spg.clean_metrics_from_missing_data.should == {}
|
37
|
+
end
|
38
|
+
|
39
|
+
it "removes entries with missing complexity" do
|
40
|
+
spg.stub(:metrics_hash).and_return("foo.rb" => {
|
41
|
+
Turbulence::Calculators::Churn => 1})
|
42
|
+
spg.clean_metrics_from_missing_data.should == {}
|
43
|
+
end
|
44
|
+
|
45
|
+
it "keeps entries with churn and complexity present" do
|
46
|
+
spg.stub(:metrics_hash).and_return("foo.rb" => {
|
47
|
+
Turbulence::Calculators::Churn => 1,
|
48
|
+
Turbulence::Calculators::Complexity => 88.3})
|
49
|
+
spg.clean_metrics_from_missing_data.should_not == {}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#grouped_by_directory" do
|
54
|
+
let(:spg) {Turbulence::ScatterPlotGenerator.new("lib/foo/foo.rb" => {
|
55
|
+
Turbulence::Calculators::Churn => 1},
|
56
|
+
"lib/bar.rb" => {
|
57
|
+
Turbulence::Calculators::Churn => 2} )}
|
58
|
+
|
59
|
+
it "uses \".\" to denote flat hierarchy" do
|
60
|
+
spg.stub(:metrics_hash).and_return("foo.rb" => {
|
61
|
+
Turbulence::Calculators::Churn => 1
|
62
|
+
})
|
63
|
+
spg.grouped_by_directory.should == {"." => [["foo.rb", Turbulence::Calculators::Churn => 1]]}
|
64
|
+
end
|
65
|
+
|
66
|
+
it "takes full path into account" do
|
67
|
+
spg.grouped_by_directory.should == {"lib/foo" => [["lib/foo/foo.rb", Turbulence::Calculators::Churn => 1]],
|
68
|
+
"lib" => [["lib/bar.rb", Turbulence::Calculators::Churn => 2]]}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "#file_metrics_for_directory" do
|
73
|
+
let(:spg) {Turbulence::ScatterPlotGenerator.new({})}
|
74
|
+
it "assigns :filename, :x, :y" do
|
75
|
+
spg.file_metrics_for_directory("lib/foo/foo.rb" => {
|
76
|
+
Turbulence::Calculators::Churn => 1,
|
77
|
+
Turbulence::Calculators::Complexity => 88.2}).should == [{:filename => "lib/foo/foo.rb",
|
78
|
+
:x => 1, :y => 88.2}]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe Turbulence::FileNameMangler do
|
83
|
+
subject { Turbulence::FileNameMangler.new }
|
84
|
+
it "anonymizes a string" do
|
85
|
+
subject.mangle_name("chad").should_not == "chad"
|
86
|
+
end
|
87
|
+
|
88
|
+
it "maintains standard directory names" do
|
89
|
+
subject.mangle_name("/app/controllers/chad.rb").should =~ %r{/app/controllers/1.rb}
|
90
|
+
end
|
91
|
+
|
92
|
+
it "honors leading path separators" do
|
93
|
+
subject.mangle_name("/a/b/c.rb").should == "/1/2/3.rb"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'turbulence/scm/git'
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
describe Turbulence::Scm::Git do
|
6
|
+
describe "::is_repo?" do
|
7
|
+
before do
|
8
|
+
@tmp = Dir.mktmpdir(nil,'..')
|
9
|
+
end
|
10
|
+
after do
|
11
|
+
FileUtils.rmdir(@tmp)
|
12
|
+
end
|
13
|
+
it "returns true for the working directory" do
|
14
|
+
Turbulence::Scm::Git.is_repo?(".").should == true
|
15
|
+
end
|
16
|
+
it "return false for a newly created tmp directory" do
|
17
|
+
Turbulence::Scm::Git.is_repo?(@tmp).should == false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "::log_command" do
|
22
|
+
it "takes an optional argument specify to the range" do
|
23
|
+
expect{Turbulence::Scm::Git.log_command("d551e63f79a90430e560ea871f4e1e39e6e739bd HEAD")}.to_not raise_error(ArgumentError)
|
24
|
+
end
|
25
|
+
it "lists insertions/deletions per file and change" do
|
26
|
+
Turbulence::Scm::Git.log_command.should match(/\d+\t\d+\t[A-z.]*/)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'turbulence/scm/perforce'
|
2
|
+
require 'rspec/mocks'
|
3
|
+
|
4
|
+
describe Turbulence::Scm::Perforce do
|
5
|
+
let (:p4_scm) { Turbulence::Scm::Perforce }
|
6
|
+
before do
|
7
|
+
p4_scm.stub(:p4_list_changes) do
|
8
|
+
"Change 62660 on 2005/11/28 by x@client 'CHANGED: adapted to DESCODE '
|
9
|
+
Change 45616 on 2005/07/12 by x@client 'ADDED: trigger that builds and '
|
10
|
+
Change 45615 on 2005/07/12 by x@client 'ADDED: for testing purposes '
|
11
|
+
Change 45614 on 2005/07/12 by x@client 'COSMETIC: updated header '
|
12
|
+
Change 11250 on 2004/09/17 by x@client 'CHANGED: trigger now also allow'
|
13
|
+
Change 9250 on 2004/08/20 by x@client 'BUGFIX: bug#1583 (People can so'
|
14
|
+
Change 5560 on 2004/04/26 by x@client 'ADDED: The \"BRANCHED\" tag.'"
|
15
|
+
end
|
16
|
+
p4_scm.stub(:p4_describe_change).with("5560") do
|
17
|
+
"Change 5560 by x@client on 2004/04/26 17:25:03
|
18
|
+
|
19
|
+
ADDED: The \"BRANCHED\" tag.
|
20
|
+
|
21
|
+
Affected files ...
|
22
|
+
|
23
|
+
... //admin/scripts/triggers/enforce-submit-comment.py#2 edit
|
24
|
+
... //admin/scripts/triggers/check-consistency.py#3 edit
|
25
|
+
|
26
|
+
Differences ...
|
27
|
+
|
28
|
+
==== //admin/scripts/triggers/enforce-submit-comment.py#2 (ktext) ====
|
29
|
+
|
30
|
+
add 1 chunks 1 lines
|
31
|
+
deleted 0 chunks 0 lines
|
32
|
+
changed 1 chunks 3 / 3 lines
|
33
|
+
|
34
|
+
==== //admin/scripts/triggers/check-consistency.py#3 (ktext) ====
|
35
|
+
|
36
|
+
add 0 chunks 0 lines
|
37
|
+
deleted 0 chunks 0 lines
|
38
|
+
changed 1 chunks 3 / 1 lines"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
describe "::is_repo?" do
|
42
|
+
it "returns true if P4CLIENT is set " do
|
43
|
+
ENV['P4CLIENT'] = "c-foo.bar"
|
44
|
+
Turbulence::Scm::Perforce.is_repo?(".").should == true
|
45
|
+
end
|
46
|
+
it "returns false if P4CLIENT is empty" do
|
47
|
+
ENV['P4CLIENT'] = ""
|
48
|
+
Turbulence::Scm::Perforce.is_repo?(".").should == false
|
49
|
+
end
|
50
|
+
it "returns false if p4 is not available" do
|
51
|
+
ENV['PATH'] = ""
|
52
|
+
Turbulence::Scm::Perforce.is_repo?(".").should == false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
describe "::log_command" do
|
56
|
+
before do
|
57
|
+
p4_scm.stub(:depot_to_local).with("//admin/scripts/triggers/enforce-submit-comment.py")\
|
58
|
+
.and_return("triggers/enforce-submit-comments.py")
|
59
|
+
p4_scm.stub(:depot_to_local).with("//admin/scripts/triggers/check-consistency.py")\
|
60
|
+
.and_return("triggers/check-consistency.py")
|
61
|
+
p4_scm.stub(:p4_list_changes) do
|
62
|
+
"Change 5560 on 2004/04/26 by x@client 'ADDED: The \"BRANCHED\" tag.'"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
it "takes an optional argument to specify the range" do
|
66
|
+
expect{Turbulence::Scm::Perforce.log_command("@1,2")}.to_not raise_error(ArgumentError)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "lists insertions/deletions per file and change" do
|
70
|
+
Turbulence::Scm::Perforce.log_command().should match(/\d+\t\d+\t[A-z.]*/)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
describe "::changes" do
|
74
|
+
it "lists changenumbers from parsing 'p4 changes' output" do
|
75
|
+
p4_scm.changes.should =~ %w[62660 45616 45615 45614 11250 9250 5560]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
describe "::files_per_change" do
|
79
|
+
before do
|
80
|
+
p4_scm.stub(:depot_to_local).with("//admin/scripts/triggers/enforce-submit-comment.py")\
|
81
|
+
.and_return("triggers/enforce-submit-comments.py")
|
82
|
+
p4_scm.stub(:depot_to_local).with("//admin/scripts/triggers/check-consistency.py")\
|
83
|
+
.and_return("triggers/check-consistency.py")
|
84
|
+
end
|
85
|
+
|
86
|
+
it "lists files with churn" do
|
87
|
+
p4_scm.files_per_change("5560").should =~ [[4,"triggers/enforce-submit-comments.py"],
|
88
|
+
[1,"triggers/check-consistency.py"]]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
describe "::transform_for_output" do
|
92
|
+
it "adds a 0 for deletions" do
|
93
|
+
p4_scm.transform_for_output([1,"triggers/check-consistency.py"]).should == "1\t0\ttriggers/check-consistency.py\n"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
describe "::depot_to_local" do
|
97
|
+
describe "on windows" do
|
98
|
+
before do
|
99
|
+
p4_scm.stub(:extract_clientfile_from_fstat_of).and_return("D:/Perforce/admin/scripts/triggers/enforce-no-head-change.py")
|
100
|
+
FileUtils.stub(:pwd).and_return("D:/Perforce")
|
101
|
+
end
|
102
|
+
it "converts depot-style paths to local paths using forward slashes" do
|
103
|
+
p4_scm.depot_to_local("//admin/scripts/triggers/enforce-no-head-change.py").should \
|
104
|
+
== "admin/scripts/triggers/enforce-no-head-change.py"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
describe "on unix" do
|
108
|
+
before do
|
109
|
+
p4_scm.stub(:extract_clientfile_from_fstat_of).and_return("/home/jhwist/admin/scripts/triggers/enforce-no-head-change.py")
|
110
|
+
FileUtils.stub(:pwd).and_return("/home/jhwist")
|
111
|
+
end
|
112
|
+
it "converts depot-style paths to local paths using forward slashes" do
|
113
|
+
p4_scm.depot_to_local("//admin/scripts/triggers/enforce-no-head-change.py").should \
|
114
|
+
== "admin/scripts/triggers/enforce-no-head-change.py"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
describe "::extract_clientfile_from_fstat_of" do
|
119
|
+
before do
|
120
|
+
p4_scm.stub(:p4_fstat) do
|
121
|
+
"... depotFile //admin/scripts/triggers/enforce-no-head-change.py
|
122
|
+
... clientFile /home/jhwist/admin/scripts/triggers/enforce-no-head-change.py
|
123
|
+
... isMapped
|
124
|
+
... headAction edit
|
125
|
+
... headType ktext
|
126
|
+
... headTime 1214555059
|
127
|
+
... headRev 5
|
128
|
+
... headChange 211211
|
129
|
+
... headModTime 1214555028
|
130
|
+
... haveRev 5"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
it "uses clientFile field" do
|
134
|
+
p4_scm.extract_clientfile_from_fstat_of("//admin/scripts/triggers/enforce-no-head-change.py").should ==
|
135
|
+
"/home/jhwist/admin/scripts/triggers/enforce-no-head-change.py"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
describe "::sum_of_changes" do
|
139
|
+
it "sums up changes" do
|
140
|
+
output = "add 1 chunks 1 lines\ndeleted 0 chunks 0 lines\nchanged 1 chunks 3 / 3 lines"
|
141
|
+
p4_scm.sum_of_changes(output).should == 4
|
142
|
+
end
|
143
|
+
it "ignores junk" do
|
144
|
+
output = "add nothing, change nothing"
|
145
|
+
p4_scm.sum_of_changes(output).should == 0
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'turbulence'
|
3
|
+
|
4
|
+
describe Turbulence do
|
5
|
+
it "finds files of interest" do
|
6
|
+
turb = Turbulence.new(".")
|
7
|
+
turb.exclusion_pattern.should be_nil
|
8
|
+
turb.files_of_interest.should include "lib/turbulence.rb"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "filters out exluded files" do
|
12
|
+
turb = Turbulence.new(".", nil, 'turbulence')
|
13
|
+
turb.files_of_interest.should_not include "lib/turbulence.rb"
|
14
|
+
end
|
15
|
+
end
|
data/turbulence.gemspec
CHANGED
@@ -10,8 +10,10 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.email = ["chad@chadfowler.com", "mfeathers@obtiva.com", "coreyhaines@gmail.com"]
|
11
11
|
s.homepage = "http://chadfowler.com"
|
12
12
|
s.add_dependency "flog", "= 2.5.0"
|
13
|
-
s.add_dependency "json", "
|
14
|
-
s.add_dependency "launchy", "~> 0.
|
13
|
+
s.add_dependency "json", ">= 1.4.6"
|
14
|
+
s.add_dependency "launchy", "~> 2.0.0"
|
15
|
+
s.add_dependency "ParseTree", "~> 3.0.7"
|
16
|
+
s.add_development_dependency 'rspec', '~> 2.6.0'
|
15
17
|
|
16
18
|
s.summary = %q{Automates churn + flog scoring on a git repo for a Ruby project}
|
17
19
|
s.description = %q{Based on this http://www.stickyminds.com/sitewide.asp?Function=edetail&ObjectType=COL&ObjectId=16679&tth=DYN&tt=siteemail&iDyn=2}
|
metadata
CHANGED
@@ -1,12 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: turbulence
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 0
|
8
|
-
- 9
|
9
|
-
version: 0.0.9
|
4
|
+
prerelease:
|
5
|
+
version: 1.0.0
|
10
6
|
platform: ruby
|
11
7
|
authors:
|
12
8
|
- Chad Fowler
|
@@ -16,8 +12,7 @@ autorequire:
|
|
16
12
|
bindir: bin
|
17
13
|
cert_chain: []
|
18
14
|
|
19
|
-
date: 2011-
|
20
|
-
default_executable:
|
15
|
+
date: 2011-10-06 00:00:00 Z
|
21
16
|
dependencies:
|
22
17
|
- !ruby/object:Gem::Dependency
|
23
18
|
name: flog
|
@@ -27,10 +22,6 @@ dependencies:
|
|
27
22
|
requirements:
|
28
23
|
- - "="
|
29
24
|
- !ruby/object:Gem::Version
|
30
|
-
segments:
|
31
|
-
- 2
|
32
|
-
- 5
|
33
|
-
- 0
|
34
25
|
version: 2.5.0
|
35
26
|
type: :runtime
|
36
27
|
version_requirements: *id001
|
@@ -40,12 +31,8 @@ dependencies:
|
|
40
31
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
32
|
none: false
|
42
33
|
requirements:
|
43
|
-
- - "
|
34
|
+
- - ">="
|
44
35
|
- !ruby/object:Gem::Version
|
45
|
-
segments:
|
46
|
-
- 1
|
47
|
-
- 4
|
48
|
-
- 6
|
49
36
|
version: 1.4.6
|
50
37
|
type: :runtime
|
51
38
|
version_requirements: *id002
|
@@ -57,13 +44,31 @@ dependencies:
|
|
57
44
|
requirements:
|
58
45
|
- - ~>
|
59
46
|
- !ruby/object:Gem::Version
|
60
|
-
|
61
|
-
- 0
|
62
|
-
- 4
|
63
|
-
- 0
|
64
|
-
version: 0.4.0
|
47
|
+
version: 2.0.0
|
65
48
|
type: :runtime
|
66
49
|
version_requirements: *id003
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: ParseTree
|
52
|
+
prerelease: false
|
53
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ~>
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: 3.0.7
|
59
|
+
type: :runtime
|
60
|
+
version_requirements: *id004
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rspec
|
63
|
+
prerelease: false
|
64
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 2.6.0
|
70
|
+
type: :development
|
71
|
+
version_requirements: *id005
|
67
72
|
description: Based on this http://www.stickyminds.com/sitewide.asp?Function=edetail&ObjectType=COL&ObjectId=16679&tth=DYN&tt=siteemail&iDyn=2
|
68
73
|
email:
|
69
74
|
- chad@chadfowler.com
|
@@ -76,33 +81,35 @@ extensions: []
|
|
76
81
|
extra_rdoc_files: []
|
77
82
|
|
78
83
|
files:
|
79
|
-
- .DS_Store
|
80
84
|
- .gitignore
|
81
85
|
- Gemfile
|
82
86
|
- Gemfile.lock
|
83
87
|
- README.md
|
84
88
|
- Rakefile
|
85
89
|
- bin/bule
|
86
|
-
- cc.js
|
87
|
-
- highcharts.js
|
88
|
-
- jquery.min.js
|
89
90
|
- lib/turbulence.rb
|
90
91
|
- lib/turbulence/calculators/churn.rb
|
91
92
|
- lib/turbulence/calculators/complexity.rb
|
92
93
|
- lib/turbulence/checks_environment.rb
|
93
94
|
- lib/turbulence/command_line_interface.rb
|
94
95
|
- lib/turbulence/scatter_plot_generator.rb
|
96
|
+
- lib/turbulence/scm/git.rb
|
97
|
+
- lib/turbulence/scm/perforce.rb
|
95
98
|
- lib/turbulence/version.rb
|
96
99
|
- spec/turbulence/calculators/churn_spec.rb
|
97
100
|
- spec/turbulence/calculators/complexity_spec.rb
|
101
|
+
- spec/turbulence/checks_environoment_spec.rb
|
98
102
|
- spec/turbulence/command_line_interface_spec.rb
|
103
|
+
- spec/turbulence/scatter_splot_generator_spec.rb
|
104
|
+
- spec/turbulence/scm/git_spec.rb
|
105
|
+
- spec/turbulence/scm/perforce_spec.rb
|
106
|
+
- spec/turbulence/turbulence_spec.rb
|
99
107
|
- template/highchart_template.js.erb
|
100
108
|
- template/highcharts.js
|
101
109
|
- template/jquery.min.js
|
102
110
|
- template/turbulence.html
|
103
111
|
- turbulence.gemspec
|
104
|
-
-
|
105
|
-
has_rdoc: true
|
112
|
+
- win_rakefile_location_fix.rb
|
106
113
|
homepage: http://chadfowler.com
|
107
114
|
licenses: []
|
108
115
|
|
@@ -116,27 +123,26 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
116
123
|
requirements:
|
117
124
|
- - ">="
|
118
125
|
- !ruby/object:Gem::Version
|
119
|
-
segments:
|
120
|
-
- 1
|
121
|
-
- 8
|
122
|
-
- 7
|
123
126
|
version: 1.8.7
|
124
127
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
128
|
none: false
|
126
129
|
requirements:
|
127
130
|
- - ">="
|
128
131
|
- !ruby/object:Gem::Version
|
129
|
-
segments:
|
130
|
-
- 0
|
131
132
|
version: "0"
|
132
133
|
requirements: []
|
133
134
|
|
134
135
|
rubyforge_project: turbulence
|
135
|
-
rubygems_version: 1.
|
136
|
+
rubygems_version: 1.8.10
|
136
137
|
signing_key:
|
137
138
|
specification_version: 3
|
138
139
|
summary: Automates churn + flog scoring on a git repo for a Ruby project
|
139
140
|
test_files:
|
140
141
|
- spec/turbulence/calculators/churn_spec.rb
|
141
142
|
- spec/turbulence/calculators/complexity_spec.rb
|
143
|
+
- spec/turbulence/checks_environoment_spec.rb
|
142
144
|
- spec/turbulence/command_line_interface_spec.rb
|
145
|
+
- spec/turbulence/scatter_splot_generator_spec.rb
|
146
|
+
- spec/turbulence/scm/git_spec.rb
|
147
|
+
- spec/turbulence/scm/perforce_spec.rb
|
148
|
+
- spec/turbulence/turbulence_spec.rb
|
data/.DS_Store
DELETED
Binary file
|
data/cc.js
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
var directorySeries = {};
|