git-topic 0.1.6.4 → 0.2.1
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.
- data/.vimspell.utf8.add +9 -0
- data/.vimspell.utf8.add.spl +0 -0
- data/README.rdoc +57 -27
- data/Rakefile +10 -0
- data/VERSION.yml +3 -3
- data/bin/git-topic-completion +58 -0
- data/lib/core_ext.rb +74 -12
- data/lib/git_topic.rb +145 -12
- data/lib/git_topic/cli.rb +105 -13
- data/lib/git_topic/comment.rb +273 -0
- data/lib/git_topic/git.rb +66 -3
- data/lib/git_topic/naming.rb +26 -5
- data/share/completion.bash +28 -0
- data/spec/bash_completion.rb +2 -0
- data/spec/comment_spec.rb +396 -0
- data/spec/git_topic_accept_spec.rb +78 -0
- data/spec/git_topic_comment_spec.rb +393 -0
- data/spec/git_topic_comments_spec.rb +47 -0
- data/spec/git_topic_done_spec.rb +94 -0
- data/spec/git_topic_install_aliases_spec.rb +32 -0
- data/spec/git_topic_reject_spec.rb +112 -0
- data/spec/git_topic_review_spec.rb +115 -0
- data/spec/git_topic_status_spec.rb +63 -0
- data/spec/git_topic_work_on_spec.rb +121 -0
- data/spec/spec_helper.rb +136 -0
- metadata +34 -11
- data/git-topic +0 -13
- data/git-topic.gemspec +0 -190
- data/spec/git_topic_spec.rb +0 -502
data/lib/git_topic/git.rb
CHANGED
@@ -9,6 +9,34 @@ module GitTopic::Git
|
|
9
9
|
|
10
10
|
protected
|
11
11
|
|
12
|
+
def git_dir
|
13
|
+
@@git_dir ||= (
|
14
|
+
git_dir = capture_git( "rev-parse --git-dir" ).chomp;
|
15
|
+
raise "Unexpected gitdir: [#{git_dir}]" unless git_dir.index '.git'
|
16
|
+
git_dir
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
def git_editor
|
21
|
+
@@git_editor ||= capture_git( "var GIT_EDITOR" ).chomp
|
22
|
+
end
|
23
|
+
|
24
|
+
def git_author_name_short
|
25
|
+
@@git_author_name_short ||= (
|
26
|
+
full_name = capture_git( "config user.name" )
|
27
|
+
raise "
|
28
|
+
whatever
|
29
|
+
" unless $?.success?
|
30
|
+
|
31
|
+
parts = full_name.split( " " )
|
32
|
+
fname = parts.shift
|
33
|
+
fname = "#{fname[0..0].upcase}#{fname[1..-1]}"
|
34
|
+
suffix = parts.map{ |p| p[0..0].upcase }.join( "" )
|
35
|
+
|
36
|
+
"#{fname} #{suffix}".strip
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
12
40
|
def working_tree_clean?
|
13
41
|
git [ "diff --quiet", "diff --quiet --cached" ]
|
14
42
|
$?.success?
|
@@ -18,6 +46,15 @@ module GitTopic::Git
|
|
18
46
|
not working_tree_clean?
|
19
47
|
end
|
20
48
|
|
49
|
+
def existing_comments?( branch=current_branch )
|
50
|
+
ref = notes_ref( branch )
|
51
|
+
not capture_git( "notes --ref #{ref} list" ).chomp.empty?
|
52
|
+
end
|
53
|
+
|
54
|
+
def existing_comments
|
55
|
+
capture_git( "notes --ref #{notes_ref} show" ).chomp
|
56
|
+
end
|
57
|
+
|
21
58
|
|
22
59
|
def display_git_output?
|
23
60
|
@@display_git_output ||= false
|
@@ -36,6 +73,10 @@ module GitTopic::Git
|
|
36
73
|
end
|
37
74
|
end
|
38
75
|
|
76
|
+
def invoke_git_editor( file )
|
77
|
+
system "#{git_editor} #{file}"
|
78
|
+
end
|
79
|
+
|
39
80
|
def cmd_redirect_suffix( opts )
|
40
81
|
if !opts[:show] && !display_git_output?
|
41
82
|
"> /dev/null 2> /dev/null"
|
@@ -43,21 +84,43 @@ module GitTopic::Git
|
|
43
84
|
end
|
44
85
|
|
45
86
|
def git( cmds=[], opts={} )
|
87
|
+
opts.assert_valid_keys :must_succeed
|
88
|
+
|
46
89
|
cmds = [cmds] if cmds.is_a? String
|
47
90
|
redir = cmd_redirect_suffix( opts )
|
48
91
|
cmd = cmds.map{|c| "git #{c} #{redir}"}.join( " && " )
|
49
92
|
|
50
93
|
puts cmd if GitTopic::global_opts[:verbose]
|
51
|
-
system cmd
|
94
|
+
result = system( cmd )
|
95
|
+
|
96
|
+
if opts[:must_succeed] && !$?.success?
|
97
|
+
raise "
|
98
|
+
Required git command failed:\n #{cmd}.\n re-run with --verbose to
|
99
|
+
see git output.
|
100
|
+
".cleanup
|
101
|
+
end
|
102
|
+
|
103
|
+
result
|
52
104
|
end
|
53
105
|
|
54
|
-
def capture_git( cmds=[] )
|
106
|
+
def capture_git( cmds=[], opts={} )
|
107
|
+
opts.assert_valid_keys :must_succeed
|
108
|
+
|
55
109
|
cmds = [cmds] if cmds.is_a? String
|
56
110
|
redir = "2> /dev/null" unless display_git_output?
|
57
111
|
cmd = "#{cmds.map{|c| "git #{c} #{redir}"}.join( " && " )}"
|
58
112
|
|
59
113
|
puts cmd if GitTopic::global_opts[:verbose]
|
60
|
-
`#{cmd}`
|
114
|
+
result = `#{cmd}`
|
115
|
+
|
116
|
+
if opts[:must_succeed] && !$?.success?
|
117
|
+
raise "
|
118
|
+
Required git command failed:\n #{cmd}.\n re-run with --verbose to
|
119
|
+
see git output.
|
120
|
+
".cleanup
|
121
|
+
end
|
122
|
+
|
123
|
+
result
|
61
124
|
end
|
62
125
|
|
63
126
|
end
|
data/lib/git_topic/naming.rb
CHANGED
@@ -32,7 +32,7 @@ module GitTopic::Naming
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def strip_namespace( ref )
|
35
|
-
if ref =~ %r{(?:wip|rejected|review)
|
35
|
+
if ref =~ %r{(?:wip|rejected|review)/(?:(?:\S*)/)?(.*)}
|
36
36
|
$1
|
37
37
|
else
|
38
38
|
ref
|
@@ -40,13 +40,20 @@ module GitTopic::Naming
|
|
40
40
|
end
|
41
41
|
|
42
42
|
|
43
|
+
def notes_ref( branch=current_branch )
|
44
|
+
user, topic = user_topic_name( branch )
|
45
|
+
"refs/notes/reviews/#{user}/#{topic}"
|
46
|
+
end
|
47
|
+
|
48
|
+
|
43
49
|
def user_topic_name( branch )
|
44
50
|
if branch =~ %r{^origin}
|
45
51
|
branch =~ %r{^\S*?/\S*?/(\S*?)/(\S*)}
|
46
52
|
[$1, $2]
|
47
|
-
|
48
|
-
branch =~ %r{^\S*?/(\S*?)/(\S*)}
|
53
|
+
elsif branch =~ %r{^(?:\S*/)?(\S*?)/(\S*)}
|
49
54
|
[$1, $2]
|
55
|
+
else
|
56
|
+
raise "Cannot compute user_topic for [#{branch}]"
|
50
57
|
end
|
51
58
|
end
|
52
59
|
|
@@ -54,6 +61,8 @@ module GitTopic::Naming
|
|
54
61
|
p = {}
|
55
62
|
parts = ref.split( '/' )
|
56
63
|
case parts.size
|
64
|
+
when 3
|
65
|
+
_, p[:user], p[:topic] = parts
|
57
66
|
when 2
|
58
67
|
p[:user], p[:topic] = parts
|
59
68
|
when 1
|
@@ -69,6 +78,11 @@ module GitTopic::Naming
|
|
69
78
|
@@user ||= (ENV['USER'] || `whoami`)
|
70
79
|
end
|
71
80
|
|
81
|
+
def current_namespace
|
82
|
+
current_branch =~ %r{(wip|review|rejected)/(\S*)}
|
83
|
+
$1
|
84
|
+
end
|
85
|
+
|
72
86
|
def current_topic
|
73
87
|
current_branch =~ %r{wip/\S*?/(\S*)}
|
74
88
|
$1
|
@@ -120,9 +134,16 @@ module GitTopic::Naming
|
|
120
134
|
end
|
121
135
|
|
122
136
|
namespace_ut.symbolize_keys!
|
123
|
-
namespace_ut[:review]
|
137
|
+
namespace_ut[:review] ||= {}
|
124
138
|
namespace_ut[:rejected] ||= {}
|
125
139
|
|
140
|
+
namespace_ut[:rejected].each do |user, topics|
|
141
|
+
topics.map! do |topic|
|
142
|
+
suffix = " (reviewer comments) "
|
143
|
+
"#{topic}#{suffix if existing_comments?( "#{user}/#{topic}" )}"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
126
147
|
namespace_ut[:review].reject!{|k,v| k == user}
|
127
148
|
namespace_ut
|
128
149
|
)
|
@@ -138,7 +159,7 @@ module GitTopic::Naming
|
|
138
159
|
|
139
160
|
commits_by_age.find do |ref|
|
140
161
|
# no ‘,’, i.e. only one ref matches the commit
|
141
|
-
ref.index( ',' ).nil?
|
162
|
+
!ref.strip.empty? && ref.index( ',' ).nil?
|
142
163
|
end.strip[ 1..-2 ] # chomp the leading and trailing parenthesis
|
143
164
|
end
|
144
165
|
|
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
|
4
|
+
_git_work_on() {
|
5
|
+
__gitcomp "$(git-topic-completion work-on 2> /dev/null)"
|
6
|
+
return
|
7
|
+
}
|
8
|
+
|
9
|
+
_git_review() {
|
10
|
+
__gitcomp "$(git-topic-completion review 2> /dev/null)"
|
11
|
+
return
|
12
|
+
}
|
13
|
+
|
14
|
+
|
15
|
+
_git_done() {
|
16
|
+
__gitcomp "$(git-topic-completion done 2> /dev/null)"
|
17
|
+
return
|
18
|
+
}
|
19
|
+
|
20
|
+
_git_accept() {
|
21
|
+
__gitcomp "$(git-topic-completion accept 2> /dev/null)"
|
22
|
+
return
|
23
|
+
}
|
24
|
+
|
25
|
+
_git_reject() {
|
26
|
+
__gitcomp "$(git-topic-completion reject 2> /dev/null)"
|
27
|
+
return
|
28
|
+
}
|
@@ -0,0 +1,396 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
DiffWithNonCommentAddition = %Q{
|
4
|
+
diff --git a/lib/git_topic.rb b/lib/git_topic.rb
|
5
|
+
index edb53f1..adceb44 100644
|
6
|
+
--- a/lib/git_topic.rb
|
7
|
+
+++ b/lib/git_topic.rb
|
8
|
+
@@ -9,0 +10 @@ require 'git_topic/naming'
|
9
|
+
+require 'git_topic/comment'
|
10
|
+
}.strip
|
11
|
+
|
12
|
+
DiffWithDeletion = %Q{
|
13
|
+
diff --git a/Gemfile b/Gemfile
|
14
|
+
index ece2952..9d2ccec 100644
|
15
|
+
--- a/Gemfile
|
16
|
+
+++ b/Gemfile
|
17
|
+
@@ -7 +6,0 @@ group :runtime do
|
18
|
+
- gem 'trollop'
|
19
|
+
}.strip
|
20
|
+
|
21
|
+
DiffWithOnlyComments = %Q{
|
22
|
+
diff --git a/Gemfile b/Gemfile
|
23
|
+
index ece2952..8485775 100644
|
24
|
+
--- a/Gemfile
|
25
|
+
+++ b/Gemfile
|
26
|
+
@@ -5,0 +6,2 @@ group :runtime do
|
27
|
+
+ # what was the point of this?
|
28
|
+
+ # surely it would be better with crazy doom stuff and fingles, no?
|
29
|
+
diff --git a/lib/git_topic.rb b/lib/git_topic.rb
|
30
|
+
index adceb44..920e512 100644
|
31
|
+
--- a/lib/git_topic.rb
|
32
|
+
+++ b/lib/git_topic.rb
|
33
|
+
@@ -17,0 +18 @@ module GitTopic
|
34
|
+
+ # This is kind of ugly. Why can't we pull this into cli?
|
35
|
+
@@ -55,0 +57 @@ module GitTopic
|
36
|
+
+ # Oh the night patty murphy died... yadda yadda.
|
37
|
+
@@ -107,0 +110,3 @@ module GitTopic
|
38
|
+
+ # That's how they showed their respect for patty murphy! that's how they
|
39
|
+
+ # showed their honour and their pride! They said it was a cryin' shame
|
40
|
+
+ # and they winked at one another.
|
41
|
+
@@ -111,0 +117 @@ module GitTopic
|
42
|
+
+ # and so on and so forth. The point is, there was a lot of wailing.
|
43
|
+
@@ -118,0 +125 @@ module GitTopic
|
44
|
+
+ # They put the bottle with the corpse to keep that whiskey cold!
|
45
|
+
diff --git a/Rakefile b/Rakefile
|
46
|
+
index 309d6df..73428b2 100644
|
47
|
+
--- a/Rakefile
|
48
|
+
+++ b/Rakefile
|
49
|
+
@@ -64,0 +65,4 @@ rescue LoadError
|
50
|
+
+ # Awesome I guess. But why not something like:
|
51
|
+
+ # Crazy good.
|
52
|
+
+ # Or something vaguely similar.
|
53
|
+
+ # It would seem better that way.
|
54
|
+
}.strip
|
55
|
+
|
56
|
+
|
57
|
+
EditorBufferResultFromClean = %Q{
|
58
|
+
./Gemfile
|
59
|
+
|
60
|
+
Line 6
|
61
|
+
|
62
|
+
David: what was the point of this? surely it would be better with
|
63
|
+
crazy doom stuff and fingles, no?
|
64
|
+
|
65
|
+
|
66
|
+
./lib/git_topic.rb
|
67
|
+
|
68
|
+
Line 18
|
69
|
+
|
70
|
+
David: This is kind of ugly. Why can't we pull this into cli?
|
71
|
+
|
72
|
+
Line 56
|
73
|
+
|
74
|
+
David: Oh the night patty murphy died... yadda yadda.
|
75
|
+
|
76
|
+
Line 108
|
77
|
+
|
78
|
+
David: That's how they showed their respect for patty murphy!
|
79
|
+
that's how they showed their honour and their pride! They
|
80
|
+
said it was a cryin' shame and they winked at one another.
|
81
|
+
|
82
|
+
Line 112
|
83
|
+
|
84
|
+
David: and so on and so forth. The point is, there was a lot of
|
85
|
+
wailing.
|
86
|
+
|
87
|
+
Line 119
|
88
|
+
|
89
|
+
David: They put the bottle with the corpse to keep that whiskey
|
90
|
+
cold!
|
91
|
+
|
92
|
+
|
93
|
+
./Rakefile
|
94
|
+
|
95
|
+
Line 65
|
96
|
+
|
97
|
+
David: Awesome I guess. But why not something like:
|
98
|
+
Crazy good.
|
99
|
+
Or something vaguely similar. It would seem better that way.
|
100
|
+
}.strip
|
101
|
+
|
102
|
+
|
103
|
+
ExistingComment = %Q{
|
104
|
+
Spec 123: I have some general comments, mostly relating to the quality
|
105
|
+
of our zombie-control policies. Basically, they're not
|
106
|
+
working.
|
107
|
+
|
108
|
+
./zombies
|
109
|
+
|
110
|
+
Line 2
|
111
|
+
Spec 123: I suggest we do the following instead:
|
112
|
+
zombies.each{ |z| reason_with( z )}
|
113
|
+
zomies.select do |z|
|
114
|
+
z.unconvinced?
|
115
|
+
end.each do |z|
|
116
|
+
destroy z
|
117
|
+
end
|
118
|
+
This should take care of our issues with zombies.
|
119
|
+
|
120
|
+
|
121
|
+
./lib/foo/zombie_repellant
|
122
|
+
|
123
|
+
Line 6
|
124
|
+
Spec 123: Does this stuff really work? I'm not convinced.
|
125
|
+
|
126
|
+
Line 40
|
127
|
+
Spec 123: Please explain this.
|
128
|
+
}.strip
|
129
|
+
|
130
|
+
LegalReply = %Q{
|
131
|
+
# Spec 123: I have some general comments, mostly relating to the quality
|
132
|
+
# of our zombie-control policies. Basically, they're not
|
133
|
+
# working.
|
134
|
+
|
135
|
+
Sorry about that. I have fixed the branch to have better zombie-control policies.
|
136
|
+
|
137
|
+
#
|
138
|
+
# ./zombies
|
139
|
+
#
|
140
|
+
# Line 2
|
141
|
+
# Spec 123: I suggest we do the following instead:
|
142
|
+
# zombies.each{ |z| reason_with( z )}
|
143
|
+
# zomies.select do |z|
|
144
|
+
# z.unconvinced?
|
145
|
+
# end.each do |z|
|
146
|
+
# destroy z
|
147
|
+
# end
|
148
|
+
# This should take care of our issues with zombies.
|
149
|
+
|
150
|
+
Excellent suggestion. It's done.
|
151
|
+
#
|
152
|
+
# ./lib/foo/zombie_repellant
|
153
|
+
#
|
154
|
+
# Line 6
|
155
|
+
# Spec 123: Does this stuff really work? I'm not convinced.
|
156
|
+
|
157
|
+
You can look at the tests yourself. It seems to work.
|
158
|
+
#
|
159
|
+
# Line 40
|
160
|
+
# Spec 123: Please explain this.
|
161
|
+
}.strip
|
162
|
+
|
163
|
+
CommentWithReply = %Q{
|
164
|
+
Spec 123: I have some general comments, mostly relating to the quality
|
165
|
+
of our zombie-control policies. Basically, they're not
|
166
|
+
working.
|
167
|
+
Spec 456: Sorry about that. I have fixed the branch to have better
|
168
|
+
zombie-control policies.
|
169
|
+
|
170
|
+
./zombies
|
171
|
+
|
172
|
+
Line 2
|
173
|
+
Spec 123: I suggest we do the following instead:
|
174
|
+
zombies.each{ |z| reason_with( z )}
|
175
|
+
zomies.select do |z|
|
176
|
+
z.unconvinced?
|
177
|
+
end.each do |z|
|
178
|
+
destroy z
|
179
|
+
end
|
180
|
+
This should take care of our issues with zombies.
|
181
|
+
Spec 456: Excellent suggestion. It's done.
|
182
|
+
|
183
|
+
|
184
|
+
./lib/foo/zombie_repellant
|
185
|
+
|
186
|
+
Line 6
|
187
|
+
Spec 123: Does this stuff really work? I'm not convinced.
|
188
|
+
Spec 456: You can look at the tests yourself. It seems to work.
|
189
|
+
|
190
|
+
Line 40
|
191
|
+
Spec 123: Please explain this.
|
192
|
+
}.strip
|
193
|
+
|
194
|
+
MalformedReplyBadLines = %Q{
|
195
|
+
# Spec 123: I have some general comments, mostly relating to the quality
|
196
|
+
# of our zombie-control policies. Basically, they're not
|
197
|
+
# working.
|
198
|
+
#
|
199
|
+
# ./zombies
|
200
|
+
|
201
|
+
Uh oh. a malformed reply. This is not a legal spot for comments!
|
202
|
+
|
203
|
+
#
|
204
|
+
# Line 2
|
205
|
+
# Spec 123: I suggest we do the following instead:
|
206
|
+
# zombies.each{ |z| reason_with( z )}
|
207
|
+
# zomies.select do |z|
|
208
|
+
# z.unconvinced?
|
209
|
+
# end.each do |z|
|
210
|
+
# destroy z
|
211
|
+
# end
|
212
|
+
# This should take care of our issues with zombies.
|
213
|
+
#
|
214
|
+
# ./lib/foo/zombie_repellant
|
215
|
+
#
|
216
|
+
# Line 6
|
217
|
+
# Spec 123: Does this stuff really work? I'm not convinced.
|
218
|
+
#
|
219
|
+
# Line 40
|
220
|
+
# Spec 123: Please explain this.
|
221
|
+
}.strip
|
222
|
+
|
223
|
+
MalformedReplyNewFiles = %Q{
|
224
|
+
# Spec 123: I have some general comments, mostly relating to the quality
|
225
|
+
# of our zombie-control policies. Basically, they're not
|
226
|
+
# working.
|
227
|
+
#
|
228
|
+
# ./zombies
|
229
|
+
#
|
230
|
+
# Line 2
|
231
|
+
# Spec 123: I suggest we do the following instead:
|
232
|
+
# zombies.each{ |z| reason_with( z )}
|
233
|
+
# zomies.select do |z|
|
234
|
+
# z.unconvinced?
|
235
|
+
# end.each do |z|
|
236
|
+
# destroy z
|
237
|
+
# end
|
238
|
+
# This should take care of our issues with zombies.
|
239
|
+
#
|
240
|
+
# ./anew/and/illegal/path
|
241
|
+
Uh oh. This appears to be an invalid reply! Madness!
|
242
|
+
#
|
243
|
+
# ./lib/foo/zombie_repellant
|
244
|
+
#
|
245
|
+
# Line 6
|
246
|
+
# Spec 123: Does this stuff really work? I'm not convinced.
|
247
|
+
#
|
248
|
+
# Line 40
|
249
|
+
# Spec 123: Please explain this.
|
250
|
+
}.strip
|
251
|
+
|
252
|
+
|
253
|
+
describe GitTopic::Comment do
|
254
|
+
include GitTopic::Comment::ClassMethods
|
255
|
+
|
256
|
+
describe "#diff_to_file_specific_notes" do
|
257
|
+
|
258
|
+
it "should fail with non-comment additions" do
|
259
|
+
lambda do
|
260
|
+
diff_to_file_specific_notes DiffWithNonCommentAddition,
|
261
|
+
:author => "David"
|
262
|
+
end.should raise_error
|
263
|
+
end
|
264
|
+
|
265
|
+
it "should fail with deletions" do
|
266
|
+
lambda do
|
267
|
+
diff_to_file_specific_notes DiffWithDeletion,
|
268
|
+
:author => "David"
|
269
|
+
end.should raise_error
|
270
|
+
end
|
271
|
+
|
272
|
+
it "should fail if :author is not supplied" do
|
273
|
+
lambda do
|
274
|
+
diff_to_file_specific_notes DiffWithOnlyComments
|
275
|
+
end.should raise_error
|
276
|
+
end
|
277
|
+
|
278
|
+
describe "when there are no existing comments" do
|
279
|
+
|
280
|
+
it "should format the diff correctly for no existing comments" do
|
281
|
+
initial_contents = diff_to_file_specific_notes(
|
282
|
+
DiffWithOnlyComments,
|
283
|
+
:author => "David"
|
284
|
+
)
|
285
|
+
|
286
|
+
# Not interested in exact formatting: just the contents.
|
287
|
+
initial_contents.gsub( /\s+/, "\n").strip.should ==
|
288
|
+
EditorBufferResultFromClean.gsub( /\s+/, "\n" ).strip
|
289
|
+
end
|
290
|
+
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
|
295
|
+
describe "#notes_from_reply_to_comments" do
|
296
|
+
|
297
|
+
it "should fail if there are no existing comments" do
|
298
|
+
self.should_receive( :existing_comments? ).and_return( false )
|
299
|
+
lambda{ notes_from_reply_to_comments }.should raise_error
|
300
|
+
end
|
301
|
+
|
302
|
+
it "
|
303
|
+
should complain if the user malforms the file by responding to ‘new’
|
304
|
+
files
|
305
|
+
".oneline do
|
306
|
+
|
307
|
+
self.should_receive( :existing_comments? ). and_return( true )
|
308
|
+
self.should_receive( :existing_comments ). and_return( ExistingComment )
|
309
|
+
self.should_receive( :git_dir ). and_return( "." )
|
310
|
+
self.should_receive( :notes_ref ).exactly( 0 ).times
|
311
|
+
self.stub!( :invoke_git_editor ) do |path|
|
312
|
+
File.open( path, 'w' ){ |f| f.puts MalformedReplyNewFiles }
|
313
|
+
end
|
314
|
+
self.should_receive( :invoke_git_editor )
|
315
|
+
|
316
|
+
lambda{ notes_from_reply_to_comments }.should raise_error
|
317
|
+
end
|
318
|
+
|
319
|
+
it "
|
320
|
+
should complain if the user malforms the file by responding to
|
321
|
+
file-specific comments before the line sections
|
322
|
+
".oneline do
|
323
|
+
|
324
|
+
self.should_receive( :existing_comments? ). and_return( true )
|
325
|
+
self.should_receive( :existing_comments ). and_return( ExistingComment )
|
326
|
+
self.should_receive( :git_dir ). and_return( "." )
|
327
|
+
self.should_receive( :notes_ref ).exactly( 0 ).times
|
328
|
+
self.stub!( :invoke_git_editor ) do |path|
|
329
|
+
File.open( path, 'w' ){ |f| f.puts MalformedReplyBadLines }
|
330
|
+
end
|
331
|
+
self.should_receive( :invoke_git_editor )
|
332
|
+
|
333
|
+
lambda{ notes_from_reply_to_comments }.should raise_error
|
334
|
+
end
|
335
|
+
|
336
|
+
it "should add the users' comments as replies to the originals" do
|
337
|
+
self.should_receive( :existing_comments? ). and_return( true )
|
338
|
+
self.should_receive( :existing_comments ). and_return( ExistingComment )
|
339
|
+
self.should_receive( :git_dir ). and_return( "." )
|
340
|
+
self.should_receive( :git_author_name_short ). and_return( "Spec 456" )
|
341
|
+
self.should_receive( :notes_ref ).
|
342
|
+
and_return( "refs/notes/reviews/#{@user}/topic" )
|
343
|
+
self.stub!( :invoke_git_editor ) do |path|
|
344
|
+
File.open( path, 'w' ){ |f| f.write LegalReply }
|
345
|
+
end
|
346
|
+
self.should_receive( :invoke_git_editor )
|
347
|
+
self.should_receive( :git ) do
|
348
|
+
File.read( "./COMMENT_EDITMSG" ).should == CommentWithReply
|
349
|
+
end
|
350
|
+
|
351
|
+
lambda{ notes_from_reply_to_comments }.should_not raise_error
|
352
|
+
end
|
353
|
+
|
354
|
+
end
|
355
|
+
|
356
|
+
|
357
|
+
describe "#notes_to_hash" do
|
358
|
+
it "should convert notes to a hash" do
|
359
|
+
hash = notes_to_hash( ExistingComment )
|
360
|
+
hash.should_not be_nil
|
361
|
+
hash.keys.should == [ :general,
|
362
|
+
"./zombies",
|
363
|
+
"./lib/foo/zombie_repellant" ]
|
364
|
+
hash[ :general ].should == 3
|
365
|
+
hash[ "./zombies" ].should be_a Hash
|
366
|
+
hash[ "./lib/foo/zombie_repellant" ].should be_a Hash
|
367
|
+
|
368
|
+
zombie_hash = hash[ "./zombies" ]
|
369
|
+
repellant_hash = hash[ "./lib/foo/zombie_repellant" ]
|
370
|
+
|
371
|
+
zombie_hash.keys.should == [ 2 ]
|
372
|
+
repellant_hash.keys.should == [ 6, 40 ]
|
373
|
+
|
374
|
+
zombie_hash[ 2 ].should == 15
|
375
|
+
repellant_hash[ 6 ].should == 21
|
376
|
+
repellant_hash[ 40 ].should == 24
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
describe "#attrib" do
|
381
|
+
|
382
|
+
it "should return a 16-length string for short author names" do
|
383
|
+
attrib( "David" ).should == "David: "
|
384
|
+
end
|
385
|
+
|
386
|
+
it "should truncate very long author names" do
|
387
|
+
attrib( "DavidVonSuperLongNameStuff" ).
|
388
|
+
should == "DavidVonSuperLo:"
|
389
|
+
end
|
390
|
+
|
391
|
+
it "should respect padding for short author names" do
|
392
|
+
attrib( "David", 4 ).should == " David: "
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
end
|