hotspots 1.0.0 → 1.2.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,65 @@
1
+ require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'minitest_helper')
2
+
3
+ class Hotspots
4
+ class StubLogger
5
+ attr_accessor :level
6
+ def initialize
7
+ @level = :uninitialized
8
+ end
9
+ end
10
+
11
+ describe "Configuration" do
12
+ describe "#initialize" do
13
+ let(:stub_logger) { StubLogger.new }
14
+ let(:configuration) { Configuration.new(:logger => stub_logger, :info_log_level => :info_level, :error_log_level => :error_level) }
15
+
16
+ it "defaults repository to the current path" do
17
+ expect(configuration.repository).must_equal "."
18
+ end
19
+
20
+ it "defaults time to 15" do
21
+ expect(configuration.time).must_equal 15
22
+ end
23
+
24
+ it "defaults file filter to empty string" do
25
+ expect(configuration.file_filter).must_equal ""
26
+ end
27
+
28
+ it "defaults message filters to array with an empty string" do
29
+ expect(configuration.message_filters).must_equal [""]
30
+ end
31
+
32
+ it "defaults cutoff to 0" do
33
+ expect(configuration.cutoff).must_equal 0
34
+ end
35
+
36
+ it "set a logger" do
37
+ expect(configuration.logger).wont_be :nil?
38
+ end
39
+
40
+ it "defaults the logger level to error" do
41
+ expect(configuration.logger.level).must_equal :error_level
42
+ end
43
+
44
+ it "defaults exit code to nil" do
45
+ expect(configuration.exit_strategy.code).must_be :nil?
46
+ end
47
+
48
+ it "defaults exit message to empty string" do
49
+ expect(configuration.exit_strategy.message).must_equal ""
50
+ end
51
+ end
52
+
53
+ describe "#initialize without default logger" do
54
+ let(:configuration) { Configuration.new }
55
+
56
+ it "set a logger" do
57
+ expect(configuration.logger).wont_be :nil?
58
+ end
59
+
60
+ it "defaults the logger level to error" do
61
+ expect(configuration.logger.level).must_equal ::Logger::ERROR
62
+ end
63
+ end
64
+ end
65
+ end
@@ -1,163 +1,135 @@
1
- require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'minitest_helper')
1
+ require "logger"
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), "..", "minitest_helper")
2
3
 
3
- module Hotspots
4
+ class Hotspots
4
5
  describe "OptionsParser" do
5
- before do
6
- @parser = OptionsParser.new
7
- end
8
-
9
- describe "#initialize" do
10
- it "defaults repository to current path" do
11
- @parser.parse[:repository].must_equal "."
12
- end
13
-
14
- it "defaults time to 15" do
15
- @parser.parse[:time].must_equal 15
16
- end
17
-
18
- it "defaults file filter to empty string" do
19
- @parser.parse[:file_filter].must_equal ""
20
- end
21
-
22
- it "defaults message filters to array with an empty string" do
23
- @parser.parse[:message_filters].must_equal [""]
24
- end
25
-
26
- it "defaults cutoff to 0" do
27
- @parser.parse[:cutoff].must_equal 0
6
+ let(:info_log_level) { ::Logger::INFO }
7
+ let(:error_log_level) { ::Logger::ERROR }
8
+ let(:logger) { ::Logger.new(STDOUT) }
9
+ let(:configuration) { Configuration.new(:logger => logger, :info_log_level => info_log_level, :error_log_level => error_log_level) }
10
+ let(:parser) { OptionsParser.new(:configuration => configuration) }
11
+
12
+ describe "#parse" do
13
+ ["--repository", "-r"].each do |option|
14
+ describe option do
15
+ it "sets the specified value repository" do
16
+ expect(parser.parse(option, "rails").repository).must_equal "rails"
17
+ end
18
+
19
+ it "sets empty repository when missing" do
20
+ expect(parser.parse(option).repository).must_equal ""
21
+ end
22
+ end
28
23
  end
29
24
 
30
- it "defaults verbose to nil" do
31
- @parser.parse[:verbose].must_equal false
32
- end
25
+ ["--time", "-t"].each do |option|
26
+ describe option do
27
+ it "sets the specified time to consider" do
28
+ expect(parser.parse(option, "8").time).must_equal 8
29
+ end
33
30
 
34
- it "defaults exit code to nil" do
35
- @parser.parse[:exit_strategy].code.must_equal nil
31
+ it "sets zero time when missing" do
32
+ expect(parser.parse(option).time).must_equal 0
33
+ end
34
+ end
36
35
  end
37
36
 
38
- it "defaults exit message to empty string" do
39
- @parser.parse[:exit_strategy].message.must_equal ""
40
- end
37
+ ["--cutoff", "-c"].each do |option|
38
+ describe option do
39
+ it "sets the specified cutoff" do
40
+ expect(parser.parse(option, "5").cutoff).must_equal 5
41
+ end
41
42
 
42
- it "defaults colour to false" do
43
- @parser.parse[:colour].must_equal false
43
+ it "sets zero cutoff when missing" do
44
+ expect(parser.parse(option).cutoff).must_equal 0
45
+ end
46
+ end
44
47
  end
45
- end
46
48
 
47
- ["--repository", "--repo", "-r"].each do |option|
48
- describe option do
49
- it "sets the specified value repository" do
50
- @parser.parse(option, "rails")[:repository].must_equal "rails"
51
- end
49
+ ["--file-filter", "-f"].each do |option|
50
+ describe option do
51
+ it "sets the specified file-filter" do
52
+ expect(parser.parse(option, "rb").file_filter).must_equal "rb"
53
+ end
52
54
 
53
- it "sets empty repository when missing" do
54
- @parser.parse(option)[:repository].must_equal ""
55
+ it "sets empty file-filter when missing" do
56
+ expect(parser.parse(option).file_filter).must_equal ""
57
+ end
55
58
  end
56
59
  end
57
- end
58
60
 
59
- ["--time", "--ti", "-t"].each do |option|
60
- describe option do
61
- it "sets the specified time to consider" do
62
- @parser.parse(option, "8")[:time].must_equal 8
63
- end
61
+ ["--message-filter", "-m"].each do |option|
62
+ describe option do
63
+ it "sets the specified message filters" do
64
+ expect(parser.parse(option, "cleanup|defect").message_filters).must_equal ["cleanup", "defect"]
65
+ end
64
66
 
65
- it "sets zero time when missing" do
66
- @parser.parse(option)[:time].must_equal 0
67
+ it "sets empty message-filter when missing" do
68
+ expect(parser.parse(option).message_filters).must_equal []
69
+ end
67
70
  end
68
71
  end
69
- end
70
72
 
71
- ["--cutoff", "--cut", "-c"].each do |option|
72
- describe option do
73
- it "sets the specified cutoff" do
74
- @parser.parse(option, "5")[:cutoff].must_equal 5
75
- end
76
-
77
- it "sets zero cutoff when missing" do
78
- @parser.parse(option)[:cutoff].must_equal 0
73
+ ["--verbose", "-v"].each do |option|
74
+ describe option do
75
+ it "sets the log level to info" do
76
+ expect(parser.parse(option).log_level).must_equal info_log_level
77
+ end
79
78
  end
80
79
  end
81
- end
82
80
 
83
- ["--file-filter", "--file", "-f"].each do |option|
84
- describe option do
85
- it "sets the specified file-filter" do
86
- @parser.parse(option, "rb")[:file_filter].must_equal "rb"
87
- end
81
+ ["--version"].each do |option|
82
+ describe option do
83
+ it "sets exit code to zero" do
84
+ expect(parser.parse(option).exit_strategy.code).must_equal 0
85
+ end
88
86
 
89
- it "sets empty file-filter when missing" do
90
- @parser.parse(option)[:file_filter].must_equal ""
87
+ it "sets a version message" do
88
+ expect(parser.parse(option).exit_strategy.message).must_be :include?, ::Hotspots::VERSION
89
+ end
91
90
  end
92
91
  end
93
- end
94
92
 
95
- ["--message-filter", "--message", "-m"].each do |option|
96
- describe option do
97
- it "sets the specified message filters" do
98
- @parser.parse(option, "cleanup|defect")[:message_filters].must_equal ["cleanup", "defect"]
99
- end
93
+ ["--help", "-h"].each do |option|
94
+ describe option do
95
+ it "sets exit code to zero" do
96
+ expect(parser.parse(option).exit_strategy.code).must_equal 0
97
+ end
100
98
 
101
- it "sets empty message-filter when missing" do
102
- @parser.parse(option)[:message_filters].must_equal []
99
+ it "sets an exit message" do
100
+ expect(parser.parse(option).exit_strategy.message).wont_be_empty
101
+ end
103
102
  end
104
103
  end
105
- end
106
104
 
107
- ["--verbose", "-v"].each do |option|
108
- describe option do
109
- it "sets the console logger" do
110
- @parser.parse(option)[:verbose].must_equal true
111
- end
105
+ it "doesn't mutate options" do
106
+ parser.parse("--help")
107
+ expect(configuration.exit_strategy.code).must_be :nil?
112
108
  end
113
- end
114
109
 
115
- ["--color", "--colour", "-C"].each do |option|
116
- describe option do
117
- it "sets colours" do
118
- @parser.parse(option)[:colour].must_equal true
119
- end
120
- end
121
- end
110
+ describe "when parsing an invalid option" do
111
+ let(:options) { parser.parse("--invalid-option") }
122
112
 
123
- ["--help", "-h"].each do |option|
124
- describe option do
125
- it "sets exit code to zero" do
126
- @parser.parse(option)[:exit_strategy].code.must_equal 0
113
+ it "sets an exit code" do
114
+ expect(options.exit_strategy.code).must_equal 1
127
115
  end
128
116
 
129
117
  it "sets an exit message" do
130
- @parser.parse(option)[:exit_strategy].message.wont_be_empty
118
+ expect(options.exit_strategy.message).wont_be_empty
131
119
  end
132
120
  end
133
- end
134
-
135
- describe "on an invalid option" do
136
- before do
137
- @options = @parser.parse("--invalid-option")
138
- end
139
-
140
- it "sets an exit code" do
141
- @options[:exit_strategy].code.must_equal 1
142
- end
143
121
 
144
- it "sets an exit message" do
145
- @options[:exit_strategy].message.wont_be_empty
146
- end
147
- end
122
+ describe "when parsing an invalid argument" do
123
+ let(:options) { parser.parse("--repository", "") }
148
124
 
149
- describe "on an invalid argument" do
150
- before do
151
- @options = @parser.parse("--repo", "")
152
- end
153
-
154
- it "sets an exit code" do
155
- @options[:exit_strategy].code.must_equal 1
156
- end
125
+ it "sets an exit code" do
126
+ expect(options.exit_strategy.code).must_equal 1
127
+ end
157
128
 
158
- it "sets an exit message" do
159
- @options[:exit_strategy].message.wont_be_empty
129
+ it "sets an exit message" do
130
+ expect(options.exit_strategy.message).wont_be_empty
131
+ end
160
132
  end
161
133
  end
162
134
  end
163
- end
135
+ end
@@ -0,0 +1,39 @@
1
+ require File.join(File.expand_path(File.dirname(__FILE__)), "..", "..", "minitest_helper")
2
+
3
+ module Hotspots::Repository
4
+ describe "GitCommand" do
5
+ describe "Log" do
6
+ describe "#to_s" do
7
+ describe "when message filter exists" do
8
+ it "includes a grep clause" do
9
+ log_command = GitCommand::Log.new :since_days => 20, :message_filter => "Foo|Bar"
10
+ expect(log_command.to_s).must_equal 'git log --pretty="%H" --since="20 days ago" --grep "Foo|Bar"'
11
+ end
12
+ end
13
+
14
+ describe "when message filter doesn't exist" do
15
+ it "doesn't have a grep clause" do
16
+ log_command = GitCommand::Log.new :since_days => 20
17
+ expect(log_command.to_s).must_equal 'git log --pretty="%H" --since="20 days ago"'
18
+ end
19
+ end
20
+
21
+ describe "when message filter is set to an empty string" do
22
+ it "grep clause is ignored" do
23
+ log_command = GitCommand::Log.new :since_days => 20, :message_filter => ""
24
+ expect(log_command.to_s).must_equal 'git log --pretty="%H" --since="20 days ago"'
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ describe "Show" do
31
+ describe "#to_s" do
32
+ it "constructs a git show with one-line format" do
33
+ show_command = GitCommand::Show.new :commit_hash => "abc123"
34
+ expect(show_command.to_s).must_equal 'git show --oneline --name-only abc123'
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,88 @@
1
+ require File.join(File.expand_path(File.dirname(__FILE__)), "..", "..", "minitest_helper")
2
+
3
+ module Hotspots::Repository
4
+ class GitDriverStub
5
+ def initialize
6
+ @pretty_log = ["SHA1\nSHA2", "SHA2\nSHA3"]
7
+ @commits = {
8
+ "SHA1" => "SHA1 commit message\nfile1\nfile2",
9
+ "SHA2" => "SHA1 commit message\nfile2\nfile3\nfile5",
10
+ "SHA3" => "SHA1 commit message\nfile4",
11
+ }
12
+ @pretty_log_cycle = 0
13
+ end
14
+
15
+ def pretty_log(options)
16
+ @pretty_log[@pretty_log_cycle].tap do
17
+ @pretty_log_cycle = (@pretty_log_cycle + 1) % 2
18
+ end
19
+ end
20
+
21
+ def show_one_line_names(options)
22
+ @commits[options[:commit_hash]]
23
+ end
24
+ end
25
+
26
+ describe GitDriverStub do
27
+ subject { GitDriverStub.new }
28
+
29
+ describe "#pretty_log" do
30
+ it "is sane" do
31
+ expect(subject.pretty_log(:time => 10, :message_filter => "Foo")).must_equal "SHA1\nSHA2"
32
+ expect(subject.pretty_log(:time => 10, :message_filter => "Bar")).must_equal "SHA2\nSHA3"
33
+ end
34
+ end
35
+
36
+ describe "#show_one_line_names" do
37
+ it "is sane" do
38
+ expect(subject.show_one_line_names(:commit_hash => "SHA2")).
39
+ must_equal "SHA1 commit message\nfile2\nfile3\nfile5"
40
+ end
41
+ end
42
+ end
43
+
44
+ describe "GitParser" do
45
+ describe "#filtered_commit_hashes" do
46
+ it "fetches a commit hash based on filter and time" do
47
+ mock_git_driver = Minitest::Mock.new
48
+ options = {:time => 10, :message_filters => ["Foo"]}
49
+ git_parser = GitParser.new mock_git_driver, options
50
+
51
+ mock_git_driver.expect(:pretty_log, "SHA1\nSHA2", [{:since_days => options[:time], :message_filter => "Foo"}])
52
+
53
+ expect(git_parser.filtered_commit_hashes).must_equal(["SHA1", "SHA2"])
54
+
55
+ expect(mock_git_driver.verify).must_equal true
56
+ end
57
+
58
+ it "fetches multiple commit hashes" do
59
+ options = {:time => 10, :message_filters => ["Foo", "Bar"]}
60
+ git_parser = GitParser.new GitDriverStub.new, options
61
+
62
+ expect(git_parser.filtered_commit_hashes).must_equal(["SHA1", "SHA2", "SHA3"])
63
+ end
64
+ end
65
+
66
+ describe "#files" do
67
+ it "finds all affected files for a commit message" do
68
+ mock_git_driver = Minitest::Mock.new
69
+ options = {:time => 10, :message_filters => ["Foo"]}
70
+ git_parser = GitParser.new mock_git_driver, options
71
+
72
+ mock_git_driver.expect(:pretty_log, "SHA1", [{:since_days => options[:time], :message_filter => "Foo"}])
73
+ mock_git_driver.expect(:show_one_line_names, "SHA1 CommitMessage\nfile1\nfile2", [{:commit_hash => "SHA1"}])
74
+
75
+ expect(git_parser.files).must_equal(["file1", "file2"])
76
+
77
+ expect(mock_git_driver.verify).must_equal true
78
+ end
79
+
80
+ it "finds all affected files for multiple commit messages" do
81
+ options = {:time => 10, :message_filters => ["Foo", "Bar"]}
82
+ git_parser = GitParser.new GitDriverStub.new, options
83
+
84
+ expect(git_parser.files).must_equal(["file1", "file2", "file2", "file3", "file5", "file4"])
85
+ end
86
+ end
87
+ end
88
+ end
@@ -1,6 +1,6 @@
1
1
  require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'minitest_helper')
2
2
 
3
- module Hotspots
3
+ class Hotspots
4
4
  describe "Store" do
5
5
  it "counts occurances of a line present once" do
6
6
  lines = [
@@ -8,8 +8,8 @@ module Hotspots
8
8
  "efg.txt"
9
9
  ]
10
10
  store = Store.new(lines)
11
- store.on("abc.txt").must_equal 1
12
- store.on("efg.txt").must_equal 1
11
+ expect(store.on("abc.txt")).must_equal 1
12
+ expect(store.on("efg.txt")).must_equal 1
13
13
  end
14
14
 
15
15
  it "counts occurances of a line present multiple times" do
@@ -19,7 +19,7 @@ module Hotspots
19
19
  "efg.txt"
20
20
  ]
21
21
  store = Store.new(lines)
22
- store.on("abc.txt").must_equal 2
22
+ expect(store.on("abc.txt")).must_equal 2
23
23
  end
24
24
 
25
25
  it "identifies zero occurances" do
@@ -28,7 +28,7 @@ module Hotspots
28
28
  "efg.txt"
29
29
  ]
30
30
  store = Store.new(lines)
31
- store.on("absent.txt").must_equal 0
31
+ expect(store.on("absent.txt")).must_equal 0
32
32
  end
33
33
 
34
34
  it "neglects empty lines" do
@@ -36,7 +36,7 @@ module Hotspots
36
36
  " "
37
37
  ]
38
38
  store = Store.new(lines)
39
- store.on(" ").must_equal 0
39
+ expect(store.on(" ")).must_equal 0
40
40
  end
41
41
 
42
42
  it "neglects spaces at the extremes of the line" do
@@ -44,7 +44,7 @@ module Hotspots
44
44
  " abc.txt "
45
45
  ]
46
46
  store = Store.new(lines)
47
- store.on("abc.txt").must_equal 1
47
+ expect(store.on("abc.txt")).must_equal 1
48
48
  end
49
49
 
50
50
  it "neglects linefeeds at the extremes of the line" do
@@ -53,7 +53,7 @@ module Hotspots
53
53
  "\n\n abc.txt \r\n"
54
54
  ]
55
55
  store = Store.new(lines)
56
- store.on("abc.txt").must_equal 2
56
+ expect(store.on("abc.txt")).must_equal 2
57
57
  end
58
58
 
59
59
  it "has a string representation" do
@@ -62,7 +62,7 @@ module Hotspots
62
62
  "efg.txt"
63
63
  ]
64
64
  store = Store.new(lines)
65
- store.to_s.must_equal "abc.txt,1\nefg.txt,1\n"
65
+ expect(store.to_s).must_equal "abc.txt,1\nefg.txt,1\n"
66
66
  end
67
67
 
68
68
  it "has a case-sensitive string representation" do
@@ -70,7 +70,7 @@ module Hotspots
70
70
  "aBc.tXt"
71
71
  ]
72
72
  store = Store.new(lines)
73
- store.to_s.must_equal "aBc.tXt,1\n"
73
+ expect(store.to_s).must_equal "aBc.tXt,1\n"
74
74
  end
75
75
 
76
76
  it "string representation has maximum occuring string at the top" do
@@ -82,7 +82,7 @@ module Hotspots
82
82
  "efg.txt"
83
83
  ]
84
84
  store = Store.new(lines)
85
- store.to_s.must_equal "efg.txt,3\nabc.txt,2\n"
85
+ expect(store.to_s).must_equal "efg.txt,3\nabc.txt,2\n"
86
86
  end
87
87
 
88
88
  it "doesn't display setting below cut-off" do
@@ -94,7 +94,7 @@ module Hotspots
94
94
  "efg.txt"
95
95
  ]
96
96
  store = Store.new(lines, :cutoff => 3)
97
- store.to_s.must_equal "efg.txt,3\n"
97
+ expect(store.to_s).must_equal "efg.txt,3\n"
98
98
  end
99
99
 
100
100
  it "doesn't display lines that don't match criteria" do
@@ -109,7 +109,7 @@ module Hotspots
109
109
  "missing.txt"
110
110
  ]
111
111
  store = Store.new(lines, :file_filter => "abc|efg")
112
- store.to_s.must_equal "abc.txt,3\nefg.txt,2\nabc.log,1\n"
112
+ expect(store.to_s).must_equal "abc.txt,3\nefg.txt,2\nabc.log,1\n"
113
113
  end
114
114
  end
115
- end
115
+ end
@@ -1,14 +1,17 @@
1
- lib = File.expand_path('../../lib/', __FILE__)
1
+ lib = File.expand_path("../../lib/", __FILE__)
2
2
  $:.unshift lib unless $:.include?(lib)
3
3
 
4
+ require "ansi/code"
5
+
4
6
  if ENV["coverage"] == "true"
5
7
  begin
6
- require 'simplecov'
8
+ require "simplecov"
7
9
  SimpleCov.start do
8
10
  add_filter "/test/"
9
11
  end
10
12
  rescue LoadError
11
- puts "\nPlease install simplecov to generate coverage report!\n\n"
13
+ $stderr.puts ::ANSI::Code.red("Please install simplecov to generate a coverage report!")
14
+ exit 1
12
15
  end
13
16
  end
14
17
 
@@ -19,5 +22,5 @@ end
19
22
 
20
23
  require_relative "../lib/hotspots"
21
24
 
22
- require 'minitest/autorun'
23
- require 'minitest/spec'
25
+ gem "minitest"
26
+ require "minitest/autorun"