t4018: an infrastructure to test hunk headers
[git] / t / t4018-diff-funcname.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2007 Johannes E. Schindelin
4 #
5
6 test_description='Test custom diff function name patterns'
7
8 . ./test-lib.sh
9
10 LF='
11 '
12 cat >Beer.java <<\EOF
13 public class Beer
14 {
15         int special;
16         public static void main(String args[])
17         {
18                 String s=" ";
19                 for(int x = 99; x > 0; x--)
20                 {
21                         System.out.print(x + " bottles of beer on the wall "
22                                 + x + " bottles of beer\n"
23                                 + "Take one down, pass it around, " + (x - 1)
24                                 + " bottles of beer on the wall.\n");
25                 }
26                 System.out.print("Go to the store, buy some more,\n"
27                         + "99 bottles of beer on the wall.\n");
28         }
29 }
30 EOF
31 sed 's/beer\\/beer,\\/' <Beer.java >Beer-correct.java
32 cat >Beer.perl <<\EOT
33 package Beer;
34
35 use strict;
36 use warnings;
37 use parent qw(Exporter);
38 our @EXPORT_OK = qw(round finalround);
39
40 sub other; # forward declaration
41
42 # hello
43
44 sub round {
45         my ($n) = @_;
46         print "$n bottles of beer on the wall ";
47         print "$n bottles of beer\n";
48         print "Take one down, pass it around, ";
49         $n = $n - 1;
50         print "$n bottles of beer on the wall.\n";
51 }
52
53 sub finalround
54 {
55         print "Go to the store, buy some more\n";
56         print "99 bottles of beer on the wall.\n");
57 }
58
59 sub withheredocument {
60         print <<"EOF"
61 decoy here-doc
62 EOF
63         # some lines of context
64         # to pad it out
65         print "hello\n";
66 }
67
68 __END__
69
70 =head1 NAME
71
72 Beer - subroutine to output fragment of a drinking song
73
74 =head1 SYNOPSIS
75
76         use Beer qw(round finalround);
77
78         sub song {
79                 for (my $i = 99; $i > 0; $i--) {
80                         round $i;
81                 }
82                 finalround;
83         }
84
85         song;
86
87 =cut
88 EOT
89 sed -e '
90         s/hello/goodbye/
91         s/beer\\/beer,\\/
92         s/more\\/more,\\/
93         s/song;/song();/
94 ' <Beer.perl >Beer-correct.perl
95
96 test_expect_funcname () {
97         lang=${2-java}
98         test_expect_code 1 git diff --no-index -U1 \
99                 "Beer.$lang" "Beer-correct.$lang" >diff &&
100         grep "^@@.*@@ $1" diff
101 }
102
103 diffpatterns="
104         ada
105         bibtex
106         cpp
107         csharp
108         fortran
109         html
110         java
111         matlab
112         objc
113         pascal
114         perl
115         php
116         python
117         ruby
118         tex
119 "
120
121 for p in $diffpatterns
122 do
123         test_expect_success "builtin $p pattern compiles" '
124                 echo "*.java diff=$p" >.gitattributes &&
125                 test_expect_code 1 git diff --no-index \
126                         Beer.java Beer-correct.java 2>msg &&
127                 ! grep fatal msg &&
128                 ! grep error msg
129         '
130         test_expect_success "builtin $p wordRegex pattern compiles" '
131                 echo "*.java diff=$p" >.gitattributes &&
132                 test_expect_code 1 git diff --no-index --word-diff \
133                         Beer.java Beer-correct.java 2>msg &&
134                 ! grep fatal msg &&
135                 ! grep error msg
136         '
137 done
138
139 test_expect_success 'set up .gitattributes declaring drivers to test' '
140         cat >.gitattributes <<-\EOF
141         *.java diff=java
142         *.perl diff=perl
143         EOF
144 '
145
146 test_expect_success 'preset java pattern' '
147         test_expect_funcname "public static void main("
148 '
149
150 test_expect_success 'preset perl pattern' '
151         test_expect_funcname "sub round {\$" perl
152 '
153
154 test_expect_success 'perl pattern accepts K&R style brace placement, too' '
155         test_expect_funcname "sub finalround\$" perl
156 '
157
158 test_expect_success 'but is not distracted by end of <<here document' '
159         test_expect_funcname "sub withheredocument {\$" perl
160 '
161
162 test_expect_success 'perl pattern is not distracted by sub within POD' '
163         test_expect_funcname "=head" perl
164 '
165
166 test_expect_success 'perl pattern gets full line of POD header' '
167         test_expect_funcname "=head1 SYNOPSIS\$" perl
168 '
169
170 test_expect_success 'perl pattern is not distracted by forward declaration' '
171         test_expect_funcname "package Beer;\$" perl
172 '
173
174 test_expect_success 'custom pattern' '
175         test_config diff.java.funcname "!static
176 !String
177 [^      ].*s.*" &&
178         test_expect_funcname "int special;\$"
179 '
180
181 test_expect_success 'last regexp must not be negated' '
182         test_config diff.java.funcname "!static" &&
183         test_expect_code 128 git diff --no-index Beer.java Beer-correct.java 2>msg &&
184         grep ": Last expression must not be negated:" msg
185 '
186
187 test_expect_success 'pattern which matches to end of line' '
188         test_config diff.java.funcname "Beer\$" &&
189         test_expect_funcname "Beer\$"
190 '
191
192 test_expect_success 'alternation in pattern' '
193         test_config diff.java.funcname "Beer$" &&
194         test_config diff.java.xfuncname "^[     ]*((public|static).*)$" &&
195         test_expect_funcname "public static void main("
196 '
197
198 test_expect_success 'setup hunk header tests' '
199         for i in $diffpatterns
200         do
201                 echo "$i-* diff=$i"
202         done > .gitattributes &&
203
204         # add all test files to the index
205         (
206                 cd "$TEST_DIRECTORY"/t4018 &&
207                 git --git-dir="$TRASH_DIRECTORY/.git" add .
208         ) &&
209
210         # place modified files in the worktree
211         for i in $(git ls-files)
212         do
213                 sed -e "s/ChangeMe/IWasChanged/" <"$TEST_DIRECTORY/t4018/$i" >"$i" || return 1
214         done
215 '
216
217 # check each individual file
218 for i in $(git ls-files)
219 do
220         if grep broken "$i" >/dev/null 2>&1
221         then
222                 result=failure
223         else
224                 result=success
225         fi
226         test_expect_$result "hunk header: $i" "
227                 test_when_finished 'cat actual' &&      # for debugging only
228                 git diff -U1 $i >actual &&
229                 grep '@@ .* @@.*RIGHT' actual
230         "
231 done
232
233 test_done