turbulence 1.2.3 → 1.3.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.
@@ -0,0 +1,50 @@
1
+ require 'rspec'
2
+ require 'turbulence'
3
+
4
+ describe Turbulence::CommandLineInterface::ConfigParser do
5
+ let(:config) { Turbulence::Configuration.new }
6
+
7
+ def parse(argv)
8
+ described_class.parse_argv_into_config(argv, config)
9
+ end
10
+
11
+ it "sets directory" do
12
+ parse %w( path/to/compute )
13
+ expect(config.directory).to eq 'path/to/compute'
14
+ end
15
+
16
+ it "sets SCM name to 'Perforce'" do
17
+ parse %w( --scm p4 )
18
+ expect(config.scm_name).to eq 'Perforce'
19
+ end
20
+
21
+ it "sets commit range" do
22
+ parse %w( --churn-range f3e1d7a6..830b9d3d9f )
23
+ expect(config.commit_range).to eq 'f3e1d7a6..830b9d3d9f'
24
+ end
25
+
26
+ it "sets compute mean" do
27
+ parse %w( --churn-mean )
28
+ expect(config.compute_mean).to be true
29
+ end
30
+
31
+ it "sets the exclusion pattern" do
32
+ parse %w( --exclude turbulence )
33
+ expect(config.exclusion_pattern).to eq 'turbulence'
34
+ end
35
+
36
+ it "sets the graph type" do
37
+ parse %w( --treemap )
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'
49
+ end
50
+ end
@@ -3,48 +3,63 @@ require 'turbulence'
3
3
 
4
4
  describe Turbulence::CommandLineInterface do
5
5
  let(:cli) { Turbulence::CommandLineInterface.new(%w(.), :output => nil) }
6
+
6
7
  describe "::TEMPLATE_FILES" do
7
8
  Turbulence::CommandLineInterface::TEMPLATE_FILES.each do |template_file|
8
- File.dirname(template_file).should == Turbulence::CommandLineInterface::TURBULENCE_TEMPLATE_PATH
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
9
12
  end
10
13
  end
14
+
11
15
  describe "#generate_bundle" do
12
16
  before do
13
17
  FileUtils.remove_dir("turbulence", true)
14
18
  end
15
19
  it "bundles the files" do
16
20
  cli.generate_bundle
17
- Dir.glob('turbulence/*').sort.should eq(["turbulence/cc.js",
18
- "turbulence/highcharts.js",
19
- "turbulence/jquery.min.js",
20
- "turbulence/treemap.html",
21
- "turbulence/turbulence.html"])
21
+ expect(Dir.glob('turbulence/*').sort).to eq(["turbulence/cc.js",
22
+ "turbulence/highcharts.js",
23
+ "turbulence/jquery.min.js",
24
+ "turbulence/treemap.html",
25
+ "turbulence/turbulence.html"])
22
26
  end
23
27
 
24
28
  it "passes along exclusion pattern" do
25
29
  cli = Turbulence::CommandLineInterface.new(%w(--exclude turbulence), :output => nil)
26
30
  cli.generate_bundle
27
31
  lines = File.new('turbulence/cc.js').readlines
28
- lines.any? { |l| l =~ /turbulence\.rb/ }.should be_false
32
+ expect(lines.any? { |l| l =~ /turbulence\.rb/ }).to be false
33
+ end
34
+
35
+ it "outputs to custom directory when --output is specified" do
36
+ custom_dir = 'tmp/custom_output'
37
+ FileUtils.remove_dir(custom_dir, true)
38
+ cli = Turbulence::CommandLineInterface.new(['--output', custom_dir], :output => nil)
39
+ cli.generate_bundle
40
+ expect(Dir.glob("#{custom_dir}/*").sort).to eq(["#{custom_dir}/cc.js",
41
+ "#{custom_dir}/highcharts.js",
42
+ "#{custom_dir}/jquery.min.js",
43
+ "#{custom_dir}/treemap.html",
44
+ "#{custom_dir}/turbulence.html"])
45
+ FileUtils.remove_dir(custom_dir, true)
29
46
  end
30
47
  end
31
- describe "command line options" do
32
- let(:cli_churn_range) { Turbulence::CommandLineInterface.new(%w(--churn-range f3e1d7a6..830b9d3d9f path/to/compute)) }
33
- let(:cli_churn_mean) { Turbulence::CommandLineInterface.new(%w(--churn-mean .)) }
34
- let(:cli_exclusion_pattern) { Turbulence::CommandLineInterface.new(%w(--exclude turbulence)) }
35
48
 
36
- it "sets churn range" do
37
- cli_churn_range.directory.should == 'path/to/compute'
38
- Turbulence::Calculators::Churn.commit_range.should == 'f3e1d7a6..830b9d3d9f'
49
+ describe "#output_path" do
50
+ before do
51
+ # Reset the singleton config between tests
52
+ Turbulence.instance_variable_set(:@config, nil)
39
53
  end
40
54
 
41
- it "sets churn mean" do
42
- cli_churn_mean.directory.should == '.'
43
- Turbulence::Calculators::Churn.compute_mean.should be_true
55
+ it "defaults to ./turbulence when output_dir is not set" do
56
+ cli = Turbulence::CommandLineInterface.new(%w(.), :output => nil)
57
+ expect(cli.output_path).to eq(File.join(Dir.pwd, "turbulence"))
44
58
  end
45
59
 
46
- it "sets the exclusion pattern" do
47
- cli_exclusion_pattern.exclusion_pattern.should == 'turbulence'
60
+ it "returns the custom output_dir when set" do
61
+ cli = Turbulence::CommandLineInterface.new(%w(--output custom/path), :output => nil)
62
+ expect(cli.output_path).to eq('custom/path')
48
63
  end
49
64
  end
50
65
  end
@@ -0,0 +1,19 @@
1
+ require 'rspec'
2
+ require 'rspec/its'
3
+ require 'turbulence'
4
+
5
+ describe Turbulence::Configuration do
6
+ describe "defaults" do
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 }
17
+ end
18
+ end
19
+
@@ -2,93 +2,98 @@ require 'turbulence'
2
2
 
3
3
  describe Turbulence::Generators::ScatterPlot do
4
4
  context "with both Metrics" do
5
- it "generates JavaScript" do
5
+ it "generates JavaScript", :aggregate_failures do
6
6
  generator = Turbulence::Generators::ScatterPlot.new(
7
- "foo.rb" => { Turbulence::Calculators::Churn => 1,
8
- Turbulence::Calculators::Complexity => 2 }
7
+ "foo.rb" => { :churn => 1,
8
+ :complexity => 2 }
9
9
  )
10
10
 
11
- generator.to_js.should =~ /var directorySeries/
12
- generator.to_js.should =~ /\"filename\"\:\"foo.rb\"/
13
- generator.to_js.should =~ /\"x\":1/
14
- generator.to_js.should =~ /\"y\":2/
11
+ expect(generator.to_js).to match(/var directorySeries/)
12
+ expect(generator.to_js).to match(/\"filename\"\:\"foo.rb\"/)
13
+ expect(generator.to_js).to match(/\"x\":1/)
14
+ expect(generator.to_js).to match(/\"y\":2/)
15
15
  end
16
16
  end
17
17
 
18
18
  context "with a missing Metric" do
19
19
  it "generates JavaScript" do
20
20
  generator = Turbulence::Generators::ScatterPlot.new(
21
- "foo.rb" => { Turbulence::Calculators::Churn => 1 }
21
+ "foo.rb" => { :churn => 1 }
22
22
  )
23
23
 
24
- generator.to_js.should == 'var directorySeries = {};'
24
+ expect(generator.to_js).to eq 'var directorySeries = {};'
25
25
  end
26
26
  end
27
27
 
28
28
  describe "#clean_metrics_from_missing_data" do
29
- let(:spg) {Turbulence::Generators::ScatterPlot.new({})}
29
+ let(:spg) { Turbulence::Generators::ScatterPlot.new({}) }
30
30
 
31
31
  it "removes entries with missing churn" do
32
- spg.stub(:metrics_hash).and_return("foo.rb" => {
33
- Turbulence::Calculators::Complexity => 88.3})
34
- spg.clean_metrics_from_missing_data.should == {}
32
+ allow(spg).to receive(:metrics_hash).and_return("foo.rb" => { :complexity => 88.3 })
33
+ expect(spg.clean_metrics_from_missing_data).to eq({})
35
34
  end
36
35
 
37
36
  it "removes entries with missing complexity" do
38
- spg.stub(:metrics_hash).and_return("foo.rb" => {
39
- Turbulence::Calculators::Churn => 1})
40
- spg.clean_metrics_from_missing_data.should == {}
37
+ allow(spg).to receive(:metrics_hash).and_return("foo.rb" => { :churn => 1 })
38
+ expect(spg.clean_metrics_from_missing_data).to eq({})
41
39
  end
42
40
 
43
41
  it "keeps entries with churn and complexity present" do
44
- spg.stub(:metrics_hash).and_return("foo.rb" => {
45
- Turbulence::Calculators::Churn => 1,
46
- Turbulence::Calculators::Complexity => 88.3})
47
- spg.clean_metrics_from_missing_data.should_not == {}
42
+ allow(spg).to receive(:metrics_hash).and_return("foo.rb" => {
43
+ :churn => 1,
44
+ :complexity => 88.3,
45
+ })
46
+
47
+ expect(spg.clean_metrics_from_missing_data).not_to eq({})
48
48
  end
49
49
  end
50
50
 
51
51
  describe "#grouped_by_directory" do
52
- let(:spg) {Turbulence::Generators::ScatterPlot.new("lib/foo/foo.rb" => {
53
- Turbulence::Calculators::Churn => 1},
54
- "lib/bar.rb" => {
55
- Turbulence::Calculators::Churn => 2} )}
56
-
57
- it "uses \".\" to denote flat hierarchy" do
58
- spg.stub(:metrics_hash).and_return("foo.rb" => {
59
- Turbulence::Calculators::Churn => 1
60
- })
61
- spg.grouped_by_directory.should == {"." => [["foo.rb", {Turbulence::Calculators::Churn => 1}]]}
62
- end
63
-
64
- it "takes full path into account" do
65
- spg.grouped_by_directory.should == {"lib/foo" => [["lib/foo/foo.rb", {Turbulence::Calculators::Churn => 1}]],
66
- "lib" => [["lib/bar.rb", {Turbulence::Calculators::Churn => 2}]]}
67
- end
52
+ let(:spg) {
53
+ Turbulence::Generators::ScatterPlot.new(
54
+ "lib/foo/foo.rb" => { :churn => 1 },
55
+ "lib/bar.rb" => { :churn => 2 }
56
+ )
57
+ }
58
+
59
+ it "uses \".\" to denote flat hierarchy" do
60
+ allow(spg).to receive(:metrics_hash).and_return("foo.rb" => { :churn => 1 })
61
+ expect(spg.grouped_by_directory).to eq({ "." => [["foo.rb", { :churn => 1 }]] })
62
+ end
63
+
64
+ it "takes full path into account" do
65
+ expect(spg.grouped_by_directory).to eq({
66
+ "lib/foo" => [["lib/foo/foo.rb", { :churn => 1 }]],
67
+ "lib" => [["lib/bar.rb", { :churn => 2 }]]
68
+ })
69
+ end
68
70
  end
69
71
 
70
72
  describe "#file_metrics_for_directory" do
71
- let(:spg) {Turbulence::Generators::ScatterPlot.new({})}
73
+ let(:spg) { Turbulence::Generators::ScatterPlot.new({}) }
74
+
72
75
  it "assigns :filename, :x, :y" do
73
- spg.file_metrics_for_directory("lib/foo/foo.rb" => {
74
- Turbulence::Calculators::Churn => 1,
75
- Turbulence::Calculators::Complexity => 88.2}).should == [{:filename => "lib/foo/foo.rb",
76
- :x => 1, :y => 88.2}]
76
+ result = spg.file_metrics_for_directory("lib/foo/foo.rb" => {
77
+ :churn => 1,
78
+ :complexity => 88.2,
79
+ })
80
+ expect(result).to eq [{ :filename => "lib/foo/foo.rb", :x => 1, :y => 88.2 }]
77
81
  end
78
82
  end
79
83
 
80
84
  describe Turbulence::FileNameMangler do
81
85
  subject { Turbulence::FileNameMangler.new }
86
+
82
87
  it "anonymizes a string" do
83
- subject.mangle_name("chad").should_not == "chad"
88
+ expect(subject.mangle_name("chad")).not_to eq "chad"
84
89
  end
85
90
 
86
91
  it "maintains standard directory names" do
87
- subject.mangle_name("/app/controllers/chad.rb").should =~ %r{/app/controllers/1.rb}
92
+ expect(subject.mangle_name("/app/controllers/chad.rb")).to match(%r{/app/controllers/1.rb})
88
93
  end
89
94
 
90
95
  it "honors leading path separators" do
91
- subject.mangle_name("/a/b/c.rb").should == "/1/2/3.rb"
96
+ expect(subject.mangle_name("/a/b/c.rb")).to eq "/1/2/3.rb"
92
97
  end
93
98
  end
94
99
  end
@@ -2,24 +2,24 @@ require 'turbulence'
2
2
 
3
3
  describe Turbulence::Generators::TreeMap do
4
4
  context "with both Metrics" do
5
- it "generates JavaScript" do
5
+ it "generates JavaScript", :aggregate_failures do
6
6
  generator = Turbulence::Generators::TreeMap.new(
7
- "foo.rb" => { Turbulence::Calculators::Churn => 1,
8
- Turbulence::Calculators::Complexity => 2 }
7
+ "foo.rb" => { :churn => 1,
8
+ :complexity => 2 }
9
9
  )
10
10
 
11
- generator.build_js.should =~ /var treemap_data/
12
- generator.build_js.should =~ /\'foo.rb\'/
11
+ expect(generator.build_js).to match(/var treemap_data/)
12
+ expect(generator.build_js).to match(/\'foo.rb\'/)
13
13
  end
14
14
  end
15
15
 
16
16
  context "with a missing Metric" do
17
17
  it "generates JavaScript" do
18
18
  generator = Turbulence::Generators::TreeMap.new(
19
- "foo.rb" => { Turbulence::Calculators::Churn => 1 }
19
+ "foo.rb" => { :churn => 1 }
20
20
  )
21
21
 
22
- generator.build_js.should == "var treemap_data = [['File', 'Parent', 'Churn (size)', 'Complexity (color)'],\n['Root', null, 0, 0],\n];"
22
+ expect(generator.build_js).to eq "var treemap_data = [['File', 'Parent', 'Churn (size)', 'Complexity (color)'],\n['Root', null, 0, 0],\n];"
23
23
  end
24
24
  end
25
25
  end
@@ -5,25 +5,26 @@ require 'fileutils'
5
5
  describe Turbulence::Scm::Git do
6
6
  describe "::is_repo?" do
7
7
  before do
8
- @tmp = Dir.mktmpdir(nil,'..')
8
+ # Create temp dir in system temp location (outside any git repo)
9
+ @tmp = Dir.mktmpdir('turbulence-test')
9
10
  end
10
11
  after do
11
- FileUtils.rmdir(@tmp)
12
+ FileUtils.remove_entry(@tmp)
12
13
  end
13
14
  it "returns true for the working directory" do
14
- Turbulence::Scm::Git.is_repo?(".").should == true
15
+ expect(Turbulence::Scm::Git.is_repo?(".")).to eq true
15
16
  end
16
17
  it "return false for a newly created tmp directory" do
17
- Turbulence::Scm::Git.is_repo?(@tmp).should == false
18
+ expect(Turbulence::Scm::Git.is_repo?(@tmp)).to eq false
18
19
  end
19
20
  end
20
21
 
21
22
  describe "::log_command" do
22
23
  it "takes an optional argument specify to the range" do
23
- expect{Turbulence::Scm::Git.log_command("d551e63f79a90430e560ea871f4e1e39e6e739bd HEAD")}.to_not raise_error
24
+ expect { Turbulence::Scm::Git.log_command("d551e63f79a90430e560ea871f4e1e39e6e739bd HEAD") }.to_not raise_error
24
25
  end
25
26
  it "lists insertions/deletions per file and change" do
26
- Turbulence::Scm::Git.log_command.should match(/\d+\t\d+\t[A-z.]*/)
27
+ expect(Turbulence::Scm::Git.log_command).to match(/\d+\t\d+\t[A-z.]*/)
27
28
  end
28
29
  end
29
30
  end
@@ -1,11 +1,10 @@
1
1
  require 'turbulence/scm/perforce'
2
- require 'rspec/mocks'
3
2
 
4
3
  describe Turbulence::Scm::Perforce do
5
- let (:p4_scm) { Turbulence::Scm::Perforce }
4
+ let(:p4_scm) { Turbulence::Scm::Perforce }
6
5
 
7
6
  before do
8
- p4_scm.stub(:p4_list_changes) do
7
+ allow(p4_scm).to receive(:p4_list_changes).and_return(
9
8
  "Change 62660 on 2005/11/28 by x@client 'CHANGED: adapted to DESCODE '
10
9
  Change 45616 on 2005/07/12 by x@client 'ADDED: trigger that builds and '
11
10
  Change 45615 on 2005/07/12 by x@client 'ADDED: for testing purposes '
@@ -13,9 +12,9 @@ Change 45614 on 2005/07/12 by x@client 'COSMETIC: updated header '
13
12
  Change 11250 on 2004/09/17 by x@client 'CHANGED: trigger now also allow'
14
13
  Change 9250 on 2004/08/20 by x@client 'BUGFIX: bug#1583 (People can so'
15
14
  Change 5560 on 2004/04/26 by x@client 'ADDED: The \"BRANCHED\" tag.'"
16
- end
15
+ )
17
16
 
18
- p4_scm.stub(:p4_describe_change).with("5560") do
17
+ allow(p4_scm).to receive(:p4_describe_change).with("5560").and_return(
19
18
  "Change 5560 by x@client on 2004/04/26 17:25:03
20
19
 
21
20
  ADDED: The \"BRANCHED\" tag.
@@ -38,105 +37,111 @@ changed 1 chunks 3 / 3 lines
38
37
  add 0 chunks 0 lines
39
38
  deleted 0 chunks 0 lines
40
39
  changed 1 chunks 3 / 1 lines"
41
- end
40
+ )
42
41
  end
43
42
 
44
43
  describe "::is_repo?" do
45
44
  before :each do
46
- ENV.stub(:[]).with("P4CLIENT").and_return(nil)
47
- ENV.stub(:[]).with("PATH").and_return("")
45
+ allow(ENV).to receive(:[]).with("P4CLIENT").and_return(nil)
46
+ allow(ENV).to receive(:[]).with("PATH").and_return("")
48
47
  end
49
48
 
50
49
  it "returns true if P4CLIENT is set " do
51
- ENV.stub(:[]).with("P4CLIENT").and_return("c-foo.bar")
50
+ allow(ENV).to receive(:[]).with("P4CLIENT").and_return("c-foo.bar")
52
51
 
53
- Turbulence::Scm::Perforce.is_repo?(".").should be_true
52
+ expect(Turbulence::Scm::Perforce.is_repo?(".")).to be true
54
53
  end
55
54
 
56
- it "returns false if P4CLIENT is empty" do
57
- Turbulence::Scm::Perforce.is_repo?(".").should be_false
55
+ it "returns false if P4CLIENT is empty" do
56
+ expect(Turbulence::Scm::Perforce.is_repo?(".")).to be false
58
57
  end
59
58
 
60
59
  it "returns false if p4 is not available" do
61
- Turbulence::Scm::Perforce.is_repo?(".").should be_false
60
+ expect(Turbulence::Scm::Perforce.is_repo?(".")).to be false
62
61
  end
63
62
  end
64
63
 
65
64
  describe "::log_command" do
66
65
  before do
67
- p4_scm.stub(:depot_to_local).with("//admin/scripts/triggers/enforce-submit-comment.py")\
66
+ allow(p4_scm).to receive(:depot_to_local)
67
+ .with("//admin/scripts/triggers/enforce-submit-comment.py")
68
68
  .and_return("triggers/enforce-submit-comments.py")
69
- p4_scm.stub(:depot_to_local).with("//admin/scripts/triggers/check-consistency.py")\
69
+ allow(p4_scm).to receive(:depot_to_local)
70
+ .with("//admin/scripts/triggers/check-consistency.py")
70
71
  .and_return("triggers/check-consistency.py")
71
- p4_scm.stub(:p4_list_changes) do
72
+ allow(p4_scm).to receive(:p4_list_changes).and_return(
72
73
  "Change 5560 on 2004/04/26 by x@client 'ADDED: The \"BRANCHED\" tag.'"
73
- end
74
+ )
74
75
  end
75
76
 
76
77
  it "takes an optional argument to specify the range" do
77
- expect{Turbulence::Scm::Perforce.log_command("@1,2")}.to_not raise_error
78
+ expect { Turbulence::Scm::Perforce.log_command("@1,2") }.to_not raise_error
78
79
  end
79
80
 
80
81
  it "lists insertions/deletions per file and change" do
81
- Turbulence::Scm::Perforce.log_command().should match(/\d+\t\d+\t[A-z.]*/)
82
+ expect(Turbulence::Scm::Perforce.log_command()).to match(/\d+\t\d+\t[A-z.]*/)
82
83
  end
83
84
  end
84
85
 
85
86
  describe "::changes" do
86
87
  it "lists changenumbers from parsing 'p4 changes' output" do
87
- p4_scm.changes.should =~ %w[62660 45616 45615 45614 11250 9250 5560]
88
+ expect(p4_scm.changes).to match_array(%w[62660 45616 45615 45614 11250 9250 5560])
88
89
  end
89
90
  end
90
91
 
91
92
  describe "::files_per_change" do
92
93
  before do
93
- p4_scm.stub(:depot_to_local).with("//admin/scripts/triggers/enforce-submit-comment.py")\
94
+ allow(p4_scm).to receive(:depot_to_local)
95
+ .with("//admin/scripts/triggers/enforce-submit-comment.py")
94
96
  .and_return("triggers/enforce-submit-comments.py")
95
- p4_scm.stub(:depot_to_local).with("//admin/scripts/triggers/check-consistency.py")\
97
+ allow(p4_scm).to receive(:depot_to_local)
98
+ .with("//admin/scripts/triggers/check-consistency.py")
96
99
  .and_return("triggers/check-consistency.py")
97
100
  end
98
101
 
99
102
  it "lists files with churn" do
100
- p4_scm.files_per_change("5560").should =~ [[4,"triggers/enforce-submit-comments.py"],
101
- [1,"triggers/check-consistency.py"]]
103
+ expect(p4_scm.files_per_change("5560")).to match_array([
104
+ [4, "triggers/enforce-submit-comments.py"],
105
+ [1, "triggers/check-consistency.py"]
106
+ ])
102
107
  end
103
108
  end
104
109
 
105
110
  describe "::transform_for_output" do
106
111
  it "adds a 0 for deletions" do
107
- p4_scm.transform_for_output([1,"triggers/check-consistency.py"]).should == "1\t0\ttriggers/check-consistency.py\n"
112
+ expect(p4_scm.transform_for_output([1, "triggers/check-consistency.py"])).to eq "1\t0\ttriggers/check-consistency.py\n"
108
113
  end
109
114
  end
110
115
 
111
116
  describe "::depot_to_local" do
112
117
  describe "on windows" do
113
118
  before do
114
- p4_scm.stub(:extract_clientfile_from_fstat_of).and_return("D:/Perforce/admin/scripts/triggers/enforce-no-head-change.py")
115
- FileUtils.stub(:pwd).and_return("D:/Perforce")
119
+ allow(p4_scm).to receive(:extract_clientfile_from_fstat_of)
120
+ .and_return("D:/Perforce/admin/scripts/triggers/enforce-no-head-change.py")
121
+ allow(FileUtils).to receive(:pwd).and_return("D:/Perforce")
116
122
  end
117
123
 
118
124
  it "converts depot-style paths to local paths using forward slashes" do
119
- p4_scm.depot_to_local("//admin/scripts/triggers/enforce-no-head-change.py").should \
120
- == "admin/scripts/triggers/enforce-no-head-change.py"
125
+ expect(p4_scm.depot_to_local("//admin/scripts/triggers/enforce-no-head-change.py")).to eq "admin/scripts/triggers/enforce-no-head-change.py"
121
126
  end
122
127
  end
123
128
 
124
129
  describe "on unix" do
125
130
  before do
126
- p4_scm.stub(:extract_clientfile_from_fstat_of).and_return("/home/jhwist/admin/scripts/triggers/enforce-no-head-change.py")
127
- FileUtils.stub(:pwd).and_return("/home/jhwist")
131
+ allow(p4_scm).to receive(:extract_clientfile_from_fstat_of)
132
+ .and_return("/home/jhwist/admin/scripts/triggers/enforce-no-head-change.py")
133
+ allow(FileUtils).to receive(:pwd).and_return("/home/jhwist")
128
134
  end
129
135
 
130
136
  it "converts depot-style paths to local paths using forward slashes" do
131
- p4_scm.depot_to_local("//admin/scripts/triggers/enforce-no-head-change.py").should \
132
- == "admin/scripts/triggers/enforce-no-head-change.py"
137
+ expect(p4_scm.depot_to_local("//admin/scripts/triggers/enforce-no-head-change.py")).to eq "admin/scripts/triggers/enforce-no-head-change.py"
133
138
  end
134
139
  end
135
140
  end
136
141
 
137
142
  describe "::extract_clientfile_from_fstat_of" do
138
143
  before do
139
- p4_scm.stub(:p4_fstat) do
144
+ allow(p4_scm).to receive(:p4_fstat).and_return(
140
145
  "... depotFile //admin/scripts/triggers/enforce-no-head-change.py
141
146
  ... clientFile /home/jhwist/admin/scripts/triggers/enforce-no-head-change.py
142
147
  ... isMapped
@@ -147,24 +152,23 @@ changed 1 chunks 3 / 1 lines"
147
152
  ... headChange 211211
148
153
  ... headModTime 1214555028
149
154
  ... haveRev 5"
150
- end
155
+ )
151
156
  end
152
157
 
153
- it "uses clientFile field" do
154
- p4_scm.extract_clientfile_from_fstat_of("//admin/scripts/triggers/enforce-no-head-change.py").should ==
155
- "/home/jhwist/admin/scripts/triggers/enforce-no-head-change.py"
158
+ it "uses clientFile field" do
159
+ expect(p4_scm.extract_clientfile_from_fstat_of("//admin/scripts/triggers/enforce-no-head-change.py")).to eq "/home/jhwist/admin/scripts/triggers/enforce-no-head-change.py"
156
160
  end
157
161
  end
158
162
 
159
163
  describe "::sum_of_changes" do
160
164
  it "sums up changes" do
161
165
  output = "add 1 chunks 1 lines\ndeleted 0 chunks 0 lines\nchanged 1 chunks 3 / 3 lines"
162
- p4_scm.sum_of_changes(output).should == 4
166
+ expect(p4_scm.sum_of_changes(output)).to eq 4
163
167
  end
164
168
 
165
169
  it "ignores junk" do
166
170
  output = "add nothing, change nothing"
167
- p4_scm.sum_of_changes(output).should == 0
171
+ expect(p4_scm.sum_of_changes(output)).to eq 0
168
172
  end
169
173
  end
170
174
  end
@@ -2,14 +2,22 @@ require 'rspec'
2
2
  require 'turbulence'
3
3
 
4
4
  describe Turbulence do
5
+ subject(:turb) { Turbulence.new(config) }
6
+
7
+ let(:config) {
8
+ Turbulence::Configuration.new.tap do |config|
9
+ config.directory = '.'
10
+ config.exclusion_pattern = nil
11
+ config.output = nil
12
+ end
13
+ }
14
+
5
15
  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"
16
+ expect(turb.files_of_interest).to include "lib/turbulence.rb"
9
17
  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"
18
+
19
+ it "filters out excluded files" do
20
+ config.exclusion_pattern = 'turbulence'
21
+ expect(turb.files_of_interest).not_to include "lib/turbulence.rb"
14
22
  end
15
23
  end
data/turbulence.gemspec CHANGED
@@ -1,4 +1,5 @@
1
- # -*- encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
+
2
3
  $:.push File.expand_path("../lib", __FILE__)
3
4
  require "turbulence/version"
4
5
 
@@ -8,21 +9,24 @@ Gem::Specification.new do |s|
8
9
  s.platform = Gem::Platform::RUBY
9
10
  s.authors = ["Chad Fowler", "Michael Feathers", "Corey Haines"]
10
11
  s.email = ["chad@chadfowler.com", "mfeathers@obtiva.com", "coreyhaines@gmail.com"]
11
- s.homepage = "http://chadfowler.com"
12
- s.add_dependency "flog", "~>4.1"
13
- s.add_dependency "json", ">= 1.4.6"
12
+ s.homepage = "https://github.com/chad/turbulence"
13
+ s.license = "MIT"
14
+
15
+ s.add_dependency "flog", ">= 4.1"
16
+ s.add_dependency "json"
14
17
  s.add_dependency "launchy", ">= 2.0.0"
15
- s.add_development_dependency 'rspec', '~> 2.14.0'
18
+ s.add_dependency "racc" # Required by flog's ruby_parser, removed from stdlib in Ruby 3.3+
19
+
20
+ s.add_development_dependency 'rspec', '~> 3.0'
21
+ s.add_development_dependency 'rspec-its'
16
22
  s.add_development_dependency 'rake'
17
23
 
18
24
  s.summary = %q{Automates churn + flog scoring on a git repo for a Ruby project}
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}
20
-
21
- s.rubyforge_project = "turbulence"
25
+ s.description = %q{Automates churn + flog scoring on a git repo for a Ruby project. Based on the article https://www.stickyminds.com/article/getting-empirical-about-refactoring}
22
26
 
23
27
  s.files = `git ls-files`.split("\n")
24
28
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
25
29
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
26
30
  s.require_paths = ["lib"]
27
- s.required_ruby_version = '>= 1.8.7'
31
+ s.required_ruby_version = '>= 3.0'
28
32
  end