Skip to content

Commit 3ab00fc

Browse files
sdsShane da Silva
authored and
Shane da Silva
committed
Add specs for PreCommit and CommitMsg contexts
Change-Id: I1037b8747ddb2b79235cc171ef840430e58310be Reviewed-on: http://gerrit.causes.com/35570 Reviewed-by: Shane da Silva <shane@causes.com> Tested-by: Shane da Silva <shane@causes.com>
1 parent cfdf233 commit 3ab00fc

21 files changed

+186
-48
lines changed

TODO

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Display when no applicable hooks ran (e.g. instead of "All pre-commit checks pas
2323
Add pre-commit check ensuring Gemfile.lock matches Gemfile (unless in .gitignore)
2424
Add check for https://github.com/mdevils/node-jscs
2525
Add post-checkout check for asking to update git submodules
26+
FIX let(:subject)
2627

2728

2829
Allow features of hooks to be customized (stealth, required, etc.)

lib/overcommit/hook/base.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module Overcommit::Hook
55
class Base
66
extend Forwardable
77

8-
def_delegators :@context, :staged_files
8+
def_delegators :@context, :modified_files
99

1010
def initialize(config, context)
1111
@config = config.hook_config(self)
@@ -62,7 +62,7 @@ def command(cmd)
6262
# Gets a list of staged files that apply to this hook based on its
6363
# configured `include` and `exclude` lists.
6464
def applicable_files
65-
@applicable_files ||= staged_files.select { |file| applicable_file?(file) }
65+
@applicable_files ||= modified_files.select { |file| applicable_file?(file) }
6666
end
6767

6868
private

lib/overcommit/hook/commit_msg/base.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ module Overcommit::Hook::CommitMsg
55
class Base < Overcommit::Hook::Base
66
extend Forwardable
77

8-
def_delegators :@context, :commit_message
8+
def_delegators :@context, :commit_message, :commit_message_lines
99
end
1010
end

lib/overcommit/hook/commit_msg/hard_tabs.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module Overcommit::Hook::CommitMsg
33
class HardTabs < Base
44
def run
55
# Catches hard tabs entered by the user (not auto-generated)
6-
if commit_message.join.index(/\t/)
6+
if commit_message.index(/\t/)
77
return :warn, "Don't use hard tabs in commit messages"
88
end
99

lib/overcommit/hook/commit_msg/russian_novel.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ class RussianNovel < Base
44
RUSSIAN_NOVEL_LENGTH = 30
55

66
def run
7-
if commit_message.length >= RUSSIAN_NOVEL_LENGTH
7+
if commit_message_lines.length >= RUSSIAN_NOVEL_LENGTH
88
return :warn, 'You seem to have authored a Russian novel; congratulations!'
99
end
1010

lib/overcommit/hook/commit_msg/single_line_subject.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module Overcommit::Hook::CommitMsg
22
# Ensures commit message subject lines are followed by a blank line.
33
class SingleLineSubject < Base
44
def run
5-
unless commit_message[1].to_s.strip.empty?
5+
unless commit_message_lines[1].to_s.strip.empty?
66
return :warn, 'Subject should be one line and followed by a blank line'
77
end
88

lib/overcommit/hook/commit_msg/text_width.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ module Overcommit::Hook::CommitMsg
33
# under the preferred limits.
44
class TextWidth < Base
55
def run
6-
if commit_message.first.size > 60
6+
if commit_message_lines.first.size > 60
77
return :warn, 'Please keep the subject < ~60 characters'
88
end
99

10-
commit_message.each do |line|
10+
commit_message_lines.each do |line|
1111
chomped = line.chomp
1212
if chomped.size > 72
1313
return :warn, "> 72 characters, please hard wrap: '#{chomped}'"

lib/overcommit/hook/commit_msg/trailing_period.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module Overcommit::Hook::CommitMsg
22
# Ensures commit message subject lines do not have a trailing period
33
class TrailingPeriod < Base
44
def run
5-
if commit_message[0].rstrip.end_with?('.')
5+
if commit_message_lines.first.rstrip.end_with?('.')
66
return :warn, 'Please omit trailing period from commit message subject'
77
end
88

lib/overcommit/hook_context/base.rb

+14-7
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,20 @@ def hook_class_name
1919
@hook_class_name ||= self.class.name.split('::').last
2020
end
2121

22-
# Get a list of added, copied, or modified files that have been staged.
23-
# Renames and deletions are ignored, since there should be nothing to check.
24-
def staged_files
25-
@staged_files ||=
26-
`git diff --cached --name-only --diff-filter=ACM --ignore-submodules=all`.
27-
split("\n").
28-
map { |relative_file| File.expand_path(relative_file) }
22+
# Returns a list of files that have been modified.
23+
#
24+
# By default, this returns an empty list. Subclasses should implement if
25+
# there is a concept of files changing for the type of hook being run.
26+
def modified_files
27+
[]
28+
end
29+
30+
# Returns a set of lines that have been modified for a file.
31+
#
32+
# By default, this returns an empty set. Subclasses should implement if
33+
# there is a concept of files changing for the type of hook being run.
34+
def modified_lines(file)
35+
Set.new
2936
end
3037
end
3138
end

lib/overcommit/hook_context/commit_msg.rb

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
module Overcommit::HookContext
2+
# Contains helpers related to contextual information used by commit-msg hooks.
23
class CommitMsg < Base
34
# User commit message stripped of comments and diff (from verbose output).
45
def commit_message
5-
raw_commit_message.
6+
commit_message_lines.join
7+
end
8+
9+
def commit_message_lines
10+
raw_commit_message_lines.
611
reject { |line| line =~ /^#/ }.
712
take_while { |line| !line.start_with?('diff --git') }
813
end
@@ -13,7 +18,7 @@ def commit_message_file
1318

1419
private
1520

16-
def raw_commit_message
21+
def raw_commit_message_lines
1722
::IO.readlines(commit_message_file)
1823
end
1924
end

lib/overcommit/hook_context/pre_commit.rb

+12-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,20 @@ module Overcommit::HookContext
44
# This includes staged files, which lines of those files have been modified,
55
# etc.
66
class PreCommit < Base
7+
# Get a list of added, copied, or modified files that have been staged.
8+
# Renames and deletions are ignored, since there should be nothing to check.
9+
def modified_files
10+
@modified_files ||=
11+
`git diff --cached --name-only --diff-filter=ACM --ignore-submodules=all`.
12+
split("\n").
13+
map { |relative_file| File.expand_path(relative_file) }
14+
end
15+
716
# Returns the set of line numbers corresponding to the lines that were
817
# changed in a specified file.
9-
def modified_lines(staged_file)
18+
def modified_lines(file)
1019
@modified_lines ||= {}
11-
@modified_lines[staged_file] ||= extract_modified_lines(staged_file)
20+
@modified_lines[file] ||= extract_modified_lines(file)
1221
end
1322

1423
private
@@ -27,7 +36,7 @@ def extract_modified_lines(staged_file)
2736
scan(DIFF_HUNK_REGEX) do |start_line, lines_added|
2837

2938
lines_added = (lines_added || 1).to_i # When blank, one line was added
30-
cur_line = start_line.to_i
39+
cur_line = start_line.to_i
3140

3241
lines_added.times do
3342
lines.add cur_line

spec/overcommit/hook/commit_msg/hard_tabs_spec.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010
end
1111

1212
context 'when message contains hard tabs' do
13-
let(:commit_msg) { ["This is a hard-tab\tcommit message"] }
13+
let(:commit_msg) { "This is a hard-tab\tcommit message" }
1414

1515
it { should warn }
1616
end
1717

1818
context 'when message does not contain hard tabs' do
19-
let(:commit_msg) { ['No hard tabs to be found'] }
19+
let(:commit_msg) { 'No hard tabs to be found' }
2020

2121
it { should pass }
2222
end

spec/overcommit/hook/commit_msg/russian_novel_spec.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
let(:subject) { described_class.new(config, context) }
77

88
before do
9-
subject.stub(:commit_message).and_return(commit_msg)
9+
subject.stub(:commit_message_lines).and_return(commit_msg)
1010
end
1111

1212
context 'when message contains fewer than 30 lines' do

spec/overcommit/hook/commit_msg/single_line_subject_spec.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
let(:subject) { described_class.new(config, context) }
77

88
before do
9-
subject.stub(:commit_message).and_return(commit_msg.split("\n"))
9+
subject.stub(:commit_message_lines).and_return(commit_msg.split("\n"))
1010
end
1111

1212
context 'when subject is separated from body by a blank line' do

spec/overcommit/hook/commit_msg/text_width_spec.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
let(:subject) { described_class.new(config, context) }
77

88
before do
9-
subject.stub(:commit_message).and_return(commit_msg.split("\n"))
9+
subject.stub(:commit_message_lines).and_return(commit_msg.split("\n"))
1010
end
1111

1212
context 'when subject is longer than 60 characters' do

spec/overcommit/hook/commit_msg/trailing_period_spec.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
let(:subject) { described_class.new(config, context) }
77

88
before do
9-
subject.stub(:commit_message).and_return(commit_msg.split("\n"))
9+
subject.stub(:commit_message_lines).and_return(commit_msg.split("\n"))
1010
end
1111

1212
context 'when subject contains a trailing period' do

spec/overcommit/hook/pre_commit/author_name_spec.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
let(:config) { Overcommit::ConfigurationLoader.default_configuration }
55
let(:context) { double('context') }
66
let(:subject) { described_class.new(config, context) }
7-
let(:result) { mock('result') }
7+
let(:result) { double('result') }
88

99
before do
1010
result = mock('result)')
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
require 'spec_helper'
2+
3+
describe Overcommit::HookContext::Base do
4+
let(:config) { double('context') }
5+
let(:args) { [] }
6+
let(:input) { '' }
7+
let(:context) { described_class.new(config, args, input) }
8+
9+
describe '#hook_class_name' do
10+
subject { context.hook_class_name }
11+
12+
it 'returns the short class name of the context' do
13+
subject.should == 'Base'
14+
end
15+
end
16+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
require 'spec_helper'
2+
require 'overcommit/hook_context/commit_msg'
3+
4+
describe Overcommit::HookContext::CommitMsg do
5+
let(:config) { double('context') }
6+
let(:args) { [commit_message_file] }
7+
let(:input) { '' }
8+
let(:context) { described_class.new(config, args, input) }
9+
let(:commit_msg) do
10+
[
11+
'# Please enter the commit message for your changes.',
12+
'Some commit message',
13+
'# On branch master',
14+
'diff --git a/file b/file',
15+
'index 4ae1030..342a117 100644',
16+
'--- a/file',
17+
'+++ b/file',
18+
]
19+
end
20+
21+
let(:commit_message_file) do
22+
Tempfile.new('commit-message').tap do |file|
23+
file.write(commit_msg.join("\n"))
24+
file.fsync
25+
end.path
26+
end
27+
28+
describe '#commit_message' do
29+
subject { context.commit_message }
30+
31+
it 'strips comments and trailing diff' do
32+
subject.should == "Some commit message\n"
33+
end
34+
end
35+
36+
describe '#commit_message_lines' do
37+
subject { context.commit_message_lines }
38+
39+
it 'strips comments and trailing diff' do
40+
subject.should == ["Some commit message\n"]
41+
end
42+
end
43+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
require 'spec_helper'
2+
require 'overcommit/hook_context/pre_commit'
3+
4+
describe Overcommit::HookContext::PreCommit do
5+
let(:config) { double('context') }
6+
let(:args) { [] }
7+
let(:input) { '' }
8+
let(:context) { described_class.new(config, args, input) }
9+
10+
describe '#modified_files' do
11+
subject { context.modified_files }
12+
13+
it 'does not include submodules' do
14+
submodule = repo do
15+
`touch foo`
16+
`git add foo`
17+
`git commit -m "Initial commit"`
18+
end
19+
20+
repo do
21+
`git submodule add #{submodule} test-sub`
22+
expect(subject).to_not include File.expand_path('test-sub')
23+
end
24+
end
25+
26+
context 'when no files were staged' do
27+
around do |example|
28+
repo do
29+
example.run
30+
end
31+
end
32+
33+
it { should be_empty }
34+
end
35+
36+
context 'when files were added' do
37+
around do |example|
38+
repo do
39+
FileUtils.touch('some-file')
40+
`git add some-file`
41+
example.run
42+
end
43+
end
44+
45+
it { should == [File.expand_path('some-file')] }
46+
end
47+
48+
context 'when files were modified' do
49+
around do |example|
50+
repo do
51+
FileUtils.touch('some-file')
52+
`git add some-file`
53+
`git commit -m 'Initial commit'`
54+
`echo Hello > some-file`
55+
`git add some-file`
56+
example.run
57+
end
58+
end
59+
60+
it { should == [File.expand_path('some-file')] }
61+
end
62+
63+
context 'when files were deleted' do
64+
around do |example|
65+
repo do
66+
FileUtils.touch('some-file')
67+
`git add some-file`
68+
`git commit -m 'Initial commit'`
69+
`git rm some-file`
70+
example.run
71+
end
72+
end
73+
74+
it { should be_empty }
75+
end
76+
end
77+
end

spec/utils_spec.rb

-20
This file was deleted.

0 commit comments

Comments
 (0)