git-commit-notifier 0.8.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/README.textile +20 -5
- data/Rakefile +40 -20
- data/VERSION +1 -1
- data/bin/git-commit-notifier +8 -1
- data/config/git-notifier-config.yml.sample +41 -15
- data/git-commit-notifier.gemspec +50 -24
- data/lib/commit_hook.rb +104 -74
- data/lib/diff_to_html.rb +120 -52
- data/lib/emailer.rb +43 -22
- data/lib/git.rb +36 -26
- data/lib/logger.rb +48 -0
- data/lib/result_processor.rb +9 -5
- data/{test → spec}/fixtures/existing_file_one_line.txt +0 -0
- data/{test → spec}/fixtures/git-notifier-group-email-by-push.yml +2 -0
- data/{test → spec}/fixtures/git-notifier-ignore-merge.yml +0 -0
- data/{test → spec}/fixtures/git-notifier-with-merge.yml +0 -0
- data/{test → spec}/fixtures/git_log +0 -0
- data/{test → spec}/fixtures/git_show_055850e7d925110322b8db4e17c3b840d76e144c +0 -0
- data/{test → spec}/fixtures/git_show_51b986619d88f7ba98be7d271188785cbbb541a0 +0 -0
- data/{test → spec}/fixtures/git_show_a4629e707d80a5769f7a71ca6ed9471015e14dc9 +0 -0
- data/{test → spec}/fixtures/git_show_dce6ade4cdc2833b53bd600ef10f9bce83c7102d +0 -0
- data/{test → spec}/fixtures/git_show_e28ad77bba0574241e6eb64dfd0c1291b221effe +0 -0
- data/spec/fixtures/git_show_ff037a73fc1094455e7bbf506171a3f3cf873ae6 +18 -0
- data/{test → spec}/fixtures/new_file_one_line.txt +0 -0
- data/spec/lib/commit_hook_spec.rb +88 -0
- data/spec/lib/diff_to_html_spec.rb +168 -0
- data/spec/lib/emailer_spec.rb +102 -0
- data/spec/lib/git_spec.rb +93 -0
- data/spec/lib/logger_spec.rb +63 -0
- data/spec/lib/result_processor_spec.rb +102 -0
- data/{test/test_helper.rb → spec/spec_helper.rb} +14 -12
- data/template/email.html.erb +2 -2
- data/template/styles.css +2 -1
- metadata +110 -31
- data/test/unit/test_commit_hook.rb +0 -43
- data/test/unit/test_diff_to_html.rb +0 -160
- data/test/unit/test_result_processor.rb +0 -95
@@ -1,43 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'test/unit'
|
3
|
-
require 'mocha'
|
4
|
-
|
5
|
-
require File.dirname(__FILE__) + '/../../lib/commit_hook'
|
6
|
-
require File.dirname(__FILE__) + '/../../lib/git'
|
7
|
-
|
8
|
-
class CommitHookTest < Test::Unit::TestCase
|
9
|
-
|
10
|
-
def test_hook_ignore_merge
|
11
|
-
# 4 commits, one email for each of them, without merge
|
12
|
-
run_with_config('test/fixtures/git-notifier-ignore-merge.yml', 4)
|
13
|
-
end
|
14
|
-
|
15
|
-
def test_hook_with_merge
|
16
|
-
# 5 commits, one email for each of them, with merge mail
|
17
|
-
run_with_config('test/fixtures/git-notifier-with-merge.yml', 5)
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_hook_group_email_by_push
|
21
|
-
# 1 commit for the push, all commits in the one message
|
22
|
-
run_with_config('test/fixtures/git-notifier-group-email-by-push.yml', 1)
|
23
|
-
end
|
24
|
-
|
25
|
-
def run_with_config(config, times)
|
26
|
-
expect_repository_access
|
27
|
-
|
28
|
-
emailer = mock('Emailer')
|
29
|
-
Emailer.expects(:new).times(times).returns(emailer)
|
30
|
-
emailer.expects(:send).times(times)
|
31
|
-
CommitHook.run config, REVISIONS.first, REVISIONS.last, 'refs/heads/master'
|
32
|
-
end
|
33
|
-
|
34
|
-
def expect_repository_access
|
35
|
-
path = File.dirname(__FILE__) + '/../fixtures/'
|
36
|
-
Git.expects(:log).with(REVISIONS.first, REVISIONS.last).returns(read_file(path + 'git_log'))
|
37
|
-
Git.expects(:mailing_list_address).returns('recipient@test.com')
|
38
|
-
REVISIONS.each do |rev|
|
39
|
-
Git.expects(:show).with(rev).returns(read_file(path + "git_show_#{rev}"))
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
end
|
@@ -1,160 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'mocha'
|
3
|
-
require 'cgi'
|
4
|
-
require 'hpricot'
|
5
|
-
|
6
|
-
require File.dirname(__FILE__) + '/../test_helper'
|
7
|
-
|
8
|
-
require File.dirname(__FILE__) + '/../../lib/diff_to_html'
|
9
|
-
require File.dirname(__FILE__) + '/../../lib/git'
|
10
|
-
|
11
|
-
class DiffToHtmlTest < Test::Unit::TestCase
|
12
|
-
|
13
|
-
def test_multiple_commits
|
14
|
-
path = File.dirname(__FILE__) + '/../fixtures/'
|
15
|
-
Git.expects(:log).with(REVISIONS.first, REVISIONS.last).returns(read_file(path + 'git_log'))
|
16
|
-
REVISIONS.each do |rev|
|
17
|
-
Git.expects(:show).with(rev).returns(read_file(path + 'git_show_' + rev))
|
18
|
-
end
|
19
|
-
|
20
|
-
diff = DiffToHtml.new
|
21
|
-
diff.diff_between_revisions REVISIONS.first, REVISIONS.last, 'testproject', 'master'
|
22
|
-
assert_equal 5, diff.result.size # one result for each of the commits
|
23
|
-
|
24
|
-
diff.result.each do |html|
|
25
|
-
assert !html.include?('@@') # diff correctly processed
|
26
|
-
end
|
27
|
-
|
28
|
-
# first commit
|
29
|
-
hp = Hpricot diff.result.first[:html_content]
|
30
|
-
assert_equal 2, (hp/"table").size # 8 files updated - one table for each of the files
|
31
|
-
(hp/"table/tr/").each do |td|
|
32
|
-
if td.inner_html == "require 'iconv'"
|
33
|
-
# first added line in changeset a4629e707d80a5769f7a71ca6ed9471015e14dc9
|
34
|
-
assert_equal '', td.parent.search('td')[0].inner_text # left
|
35
|
-
assert_equal '2', td.parent.search('td')[1].inner_text # right
|
36
|
-
assert_equal "require 'iconv'", td.parent.search('td')[2].inner_html # change
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
# second commit
|
41
|
-
hp = Hpricot diff.result[1][:html_content]
|
42
|
-
assert_equal 1, (hp/"table").size # 1 file updated
|
43
|
-
|
44
|
-
# third commit - dce6ade4cdc2833b53bd600ef10f9bce83c7102d
|
45
|
-
hp = Hpricot diff.result[2][:html_content]
|
46
|
-
assert_equal 6, (hp/"table").size # 6 files updated
|
47
|
-
assert_equal 'Added binary file railties/doc/guides/source/images/icons/callouts/11.png', (hp/"h2")[1].inner_text
|
48
|
-
assert_equal 'Deleted binary file railties/doc/guides/source/icons/up.png', (hp/"h2")[2].inner_text
|
49
|
-
assert_equal 'Deleted file railties/doc/guides/source/icons/README', (hp/"h2")[3].inner_text
|
50
|
-
assert_equal 'Added file railties/doc/guides/source/images/icons/README', (hp/"h2")[4].inner_text
|
51
|
-
|
52
|
-
# fourth commit - 51b986619d88f7ba98be7d271188785cbbb541a0
|
53
|
-
hp = Hpricot diff.result[3][:html_content]
|
54
|
-
assert_equal 3, (hp/"table").size # 3 files updated
|
55
|
-
(hp/"table/tr/").each do |td|
|
56
|
-
if td.inner_html =~ /create_btn/
|
57
|
-
cols = td.parent.search('td')
|
58
|
-
['405', '408', ''].include? cols[0].inner_text # line 405 changed
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def test_single_commit
|
64
|
-
path = File.dirname(__FILE__) + '/../fixtures/'
|
65
|
-
Git.expects(:log).never
|
66
|
-
Git.expects(:show).with(REVISIONS.first).returns(read_file(path + 'git_show_' + REVISIONS.first))
|
67
|
-
|
68
|
-
diff = DiffToHtml.new
|
69
|
-
diff.diff_between_revisions REVISIONS.first, REVISIONS.first, 'testproject', 'master'
|
70
|
-
assert_equal 1, diff.result.size # single result for a single commit
|
71
|
-
assert_equal 'Allow use of :path_prefix and :name_prefix outside of namespaced routes. [#1188 state:resolved]', diff.result.first[:commit_info][:message]
|
72
|
-
assert_equal 'Tom Stuart', diff.result.first[:commit_info][:author]
|
73
|
-
assert_equal 'tom@experthuman.com', diff.result.first[:commit_info][:email]
|
74
|
-
|
75
|
-
hp = Hpricot(diff.result.first[:html_content])
|
76
|
-
assert !diff.result.first[:html_content].include?('@@')
|
77
|
-
assert_equal 2, (hp/"table").size # 2 files updated
|
78
|
-
(hp/"table/tr/").each do |td|
|
79
|
-
if td.inner_html == "require 'iconv'"
|
80
|
-
# first added line in changeset a4629e707d80a5769f7a71ca6ed9471015e14dc9
|
81
|
-
assert_equal '', td.parent.search('td')[0].inner_text # left
|
82
|
-
assert_equal '2', td.parent.search('td')[1].inner_text # right
|
83
|
-
assert_equal "require 'iconv'", td.parent.search('td')[2].inner_html # change
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
def test_tokenize
|
89
|
-
s = "keys = I18n.send :normalize_translation_keys, locale, key, scope"
|
90
|
-
diff = DiffToHtml.new
|
91
|
-
tokens = diff.tokenize_string(s)
|
92
|
-
|
93
|
-
assert_equal ['keys', ' ', '=', ' ', 'I18n', '.', 'send',' ',':','normalize','_','translation','_','keys',',',' ','locale',',',' ',
|
94
|
-
'key',',',' ','scope'], tokens
|
95
|
-
end
|
96
|
-
|
97
|
-
def test_gitweb_operation_description
|
98
|
-
diff = DiffToHtml.new
|
99
|
-
diff.current_file_name = "file/to/test.yml"
|
100
|
-
assert_equal "<h2>Changed file file/to/test.yml</h2>\n", diff.operation_description
|
101
|
-
|
102
|
-
config = {
|
103
|
-
"link_files" => "gitweb",
|
104
|
-
"gitweb" => {
|
105
|
-
"path" => "http://developerserver/path_to_gitweb",
|
106
|
-
"project" => "test.git"
|
107
|
-
}
|
108
|
-
}
|
109
|
-
|
110
|
-
diff = DiffToHtml.new(nil, config)
|
111
|
-
diff.current_file_name = "file/to/test.yml"
|
112
|
-
assert_equal "<h2>Changed file <a href='http://developerserver/path_to_gitweb?p=test.git;f=file/to/test.yml;hb=HEAD'>file/to/test.yml</a></h2>\n", diff.operation_description
|
113
|
-
end
|
114
|
-
|
115
|
-
def test_gitorious_operation_description
|
116
|
-
diff = DiffToHtml.new
|
117
|
-
diff.current_file_name = "file/to/test.yml"
|
118
|
-
assert_equal "<h2>Changed file file/to/test.yml</h2>\n", diff.operation_description
|
119
|
-
|
120
|
-
config = {
|
121
|
-
"link_files" => "gitorious",
|
122
|
-
"gitorious" => {
|
123
|
-
"path" => "http://example.com/gitorious",
|
124
|
-
"project" => "tests",
|
125
|
-
"repository" => "test",
|
126
|
-
}
|
127
|
-
}
|
128
|
-
|
129
|
-
diff = DiffToHtml.new(nil, config)
|
130
|
-
diff.current_file_name = "file/to/test.yml"
|
131
|
-
assert_equal "<h2>Changed file <a href='http://example.com/gitorious/tests/test/blobs/HEAD/file/to/test.yml'>file/to/test.yml</a></h2>\n", diff.operation_description
|
132
|
-
end
|
133
|
-
|
134
|
-
def test_should_correctly_set_line_numbers_on_single_line_add_to_new_file
|
135
|
-
diff = DiffToHtml.new
|
136
|
-
diff.expects(:add_line_to_result).with() { |line, escape| line[:added] == 1 }
|
137
|
-
content = IO.read('test/fixtures/new_file_one_line.txt')
|
138
|
-
result = diff.diff_for_revision(content)
|
139
|
-
end
|
140
|
-
|
141
|
-
def test_should_correctly_set_line_numbers_on_single_line_add_to_existing_file
|
142
|
-
diff = DiffToHtml.new
|
143
|
-
diff.expects(:add_line_to_result).at_least_once
|
144
|
-
diff.expects(:add_line_to_result).at_least_once.with() { |line, escape| line[:added] == 5 && line[:removed] == nil }
|
145
|
-
content = IO.read('test/fixtures/existing_file_one_line.txt')
|
146
|
-
result = diff.diff_for_revision(content)
|
147
|
-
end
|
148
|
-
|
149
|
-
def test_message_map_should_correctly_rework_message
|
150
|
-
diff = DiffToHtml.new(nil, 'message_map' => {
|
151
|
-
'\brefs\s*\#(\d+)' => 'http://redmine.example.com/issues/show/\1'
|
152
|
-
}, 'message_integration' => {
|
153
|
-
'bugzilla' => 'http://bugzilla.example.com'
|
154
|
-
})
|
155
|
-
assert_equal(
|
156
|
-
'<a href="http://bugzilla.example.com/show_bug.cgi?id=15">BUG 15</a>. Draft design <a href="http://redmine.example.com/issues/show/5654">refs #5654</a>',
|
157
|
-
diff.message_map('BUG 15. Draft design refs #5654')
|
158
|
-
)
|
159
|
-
end
|
160
|
-
end
|
@@ -1,95 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'jcode'
|
3
|
-
require File.dirname(__FILE__) + '/../../lib/result_processor'
|
4
|
-
require File.dirname(__FILE__) + '/../../lib/diff_to_html'
|
5
|
-
|
6
|
-
class ResultProcessorTest < Test::Unit::TestCase
|
7
|
-
# button_to_remote 'create_btn'
|
8
|
-
# submit_to_remote 'create_btn'
|
9
|
-
|
10
|
-
def setup
|
11
|
-
create_test_input
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_processor
|
15
|
-
proc = ResultProcessor.new(@diff)
|
16
|
-
removal, addition = proc.results
|
17
|
-
assert_equal 1, removal.size
|
18
|
-
|
19
|
-
assert removal[0].include?(' <span class="rr">b</span>')
|
20
|
-
assert removal[0].include?('<span class="rr">ton</span>')
|
21
|
-
|
22
|
-
assert_equal 1, removal[0].split('<span>').size # one occurrence (beginning of string)
|
23
|
-
assert_equal 1, addition.size
|
24
|
-
assert addition[0].include?(' <span class="aa">s</span>')
|
25
|
-
assert addition[0].include?('<span class="aa">bmi</span>')
|
26
|
-
assert_equal 1, addition[0].split('<span>').size
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_processor_with_almost_no_common_part
|
30
|
-
@diff = [
|
31
|
-
{ :action => :match, :token => ' '},
|
32
|
-
{ :action => :match, :token => ' '},
|
33
|
-
{ :action => :discard_a, :token => 'button'},
|
34
|
-
{:action => :discard_b, :token => 'submit'},
|
35
|
-
{ :action => :match, :token => 'x'}]
|
36
|
-
|
37
|
-
proc = ResultProcessor.new(@diff)
|
38
|
-
removal, addition = proc.results
|
39
|
-
|
40
|
-
assert_equal 1, removal.size
|
41
|
-
assert_equal ' buttonx', removal[0] # no highlight
|
42
|
-
assert_equal 1, addition.size
|
43
|
-
assert_equal ' submitx', addition[0] # no highlight
|
44
|
-
end
|
45
|
-
|
46
|
-
def test_close_span_tag_when_having_difference_at_the_end
|
47
|
-
diff = []
|
48
|
-
s1 = " submit_to_remote 'create_btn', 'Create', :url => { :action => 'cre"
|
49
|
-
s2 = " submit_to_remote 'create_btn', 'Create', :url => { :action => 'sub"
|
50
|
-
|
51
|
-
s1[0..s1.size-6].each_char do |c|
|
52
|
-
diff << { :action => :match, :token => c}
|
53
|
-
end
|
54
|
-
diff << { :action => :discard_a, :token => 'c'}
|
55
|
-
diff << { :action => :discard_a, :token => 'r'}
|
56
|
-
diff << { :action => :discard_a, :token => 'e'}
|
57
|
-
diff << { :action => :discard_b, :token => 's'}
|
58
|
-
diff << { :action => :discard_b, :token => 'u'}
|
59
|
-
diff << { :action => :discard_b, :token => 'b'}
|
60
|
-
|
61
|
-
proc = ResultProcessor.new(diff)
|
62
|
-
removal, addition = proc.results
|
63
|
-
assert_equal 1, removal.size
|
64
|
-
assert removal[0].include?('action =><span class="rr">cre</span>')
|
65
|
-
|
66
|
-
assert_equal 1, addition.size
|
67
|
-
assert addition[0].include?('action =><span class="aa">sub</span>')
|
68
|
-
end
|
69
|
-
|
70
|
-
def create_test_input
|
71
|
-
@diff = []
|
72
|
-
s1 = " button_to_remote 'create_btn', 'Create', :url => { :action => 'create' }"
|
73
|
-
s2 = " submit_to_remote 'create_btn', 'Create', :url => { :action => 'create' }"
|
74
|
-
|
75
|
-
@diff = [
|
76
|
-
[:match, ' '],
|
77
|
-
[:match, ' '],
|
78
|
-
[:discard_a,'b'],
|
79
|
-
[:discard_b,'s'],
|
80
|
-
[:match, 'u'],
|
81
|
-
[:discard_b,'b'],
|
82
|
-
[:discard_b,'m'],
|
83
|
-
[:discard_b,'i'],
|
84
|
-
[:match, 't'],
|
85
|
-
[:discard_a,'t'],
|
86
|
-
[:discard_a,'o'],
|
87
|
-
[:discard_a,'n']]
|
88
|
-
@diff = @diff.collect { |d| { :action => d.first, :token => d.last}}
|
89
|
-
|
90
|
-
s1[@diff.size..-1].each_char do |c|
|
91
|
-
@diff << { :action => :match, :token => c}
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
end
|