rpatch 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +22 -0
- data/README.md +90 -0
- data/bin/rpatch +27 -0
- data/lib/rpatch/entry.rb +137 -0
- data/lib/rpatch/error.rb +8 -0
- data/lib/rpatch/hunk.rb +271 -0
- data/lib/rpatch/patch.rb +158 -0
- data/lib/rpatch/runner.rb +44 -0
- data/lib/rpatch/version.rb +3 -0
- data/spec/patch_entry_spec.rb +234 -0
- data/spec/patch_file_regexp_spec.rb +73 -0
- data/spec/patch_file_spec.rb +267 -0
- data/spec/patch_hunk_spec.rb +272 -0
- data/spec/spec_helper.rb +24 -0
- data/t/Makefile +80 -0
- data/t/README +3 -0
- data/t/aggregate-results.sh +46 -0
- data/t/t0000-patch-file.sh +297 -0
- data/t/t0100-patch-directory.sh +203 -0
- data/t/test-lib-functions.sh +722 -0
- data/t/test-lib.sh +623 -0
- metadata +132 -0
@@ -0,0 +1,722 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
#
|
3
|
+
# Copyright (c) 2005 Junio C Hamano
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 2 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see http://www.gnu.org/licenses/ .
|
17
|
+
|
18
|
+
# The semantics of the editor variables are that of invoking
|
19
|
+
# sh -c "$EDITOR \"$@\"" files ...
|
20
|
+
#
|
21
|
+
# If our trash directory contains shell metacharacters, they will be
|
22
|
+
# interpreted if we just set $EDITOR directly, so do a little dance with
|
23
|
+
# environment variables to work around this.
|
24
|
+
#
|
25
|
+
# In particular, quoting isn't enough, as the path may contain the same quote
|
26
|
+
# that we're using.
|
27
|
+
test_set_editor () {
|
28
|
+
FAKE_EDITOR="$1"
|
29
|
+
export FAKE_EDITOR
|
30
|
+
EDITOR='"$FAKE_EDITOR"'
|
31
|
+
export EDITOR
|
32
|
+
}
|
33
|
+
|
34
|
+
test_decode_color () {
|
35
|
+
awk '
|
36
|
+
function name(n) {
|
37
|
+
if (n == 0) return "RESET";
|
38
|
+
if (n == 1) return "BOLD";
|
39
|
+
if (n == 30) return "BLACK";
|
40
|
+
if (n == 31) return "RED";
|
41
|
+
if (n == 32) return "GREEN";
|
42
|
+
if (n == 33) return "YELLOW";
|
43
|
+
if (n == 34) return "BLUE";
|
44
|
+
if (n == 35) return "MAGENTA";
|
45
|
+
if (n == 36) return "CYAN";
|
46
|
+
if (n == 37) return "WHITE";
|
47
|
+
if (n == 40) return "BLACK";
|
48
|
+
if (n == 41) return "BRED";
|
49
|
+
if (n == 42) return "BGREEN";
|
50
|
+
if (n == 43) return "BYELLOW";
|
51
|
+
if (n == 44) return "BBLUE";
|
52
|
+
if (n == 45) return "BMAGENTA";
|
53
|
+
if (n == 46) return "BCYAN";
|
54
|
+
if (n == 47) return "BWHITE";
|
55
|
+
}
|
56
|
+
{
|
57
|
+
while (match($0, /\033\[[0-9;]*m/) != 0) {
|
58
|
+
printf "%s<", substr($0, 1, RSTART-1);
|
59
|
+
codes = substr($0, RSTART+2, RLENGTH-3);
|
60
|
+
if (length(codes) == 0)
|
61
|
+
printf "%s", name(0)
|
62
|
+
else {
|
63
|
+
n = split(codes, ary, ";");
|
64
|
+
sep = "";
|
65
|
+
for (i = 1; i <= n; i++) {
|
66
|
+
printf "%s%s", sep, name(ary[i]);
|
67
|
+
sep = ";"
|
68
|
+
}
|
69
|
+
}
|
70
|
+
printf ">";
|
71
|
+
$0 = substr($0, RSTART + RLENGTH, length($0) - RSTART - RLENGTH + 1);
|
72
|
+
}
|
73
|
+
print
|
74
|
+
}
|
75
|
+
'
|
76
|
+
}
|
77
|
+
|
78
|
+
nul_to_q () {
|
79
|
+
"$PERL_PATH" -pe 'y/\000/Q/'
|
80
|
+
}
|
81
|
+
|
82
|
+
q_to_nul () {
|
83
|
+
"$PERL_PATH" -pe 'y/Q/\000/'
|
84
|
+
}
|
85
|
+
|
86
|
+
q_to_cr () {
|
87
|
+
tr Q '\015'
|
88
|
+
}
|
89
|
+
|
90
|
+
q_to_tab () {
|
91
|
+
tr Q '\011'
|
92
|
+
}
|
93
|
+
|
94
|
+
qz_to_tab_space () {
|
95
|
+
tr QZ '\011\040'
|
96
|
+
}
|
97
|
+
|
98
|
+
append_cr () {
|
99
|
+
sed -e 's/$/Q/' | tr Q '\015'
|
100
|
+
}
|
101
|
+
|
102
|
+
remove_cr () {
|
103
|
+
tr '\015' Q | sed -e 's/Q$//'
|
104
|
+
}
|
105
|
+
|
106
|
+
# In some bourne shell implementations, the "unset" builtin returns
|
107
|
+
# nonzero status when a variable to be unset was not set in the first
|
108
|
+
# place.
|
109
|
+
#
|
110
|
+
# Use sane_unset when that should not be considered an error.
|
111
|
+
|
112
|
+
sane_unset () {
|
113
|
+
unset "$@"
|
114
|
+
return 0
|
115
|
+
}
|
116
|
+
|
117
|
+
test_tick () {
|
118
|
+
if test -z "${test_tick+set}"
|
119
|
+
then
|
120
|
+
test_tick=1112911993
|
121
|
+
else
|
122
|
+
test_tick=$(($test_tick + 60))
|
123
|
+
fi
|
124
|
+
GIT_COMMITTER_DATE="$test_tick -0700"
|
125
|
+
GIT_AUTHOR_DATE="$test_tick -0700"
|
126
|
+
export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
|
127
|
+
}
|
128
|
+
|
129
|
+
# Stop execution and start a shell. This is useful for debugging tests and
|
130
|
+
# only makes sense together with "-v".
|
131
|
+
#
|
132
|
+
# Be sure to remove all invocations of this command before submitting.
|
133
|
+
|
134
|
+
test_pause () {
|
135
|
+
if test "$verbose" = t; then
|
136
|
+
"$SHELL_PATH" <&6 >&3 2>&4
|
137
|
+
else
|
138
|
+
error >&5 "test_pause requires --verbose"
|
139
|
+
fi
|
140
|
+
}
|
141
|
+
|
142
|
+
# Call test_commit with the arguments "<message> [<file> [<contents> [<tag>]]]"
|
143
|
+
#
|
144
|
+
# This will commit a file with the given contents and the given commit
|
145
|
+
# message, and tag the resulting commit with the given tag name.
|
146
|
+
#
|
147
|
+
# <file>, <contents>, and <tag> all default to <message>.
|
148
|
+
|
149
|
+
test_commit () {
|
150
|
+
notick= &&
|
151
|
+
signoff= &&
|
152
|
+
while test $# != 0
|
153
|
+
do
|
154
|
+
case "$1" in
|
155
|
+
--notick)
|
156
|
+
notick=yes
|
157
|
+
;;
|
158
|
+
--signoff)
|
159
|
+
signoff="$1"
|
160
|
+
;;
|
161
|
+
*)
|
162
|
+
break
|
163
|
+
;;
|
164
|
+
esac
|
165
|
+
shift
|
166
|
+
done &&
|
167
|
+
file=${2:-"$1.t"} &&
|
168
|
+
echo "${3-$1}" > "$file" &&
|
169
|
+
git add "$file" &&
|
170
|
+
if test -z "$notick"
|
171
|
+
then
|
172
|
+
test_tick
|
173
|
+
fi &&
|
174
|
+
git commit $signoff -m "$1" &&
|
175
|
+
git tag "${4:-$1}"
|
176
|
+
}
|
177
|
+
|
178
|
+
# Call test_merge with the arguments "<message> <commit>", where <commit>
|
179
|
+
# can be a tag pointing to the commit-to-merge.
|
180
|
+
|
181
|
+
test_merge () {
|
182
|
+
test_tick &&
|
183
|
+
git merge -m "$1" "$2" &&
|
184
|
+
git tag "$1"
|
185
|
+
}
|
186
|
+
|
187
|
+
# This function helps systems where core.filemode=false is set.
|
188
|
+
# Use it instead of plain 'chmod +x' to set or unset the executable bit
|
189
|
+
# of a file in the working directory and add it to the index.
|
190
|
+
|
191
|
+
test_chmod () {
|
192
|
+
chmod "$@" &&
|
193
|
+
git update-index --add "--chmod=$@"
|
194
|
+
}
|
195
|
+
|
196
|
+
# Unset a configuration variable, but don't fail if it doesn't exist.
|
197
|
+
test_unconfig () {
|
198
|
+
git config --unset-all "$@"
|
199
|
+
config_status=$?
|
200
|
+
case "$config_status" in
|
201
|
+
5) # ok, nothing to unset
|
202
|
+
config_status=0
|
203
|
+
;;
|
204
|
+
esac
|
205
|
+
return $config_status
|
206
|
+
}
|
207
|
+
|
208
|
+
# Set git config, automatically unsetting it after the test is over.
|
209
|
+
test_config () {
|
210
|
+
test_when_finished "test_unconfig '$1'" &&
|
211
|
+
git config "$@"
|
212
|
+
}
|
213
|
+
|
214
|
+
test_config_global () {
|
215
|
+
test_when_finished "test_unconfig --global '$1'" &&
|
216
|
+
git config --global "$@"
|
217
|
+
}
|
218
|
+
|
219
|
+
write_script () {
|
220
|
+
{
|
221
|
+
echo "#!${2-"$SHELL_PATH"}" &&
|
222
|
+
cat
|
223
|
+
} >"$1" &&
|
224
|
+
chmod +x "$1"
|
225
|
+
}
|
226
|
+
|
227
|
+
# Use test_set_prereq to tell that a particular prerequisite is available.
|
228
|
+
# The prerequisite can later be checked for in two ways:
|
229
|
+
#
|
230
|
+
# - Explicitly using test_have_prereq.
|
231
|
+
#
|
232
|
+
# - Implicitly by specifying the prerequisite tag in the calls to
|
233
|
+
# test_expect_{success,failure,code}.
|
234
|
+
#
|
235
|
+
# The single parameter is the prerequisite tag (a simple word, in all
|
236
|
+
# capital letters by convention).
|
237
|
+
|
238
|
+
test_set_prereq () {
|
239
|
+
satisfied_prereq="$satisfied_prereq$1 "
|
240
|
+
}
|
241
|
+
satisfied_prereq=" "
|
242
|
+
lazily_testable_prereq= lazily_tested_prereq=
|
243
|
+
|
244
|
+
# Usage: test_lazy_prereq PREREQ 'script'
|
245
|
+
test_lazy_prereq () {
|
246
|
+
lazily_testable_prereq="$lazily_testable_prereq$1 "
|
247
|
+
eval test_prereq_lazily_$1=\$2
|
248
|
+
}
|
249
|
+
|
250
|
+
test_run_lazy_prereq_ () {
|
251
|
+
script='
|
252
|
+
mkdir -p "$TRASH_DIRECTORY/prereq-test-dir" &&
|
253
|
+
(
|
254
|
+
cd "$TRASH_DIRECTORY/prereq-test-dir" &&'"$2"'
|
255
|
+
)'
|
256
|
+
say >&3 "checking prerequisite: $1"
|
257
|
+
say >&3 "$script"
|
258
|
+
test_eval_ "$script"
|
259
|
+
eval_ret=$?
|
260
|
+
rm -rf "$TRASH_DIRECTORY/prereq-test-dir"
|
261
|
+
if test "$eval_ret" = 0; then
|
262
|
+
say >&3 "prerequisite $1 ok"
|
263
|
+
else
|
264
|
+
say >&3 "prerequisite $1 not satisfied"
|
265
|
+
fi
|
266
|
+
return $eval_ret
|
267
|
+
}
|
268
|
+
|
269
|
+
test_have_prereq () {
|
270
|
+
# prerequisites can be concatenated with ','
|
271
|
+
save_IFS=$IFS
|
272
|
+
IFS=,
|
273
|
+
set -- $*
|
274
|
+
IFS=$save_IFS
|
275
|
+
|
276
|
+
total_prereq=0
|
277
|
+
ok_prereq=0
|
278
|
+
missing_prereq=
|
279
|
+
|
280
|
+
for prerequisite
|
281
|
+
do
|
282
|
+
case "$prerequisite" in
|
283
|
+
!*)
|
284
|
+
negative_prereq=t
|
285
|
+
prerequisite=${prerequisite#!}
|
286
|
+
;;
|
287
|
+
*)
|
288
|
+
negative_prereq=
|
289
|
+
esac
|
290
|
+
|
291
|
+
case " $lazily_tested_prereq " in
|
292
|
+
*" $prerequisite "*)
|
293
|
+
;;
|
294
|
+
*)
|
295
|
+
case " $lazily_testable_prereq " in
|
296
|
+
*" $prerequisite "*)
|
297
|
+
eval "script=\$test_prereq_lazily_$prerequisite" &&
|
298
|
+
if test_run_lazy_prereq_ "$prerequisite" "$script"
|
299
|
+
then
|
300
|
+
test_set_prereq $prerequisite
|
301
|
+
fi
|
302
|
+
lazily_tested_prereq="$lazily_tested_prereq$prerequisite "
|
303
|
+
esac
|
304
|
+
;;
|
305
|
+
esac
|
306
|
+
|
307
|
+
total_prereq=$(($total_prereq + 1))
|
308
|
+
case "$satisfied_prereq" in
|
309
|
+
*" $prerequisite "*)
|
310
|
+
satisfied_this_prereq=t
|
311
|
+
;;
|
312
|
+
*)
|
313
|
+
satisfied_this_prereq=
|
314
|
+
esac
|
315
|
+
|
316
|
+
case "$satisfied_this_prereq,$negative_prereq" in
|
317
|
+
t,|,t)
|
318
|
+
ok_prereq=$(($ok_prereq + 1))
|
319
|
+
;;
|
320
|
+
*)
|
321
|
+
# Keep a list of missing prerequisites; restore
|
322
|
+
# the negative marker if necessary.
|
323
|
+
prerequisite=${negative_prereq:+!}$prerequisite
|
324
|
+
if test -z "$missing_prereq"
|
325
|
+
then
|
326
|
+
missing_prereq=$prerequisite
|
327
|
+
else
|
328
|
+
missing_prereq="$prerequisite,$missing_prereq"
|
329
|
+
fi
|
330
|
+
esac
|
331
|
+
done
|
332
|
+
|
333
|
+
test $total_prereq = $ok_prereq
|
334
|
+
}
|
335
|
+
|
336
|
+
test_declared_prereq () {
|
337
|
+
case ",$test_prereq," in
|
338
|
+
*,$1,*)
|
339
|
+
return 0
|
340
|
+
;;
|
341
|
+
esac
|
342
|
+
return 1
|
343
|
+
}
|
344
|
+
|
345
|
+
test_expect_failure () {
|
346
|
+
test_start_
|
347
|
+
test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
|
348
|
+
test "$#" = 2 ||
|
349
|
+
error "bug in the test script: not 2 or 3 parameters to test-expect-failure"
|
350
|
+
export test_prereq
|
351
|
+
if ! test_skip "$@"
|
352
|
+
then
|
353
|
+
say >&3 "checking known breakage: $2"
|
354
|
+
if test_run_ "$2" expecting_failure
|
355
|
+
then
|
356
|
+
test_known_broken_ok_ "$1"
|
357
|
+
else
|
358
|
+
test_known_broken_failure_ "$1"
|
359
|
+
fi
|
360
|
+
fi
|
361
|
+
test_finish_
|
362
|
+
}
|
363
|
+
|
364
|
+
test_expect_success () {
|
365
|
+
test_start_
|
366
|
+
test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
|
367
|
+
test "$#" = 2 ||
|
368
|
+
error "bug in the test script: not 2 or 3 parameters to test-expect-success"
|
369
|
+
export test_prereq
|
370
|
+
if ! test_skip "$@"
|
371
|
+
then
|
372
|
+
say >&3 "expecting success: $2"
|
373
|
+
if test_run_ "$2"
|
374
|
+
then
|
375
|
+
test_ok_ "$1"
|
376
|
+
else
|
377
|
+
test_failure_ "$@"
|
378
|
+
fi
|
379
|
+
fi
|
380
|
+
test_finish_
|
381
|
+
}
|
382
|
+
|
383
|
+
# test_external runs external test scripts that provide continuous
|
384
|
+
# test output about their progress, and succeeds/fails on
|
385
|
+
# zero/non-zero exit code. It outputs the test output on stdout even
|
386
|
+
# in non-verbose mode, and announces the external script with "# run
|
387
|
+
# <n>: ..." before running it. When providing relative paths, keep in
|
388
|
+
# mind that all scripts run in "trash directory".
|
389
|
+
# Usage: test_external description command arguments...
|
390
|
+
# Example: test_external 'Perl API' perl ../path/to/test.pl
|
391
|
+
test_external () {
|
392
|
+
test "$#" = 4 && { test_prereq=$1; shift; } || test_prereq=
|
393
|
+
test "$#" = 3 ||
|
394
|
+
error >&5 "bug in the test script: not 3 or 4 parameters to test_external"
|
395
|
+
descr="$1"
|
396
|
+
shift
|
397
|
+
export test_prereq
|
398
|
+
if ! test_skip "$descr" "$@"
|
399
|
+
then
|
400
|
+
# Announce the script to reduce confusion about the
|
401
|
+
# test output that follows.
|
402
|
+
say_color "" "# run $test_count: $descr ($*)"
|
403
|
+
# Export TEST_DIRECTORY, TRASH_DIRECTORY and GIT_TEST_LONG
|
404
|
+
# to be able to use them in script
|
405
|
+
export TEST_DIRECTORY TRASH_DIRECTORY GIT_TEST_LONG
|
406
|
+
# Run command; redirect its stderr to &4 as in
|
407
|
+
# test_run_, but keep its stdout on our stdout even in
|
408
|
+
# non-verbose mode.
|
409
|
+
"$@" 2>&4
|
410
|
+
if [ "$?" = 0 ]
|
411
|
+
then
|
412
|
+
if test $test_external_has_tap -eq 0; then
|
413
|
+
test_ok_ "$descr"
|
414
|
+
else
|
415
|
+
say_color "" "# test_external test $descr was ok"
|
416
|
+
test_success=$(($test_success + 1))
|
417
|
+
fi
|
418
|
+
else
|
419
|
+
if test $test_external_has_tap -eq 0; then
|
420
|
+
test_failure_ "$descr" "$@"
|
421
|
+
else
|
422
|
+
say_color error "# test_external test $descr failed: $@"
|
423
|
+
test_failure=$(($test_failure + 1))
|
424
|
+
fi
|
425
|
+
fi
|
426
|
+
fi
|
427
|
+
}
|
428
|
+
|
429
|
+
# Like test_external, but in addition tests that the command generated
|
430
|
+
# no output on stderr.
|
431
|
+
test_external_without_stderr () {
|
432
|
+
# The temporary file has no (and must have no) security
|
433
|
+
# implications.
|
434
|
+
tmp=${TMPDIR:-/tmp}
|
435
|
+
stderr="$tmp/git-external-stderr.$$.tmp"
|
436
|
+
test_external "$@" 4> "$stderr"
|
437
|
+
[ -f "$stderr" ] || error "Internal error: $stderr disappeared."
|
438
|
+
descr="no stderr: $1"
|
439
|
+
shift
|
440
|
+
say >&3 "# expecting no stderr from previous command"
|
441
|
+
if [ ! -s "$stderr" ]; then
|
442
|
+
rm "$stderr"
|
443
|
+
|
444
|
+
if test $test_external_has_tap -eq 0; then
|
445
|
+
test_ok_ "$descr"
|
446
|
+
else
|
447
|
+
say_color "" "# test_external_without_stderr test $descr was ok"
|
448
|
+
test_success=$(($test_success + 1))
|
449
|
+
fi
|
450
|
+
else
|
451
|
+
if [ "$verbose" = t ]; then
|
452
|
+
output=`echo; echo "# Stderr is:"; cat "$stderr"`
|
453
|
+
else
|
454
|
+
output=
|
455
|
+
fi
|
456
|
+
# rm first in case test_failure exits.
|
457
|
+
rm "$stderr"
|
458
|
+
if test $test_external_has_tap -eq 0; then
|
459
|
+
test_failure_ "$descr" "$@" "$output"
|
460
|
+
else
|
461
|
+
say_color error "# test_external_without_stderr test $descr failed: $@: $output"
|
462
|
+
test_failure=$(($test_failure + 1))
|
463
|
+
fi
|
464
|
+
fi
|
465
|
+
}
|
466
|
+
|
467
|
+
# debugging-friendly alternatives to "test [-f|-d|-e]"
|
468
|
+
# The commands test the existence or non-existence of $1. $2 can be
|
469
|
+
# given to provide a more precise diagnosis.
|
470
|
+
test_path_is_file () {
|
471
|
+
if ! [ -f "$1" ]
|
472
|
+
then
|
473
|
+
echo "File $1 doesn't exist. $*"
|
474
|
+
false
|
475
|
+
fi
|
476
|
+
}
|
477
|
+
|
478
|
+
test_path_is_dir () {
|
479
|
+
if ! [ -d "$1" ]
|
480
|
+
then
|
481
|
+
echo "Directory $1 doesn't exist. $*"
|
482
|
+
false
|
483
|
+
fi
|
484
|
+
}
|
485
|
+
|
486
|
+
test_path_is_missing () {
|
487
|
+
if [ -e "$1" ]
|
488
|
+
then
|
489
|
+
echo "Path exists:"
|
490
|
+
ls -ld "$1"
|
491
|
+
if [ $# -ge 1 ]; then
|
492
|
+
echo "$*"
|
493
|
+
fi
|
494
|
+
false
|
495
|
+
fi
|
496
|
+
}
|
497
|
+
|
498
|
+
# test_line_count checks that a file has the number of lines it
|
499
|
+
# ought to. For example:
|
500
|
+
#
|
501
|
+
# test_expect_success 'produce exactly one line of output' '
|
502
|
+
# do something >output &&
|
503
|
+
# test_line_count = 1 output
|
504
|
+
# '
|
505
|
+
#
|
506
|
+
# is like "test $(wc -l <output) = 1" except that it passes the
|
507
|
+
# output through when the number of lines is wrong.
|
508
|
+
|
509
|
+
test_line_count () {
|
510
|
+
if test $# != 3
|
511
|
+
then
|
512
|
+
error "bug in the test script: not 3 parameters to test_line_count"
|
513
|
+
elif ! test $(wc -l <"$3") "$1" "$2"
|
514
|
+
then
|
515
|
+
echo "test_line_count: line count for $3 !$1 $2"
|
516
|
+
cat "$3"
|
517
|
+
return 1
|
518
|
+
fi
|
519
|
+
}
|
520
|
+
|
521
|
+
# This is not among top-level (test_expect_success | test_expect_failure)
|
522
|
+
# but is a prefix that can be used in the test script, like:
|
523
|
+
#
|
524
|
+
# test_expect_success 'complain and die' '
|
525
|
+
# do something &&
|
526
|
+
# do something else &&
|
527
|
+
# test_must_fail git checkout ../outerspace
|
528
|
+
# '
|
529
|
+
#
|
530
|
+
# Writing this as "! git checkout ../outerspace" is wrong, because
|
531
|
+
# the failure could be due to a segv. We want a controlled failure.
|
532
|
+
|
533
|
+
test_must_fail () {
|
534
|
+
"$@"
|
535
|
+
exit_code=$?
|
536
|
+
if test $exit_code = 0; then
|
537
|
+
echo >&2 "test_must_fail: command succeeded: $*"
|
538
|
+
return 1
|
539
|
+
elif test $exit_code -gt 129 -a $exit_code -le 192; then
|
540
|
+
echo >&2 "test_must_fail: died by signal: $*"
|
541
|
+
return 1
|
542
|
+
elif test $exit_code = 127; then
|
543
|
+
echo >&2 "test_must_fail: command not found: $*"
|
544
|
+
return 1
|
545
|
+
elif test $exit_code = 126; then
|
546
|
+
echo >&2 "test_must_fail: valgrind error: $*"
|
547
|
+
return 1
|
548
|
+
fi
|
549
|
+
return 0
|
550
|
+
}
|
551
|
+
|
552
|
+
# Similar to test_must_fail, but tolerates success, too. This is
|
553
|
+
# meant to be used in contexts like:
|
554
|
+
#
|
555
|
+
# test_expect_success 'some command works without configuration' '
|
556
|
+
# test_might_fail git config --unset all.configuration &&
|
557
|
+
# do something
|
558
|
+
# '
|
559
|
+
#
|
560
|
+
# Writing "git config --unset all.configuration || :" would be wrong,
|
561
|
+
# because we want to notice if it fails due to segv.
|
562
|
+
|
563
|
+
test_might_fail () {
|
564
|
+
"$@"
|
565
|
+
exit_code=$?
|
566
|
+
if test $exit_code -gt 129 -a $exit_code -le 192; then
|
567
|
+
echo >&2 "test_might_fail: died by signal: $*"
|
568
|
+
return 1
|
569
|
+
elif test $exit_code = 127; then
|
570
|
+
echo >&2 "test_might_fail: command not found: $*"
|
571
|
+
return 1
|
572
|
+
fi
|
573
|
+
return 0
|
574
|
+
}
|
575
|
+
|
576
|
+
# Similar to test_must_fail and test_might_fail, but check that a
|
577
|
+
# given command exited with a given exit code. Meant to be used as:
|
578
|
+
#
|
579
|
+
# test_expect_success 'Merge with d/f conflicts' '
|
580
|
+
# test_expect_code 1 git merge "merge msg" B master
|
581
|
+
# '
|
582
|
+
|
583
|
+
test_expect_code () {
|
584
|
+
want_code=$1
|
585
|
+
shift
|
586
|
+
"$@"
|
587
|
+
exit_code=$?
|
588
|
+
if test $exit_code = $want_code
|
589
|
+
then
|
590
|
+
return 0
|
591
|
+
fi
|
592
|
+
|
593
|
+
echo >&2 "test_expect_code: command exited with $exit_code, we wanted $want_code $*"
|
594
|
+
return 1
|
595
|
+
}
|
596
|
+
|
597
|
+
# test_cmp is a helper function to compare actual and expected output.
|
598
|
+
# You can use it like:
|
599
|
+
#
|
600
|
+
# test_expect_success 'foo works' '
|
601
|
+
# echo expected >expected &&
|
602
|
+
# foo >actual &&
|
603
|
+
# test_cmp expected actual
|
604
|
+
# '
|
605
|
+
#
|
606
|
+
# This could be written as either "cmp" or "diff -u", but:
|
607
|
+
# - cmp's output is not nearly as easy to read as diff -u
|
608
|
+
# - not all diff versions understand "-u"
|
609
|
+
|
610
|
+
test_cmp() {
|
611
|
+
$GIT_TEST_CMP "$@"
|
612
|
+
}
|
613
|
+
|
614
|
+
# Check if the file expected to be empty is indeed empty, and barfs
|
615
|
+
# otherwise.
|
616
|
+
|
617
|
+
test_must_be_empty () {
|
618
|
+
if test -s "$1"
|
619
|
+
then
|
620
|
+
echo "'$1' is not empty, it contains:"
|
621
|
+
cat "$1"
|
622
|
+
return 1
|
623
|
+
fi
|
624
|
+
}
|
625
|
+
|
626
|
+
# Tests that its two parameters refer to the same revision
|
627
|
+
test_cmp_rev () {
|
628
|
+
git rev-parse --verify "$1" >expect.rev &&
|
629
|
+
git rev-parse --verify "$2" >actual.rev &&
|
630
|
+
test_cmp expect.rev actual.rev
|
631
|
+
}
|
632
|
+
|
633
|
+
# Print a sequence of numbers or letters in increasing order. This is
|
634
|
+
# similar to GNU seq(1), but the latter might not be available
|
635
|
+
# everywhere (and does not do letters). It may be used like:
|
636
|
+
#
|
637
|
+
# for i in `test_seq 100`; do
|
638
|
+
# for j in `test_seq 10 20`; do
|
639
|
+
# for k in `test_seq a z`; do
|
640
|
+
# echo $i-$j-$k
|
641
|
+
# done
|
642
|
+
# done
|
643
|
+
# done
|
644
|
+
|
645
|
+
test_seq () {
|
646
|
+
case $# in
|
647
|
+
1) set 1 "$@" ;;
|
648
|
+
2) ;;
|
649
|
+
*) error "bug in the test script: not 1 or 2 parameters to test_seq" ;;
|
650
|
+
esac
|
651
|
+
"$PERL_PATH" -le 'print for $ARGV[0]..$ARGV[1]' -- "$@"
|
652
|
+
}
|
653
|
+
|
654
|
+
# This function can be used to schedule some commands to be run
|
655
|
+
# unconditionally at the end of the test to restore sanity:
|
656
|
+
#
|
657
|
+
# test_expect_success 'test core.capslock' '
|
658
|
+
# git config core.capslock true &&
|
659
|
+
# test_when_finished "git config --unset core.capslock" &&
|
660
|
+
# hello world
|
661
|
+
# '
|
662
|
+
#
|
663
|
+
# That would be roughly equivalent to
|
664
|
+
#
|
665
|
+
# test_expect_success 'test core.capslock' '
|
666
|
+
# git config core.capslock true &&
|
667
|
+
# hello world
|
668
|
+
# git config --unset core.capslock
|
669
|
+
# '
|
670
|
+
#
|
671
|
+
# except that the greeting and config --unset must both succeed for
|
672
|
+
# the test to pass.
|
673
|
+
#
|
674
|
+
# Note that under --immediate mode, no clean-up is done to help diagnose
|
675
|
+
# what went wrong.
|
676
|
+
|
677
|
+
test_when_finished () {
|
678
|
+
test_cleanup="{ $*
|
679
|
+
} && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup"
|
680
|
+
}
|
681
|
+
|
682
|
+
# Most tests can use the created repository, but some may need to create more.
|
683
|
+
# Usage: test_create_repo <directory>
|
684
|
+
test_create_repo () {
|
685
|
+
test "$#" = 1 ||
|
686
|
+
error "bug in the test script: not 1 parameter to test-create-repo"
|
687
|
+
repo="$1"
|
688
|
+
mkdir -p "$repo"
|
689
|
+
(
|
690
|
+
cd "$repo" || error "Cannot setup test environment"
|
691
|
+
gistore init --repo . >&3 2>&4 ||
|
692
|
+
error "cannot run git init -- have you built things yet?"
|
693
|
+
) || exit
|
694
|
+
}
|
695
|
+
|
696
|
+
# This function helps on symlink challenged file systems when it is not
|
697
|
+
# important that the file system entry is a symbolic link.
|
698
|
+
# Use test_ln_s_add instead of "ln -s x y && git add y" to add a
|
699
|
+
# symbolic link entry y to the index.
|
700
|
+
|
701
|
+
test_ln_s_add () {
|
702
|
+
if test_have_prereq SYMLINKS
|
703
|
+
then
|
704
|
+
ln -s "$1" "$2" &&
|
705
|
+
git update-index --add "$2"
|
706
|
+
else
|
707
|
+
printf '%s' "$1" >"$2" &&
|
708
|
+
ln_s_obj=$(git hash-object -w "$2") &&
|
709
|
+
git update-index --add --cacheinfo 120000 $ln_s_obj "$2"
|
710
|
+
fi
|
711
|
+
}
|
712
|
+
|
713
|
+
git_log_only_subject() {
|
714
|
+
repo=$1
|
715
|
+
shift
|
716
|
+
if test $(gistore check-git-version 1.6.3) -ge 0; then
|
717
|
+
gistore log --repo $repo --pretty="%s" $@
|
718
|
+
else
|
719
|
+
gistore log --repo $repo --pretty="format:%s" $@
|
720
|
+
printf "\n"
|
721
|
+
fi
|
722
|
+
}
|