rpatch 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,272 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+
4
+ require 'spec_helper'
5
+
6
+ describe Rpatch::PatchHunk do
7
+
8
+ let(:hunk_text) do
9
+ <<-EOF
10
+ +/*
11
+ + * Copyright (c) 2013 Jiang Xin
12
+ + */
13
+ +
14
+ When I hack files using GNU patch,
15
+ sometimes fail because of the change of upstream files.
16
+ If patch can ignore blank lines, support regex patterns
17
+ in patch, it will be nice.
18
+ +So comes rpatch.
19
+ +
20
+ Happy hacking.
21
+ -
22
+ --- jiangxin
23
+ +--
24
+ +jiangxin
25
+ EOF
26
+ end
27
+
28
+ let(:patch_hunk) do
29
+ hunk = Rpatch::PatchHunk.new('@@ description')
30
+ hunk_text.lines.each do |line|
31
+ hunk.feed_line line.chomp
32
+ end
33
+ hunk
34
+ end
35
+
36
+ it "Initial with description only" do
37
+ title = "foo.bar"
38
+ Rpatch::PatchHunk.new("@@ #{title}").title.should be == title
39
+ end
40
+
41
+ it "Initial with zero patterns_before_patch.size and zero patterns_after_patch.size" do
42
+ Rpatch::PatchHunk.new("@@ test").diffs.size.should be == 0
43
+ Rpatch::PatchHunk.new("@@ test").patterns_before_patch.size.should be == 0
44
+ Rpatch::PatchHunk.new("@@ test").patterns_after_patch.size.should be == 0
45
+ end
46
+
47
+
48
+ it "patch_hunk's desc and contents test" do
49
+ patch_hunk.title.should be == 'description'
50
+ patch_hunk.diffs.size.should be == hunk_text.split("\n").size
51
+ patch_hunk.patterns.size.should be == 15
52
+ end
53
+
54
+ it "should have 7 patterns_before_patch.sizes" do
55
+ patch_hunk.patterns_before_patch.size.should be == 7
56
+ patch_hunk.patterns_before_patch.size.should be == 7
57
+ end
58
+
59
+ it "should have 13 patterns_after_patch.sizes" do
60
+ patch_hunk.patterns_after_patch.size.should be == 13
61
+ patch_hunk.patterns_after_patch.size.should be == 13
62
+ end
63
+
64
+ it "patch success (1)" do
65
+ before = <<-EOF
66
+ When I hack files using GNU patch,
67
+ sometimes fail because of the change of upstream files.
68
+ If patch can ignore blank lines, support regex patterns
69
+ in patch, it will be nice.
70
+ Happy hacking.
71
+
72
+ -- jiangxin
73
+ EOF
74
+ before_lines = before.split("\n")
75
+ before_lines_dup = before_lines.dup
76
+
77
+ after = <<-EOF
78
+ /*
79
+ * Copyright (c) 2013 Jiang Xin
80
+ */
81
+
82
+ When I hack files using GNU patch,
83
+ sometimes fail because of the change of upstream files.
84
+ If patch can ignore blank lines, support regex patterns
85
+ in patch, it will be nice.
86
+ So comes rpatch.
87
+
88
+ Happy hacking.
89
+ --
90
+ jiangxin
91
+ EOF
92
+
93
+ patch_hunk.match_after_patch(before_lines).should be == nil
94
+ patch_hunk.match_before_patch(before_lines).should be == [0, 7]
95
+ result = before_lines.dup
96
+ patch_hunk.patch(result).should be == after.split("\n")
97
+ (result * "\n" + "\n").should be == after
98
+ before_lines_dup.should be == before_lines
99
+ end
100
+
101
+ it "patch success (2): whitespaces" do
102
+ before = <<-EOF
103
+ When I hack files using GNU patch,
104
+ sometimes fail because of the change of upstream files.
105
+ If patch can ignore blank lines, support regex patterns
106
+ in patch, it will be nice.
107
+ Happy hacking.
108
+
109
+ -- jiangxin
110
+ EOF
111
+ before_lines = before.split("\n")
112
+ before_lines_dup = before_lines.dup
113
+
114
+ after = <<-EOF
115
+ /*
116
+ * Copyright (c) 2013 Jiang Xin
117
+ */
118
+
119
+ When I hack files using GNU patch,
120
+ sometimes fail because of the change of upstream files.
121
+ If patch can ignore blank lines, support regex patterns
122
+ in patch, it will be nice.
123
+ So comes rpatch.
124
+
125
+ Happy hacking.
126
+ --
127
+ jiangxin
128
+ EOF
129
+
130
+ patch_hunk.match_after_patch(before_lines).should be == nil
131
+ patch_hunk.match_before_patch(before_lines).should be == [0, 7]
132
+ result = before_lines.dup
133
+ patch_hunk.patch(result)
134
+ (result * "\n" + "\n").should be == after
135
+ before_lines_dup.should be == before_lines
136
+ end
137
+
138
+ it "patch success (3): blank lines and comments " do
139
+ before = <<-EOF
140
+
141
+
142
+ When I hack files using GNU patch,
143
+
144
+ sometimes fail because of the change of upstream files.
145
+
146
+ # If patch can ignore blank lines, support regex patterns
147
+ ## in patch, it will be nice.
148
+ Happy hacking.
149
+
150
+ -- jiangxin
151
+ EOF
152
+ before_lines = before.split("\n")
153
+ before_lines_dup = before_lines.dup
154
+
155
+ after = <<-EOF
156
+
157
+
158
+ /*
159
+ * Copyright (c) 2013 Jiang Xin
160
+ */
161
+
162
+ When I hack files using GNU patch,
163
+
164
+ sometimes fail because of the change of upstream files.
165
+
166
+ # If patch can ignore blank lines, support regex patterns
167
+ ## in patch, it will be nice.
168
+ So comes rpatch.
169
+
170
+ Happy hacking.
171
+ --
172
+ jiangxin
173
+ EOF
174
+
175
+ patch_hunk.match_after_patch(before_lines).should be == nil
176
+ patch_hunk.match_before_patch(before_lines).should be == [2, 9]
177
+ result = before_lines.dup
178
+ patch_hunk.patch(result)
179
+ (result * "\n" + "\n").should be == after
180
+ before_lines_dup.should be == before_lines
181
+ end
182
+
183
+ it "patch failed (1): not match" do
184
+ before = "Hello, \nworld."
185
+ before_lines = before.split("\n")
186
+ before_lines_dup = before_lines.dup
187
+
188
+ patch_hunk.match_after_patch(before_lines).should be == nil
189
+ patch_hunk.match_before_patch(before_lines).should be == nil
190
+ expect {
191
+ patch_hunk.patch(before_lines)
192
+ }.to raise_exception Rpatch::PatchHunkError, /Hunk # \(description\) FAILED to apply. Match failed./
193
+ before_lines.should be == before_lines_dup
194
+ end
195
+
196
+ it "patch failed (2): already patched" do
197
+ before = <<-EOF
198
+ /*
199
+ * Copyright (c) 2013 Jiang Xin
200
+ */
201
+
202
+
203
+
204
+ When I hack files using GNU patch,
205
+
206
+ sometimes fail because of the change of upstream files.
207
+
208
+ # If patch can ignore blank lines, support regex patterns
209
+ ## in patch, it will be nice.
210
+ So comes rpatch.
211
+
212
+ Happy hacking.
213
+ --
214
+ jiangxin
215
+ EOF
216
+
217
+
218
+ before_lines = before.split("\n")
219
+ before_lines_dup = before_lines.dup
220
+
221
+ patch_hunk.match_after_patch(before_lines).should be == [0, 17]
222
+ patch_hunk.match_before_patch(before_lines).should be == nil
223
+ expect {
224
+ patch_hunk.patch(before_lines)
225
+ }.to raise_exception Rpatch::AlreadyPatchedError
226
+ before_lines.should be == before_lines_dup
227
+ end
228
+
229
+ it "patch partial of text" do
230
+ before = <<-EOF
231
+ When I hack files using GNU patch,
232
+ sometimes fail because of the change of upstream files.
233
+ So comes rpatch.
234
+
235
+ Happy hacking.
236
+ EOF
237
+ before_lines = before.split("\n")
238
+ result = before_lines.dup
239
+
240
+ diff = <<-EOF
241
+ +/*
242
+ + * Copyright (c) 2013 Jiang Xin
243
+ + */
244
+ +
245
+ When I hack files using GNU patch,
246
+ sometimes fail because of the change of upstream files.
247
+ EOF
248
+
249
+ after = <<-EOF
250
+ /*
251
+ * Copyright (c) 2013 Jiang Xin
252
+ */
253
+
254
+ When I hack files using GNU patch,
255
+ sometimes fail because of the change of upstream files.
256
+ So comes rpatch.
257
+
258
+ Happy hacking.
259
+ EOF
260
+
261
+ patch_hunk = Rpatch::PatchHunk.new('@@ description')
262
+ diff.lines.each do |line|
263
+ patch_hunk.feed_line line.chomp
264
+ end
265
+
266
+ patch_hunk.match_after_patch(before_lines).should be == nil
267
+ patch_hunk.match_before_patch(before_lines).should be == [0, 2]
268
+ result.should be == before_lines
269
+ patch_hunk.patch(result)
270
+ (result * "\n" + "\n").should be == after
271
+ end
272
+ end
@@ -0,0 +1,24 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ RSpec.configure do |config|
8
+ config.treat_symbols_as_metadata_keys_with_true_values = true
9
+ config.run_all_when_everything_filtered = true
10
+ config.filter_run :focus
11
+
12
+ # Run specs in random order to surface order dependencies. If you find an
13
+ # order dependency and want to debug it, you can fix the order by providing
14
+ # the seed, which is printed after each run.
15
+ # --seed 1234
16
+ config.order = 'random'
17
+ end
18
+
19
+ $:.unshift 'lib'
20
+ require 'rpatch/patch'
21
+ require 'rpatch/entry'
22
+ require 'rpatch/hunk'
23
+ require 'rpatch/error'
24
+ require 'rpatch/version'
data/t/Makefile ADDED
@@ -0,0 +1,80 @@
1
+ # Run tests
2
+ #
3
+ # Copyright (c) 2005 Junio C Hamano
4
+ #
5
+
6
+ #GIT_TEST_OPTS = --verbose --debug
7
+ SHELL_PATH ?= $(SHELL)
8
+ PERL_PATH ?= /usr/bin/perl
9
+ TAR ?= $(TAR)
10
+ RM ?= rm -f
11
+ PROVE ?= prove
12
+ DEFAULT_TEST_TARGET ?= test
13
+ TEST_LINT ?= test-lint-duplicates test-lint-executable
14
+
15
+ ifdef TEST_OUTPUT_DIRECTORY
16
+ TEST_RESULTS_DIRECTORY = $(TEST_OUTPUT_DIRECTORY)/test-results
17
+ else
18
+ TEST_RESULTS_DIRECTORY = test-results
19
+ endif
20
+
21
+ # Shell quote;
22
+ SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
23
+ PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
24
+ TEST_RESULTS_DIRECTORY_SQ = $(subst ','\'',$(TEST_RESULTS_DIRECTORY))
25
+
26
+ T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh))
27
+
28
+ all: $(DEFAULT_TEST_TARGET)
29
+
30
+ test: pre-clean $(TEST_LINT)
31
+ $(MAKE) aggregate-results-and-cleanup
32
+
33
+ prove: pre-clean $(TEST_LINT)
34
+ @echo "*** prove ***"; $(PROVE) --exec '$(SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)
35
+ $(MAKE) clean-except-prove-cache
36
+
37
+ $(T):
38
+ @echo "*** $@ ***"; GIT_CONFIG=.git/config '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)
39
+
40
+ pre-clean:
41
+ $(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)'
42
+
43
+ clean-except-prove-cache:
44
+ $(RM) -r 'trash directory'.* '$(TEST_RESULTS_DIRECTORY_SQ)'
45
+ $(RM) -r valgrind/bin
46
+
47
+ clean: clean-except-prove-cache
48
+ $(RM) .prove
49
+
50
+ test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax
51
+
52
+ test-lint-duplicates:
53
+ @dups=`echo $(T) | tr ' ' '\n' | sed 's/-.*//' | sort | uniq -d` && \
54
+ test -z "$$dups" || { \
55
+ echo >&2 "duplicate test numbers:" $$dups; exit 1; }
56
+
57
+ test-lint-executable:
58
+ @bad=`for i in $(T); do test -x "$$i" || echo $$i; done` && \
59
+ test -z "$$bad" || { \
60
+ echo >&2 "non-executable tests:" $$bad; exit 1; }
61
+
62
+ test-lint-shell-syntax:
63
+ @'$(PERL_PATH_SQ)' check-non-portable-shell.pl $(T)
64
+
65
+ aggregate-results-and-cleanup: $(T)
66
+ $(MAKE) aggregate-results
67
+ $(MAKE) clean
68
+
69
+ aggregate-results:
70
+ for f in '$(TEST_RESULTS_DIRECTORY_SQ)'/t*-*.counts; do \
71
+ echo "$$f"; \
72
+ done | '$(SHELL_PATH_SQ)' ./aggregate-results.sh
73
+
74
+ valgrind:
75
+ $(MAKE) GIT_TEST_OPTS="$(GIT_TEST_OPTS) --valgrind"
76
+
77
+ perf:
78
+ $(MAKE) -C perf/ all
79
+
80
+ .PHONY: pre-clean $(T) aggregate-results clean valgrind perf
data/t/README ADDED
@@ -0,0 +1,3 @@
1
+ Run unit test at spec/, and run integrate test at here.
2
+
3
+ This integrate test framework are from git.git, and designed by Junio C Hamano.
@@ -0,0 +1,46 @@
1
+ #!/bin/sh
2
+
3
+ failed_tests=
4
+ fixed=0
5
+ success=0
6
+ failed=0
7
+ broken=0
8
+ total=0
9
+
10
+ while read file
11
+ do
12
+ while read type value
13
+ do
14
+ case $type in
15
+ '')
16
+ continue ;;
17
+ fixed)
18
+ fixed=$(($fixed + $value)) ;;
19
+ success)
20
+ success=$(($success + $value)) ;;
21
+ failed)
22
+ failed=$(($failed + $value))
23
+ if test $value != 0
24
+ then
25
+ testnum=$(expr "$file" : 'test-results/\(t[0-9]*\)-')
26
+ failed_tests="$failed_tests $testnum"
27
+ fi
28
+ ;;
29
+ broken)
30
+ broken=$(($broken + $value)) ;;
31
+ total)
32
+ total=$(($total + $value)) ;;
33
+ esac
34
+ done <"$file"
35
+ done
36
+
37
+ if test -n "$failed_tests"
38
+ then
39
+ printf "\nfailed test(s):$failed_tests\n\n"
40
+ fi
41
+
42
+ printf "%-8s%d\n" fixed $fixed
43
+ printf "%-8s%d\n" success $success
44
+ printf "%-8s%d\n" failed $failed
45
+ printf "%-8s%d\n" broken $broken
46
+ printf "%-8s%d\n" total $total
@@ -0,0 +1,297 @@
1
+ #!/bin/sh
2
+ #
3
+ # Copyright (c) 2013 Jiang Xin
4
+ #
5
+
6
+ test_description='patch file test'
7
+
8
+ . ./test-lib.sh
9
+
10
+ ############################################################
11
+
12
+ cat > diff <<EOF
13
+ diff -u a/foo b/foo
14
+ --- a/foo 2013-11-04 16:01:56.000000000 +0800
15
+ +++ b/foo 2013-11-04 16:01:59.000000000 +0800
16
+ @@ add two lines
17
+ +bar
18
+ +baz
19
+ EOF
20
+
21
+ cat > expect <<EOF
22
+ bar
23
+ baz
24
+ EOF
25
+
26
+ test_expect_success 'patch newfile' '
27
+ touch ! -f actual &&
28
+ touch actual &&
29
+ rpatch -p1 actual < diff &&
30
+ test_cmp expect actual
31
+ '
32
+
33
+ ############################################################
34
+
35
+ cat > expect_errlog <<EOF
36
+ Patched "actual".
37
+ actual: Hunk 1 (add two lines) is already patched.
38
+ actual: nothing changed
39
+ EOF
40
+
41
+ test_expect_success 'patch newfile (2nd)' '
42
+ rm actual &&
43
+ touch actual &&
44
+ rpatch actual < diff 2> actual_errlog &&
45
+ rpatch actual < diff 2>>actual_errlog &&
46
+ test_cmp expect actual &&
47
+ test_cmp expect_errlog actual_errlog
48
+ '
49
+
50
+ ############################################################
51
+
52
+ cat > orig <<EOF
53
+ bar
54
+ baz
55
+ EOF
56
+
57
+ cat > diff <<EOF
58
+ diff -u a/foo b/foo
59
+ --- a/foo 2013-11-04 16:01:56.000000000 +0800
60
+ +++ b/foo 2013-11-04 16:01:59.000000000 +0800
61
+ @@ insert heading
62
+ +Insert at the beginning
63
+ @@ add/remove
64
+ bar
65
+ -baz
66
+ +foo
67
+ @@ insert footer
68
+ foo
69
+ +end of text
70
+ EOF
71
+
72
+ cat > expect <<EOF
73
+ Insert at the beginning
74
+ bar
75
+ foo
76
+ end of text
77
+ EOF
78
+
79
+ test_expect_success 'patch add/remote contents' '
80
+ cp orig actual &&
81
+ rpatch actual < diff &&
82
+ test_cmp expect actual
83
+ '
84
+
85
+ ############################################################
86
+
87
+ cat > expect_errlog <<EOF
88
+ actual: Hunk 1 (insert heading) is already patched.
89
+ actual: Hunk 2 (add/remove) is already patched.
90
+ actual: Hunk 3 (insert footer) is already patched.
91
+ actual: nothing changed
92
+ EOF
93
+
94
+ test_expect_success 'patch add/remote contents (2nd)' '
95
+ rpatch actual < diff 2>actual_errlog &&
96
+ test_cmp expect actual &&
97
+ test_cmp expect_errlog actual_errlog
98
+ '
99
+
100
+ ############################################################
101
+
102
+ cat > diff <<EOF
103
+ diff -u a/foo b/foo
104
+ --- a/foo 2013-11-04 16:01:56.000000000 +0800
105
+ +++ b/foo 2013-11-04 16:01:59.000000000 +0800
106
+ @@ delete all
107
+ -Insert at the beginning
108
+ -bar
109
+ -foo
110
+ -end of text
111
+ EOF
112
+
113
+ cat > expect_errlog <<EOF
114
+ Remove "actual".
115
+ EOF
116
+
117
+ test_expect_success 'patch to rm file' '
118
+ rpatch -p1 actual < diff 2> actual_errlog &&
119
+ test ! -f actual &&
120
+ test_cmp expect_errlog actual_errlog
121
+ '
122
+
123
+ ############################################################
124
+
125
+ cat > expect_errlog <<EOF
126
+ actual: Hunk 1 (delete all) is already patched.
127
+ actual: nothing changed
128
+ EOF
129
+
130
+ test_expect_success 'patch to rm file (2nd)' '
131
+ touch actual &&
132
+ rpatch -p1 actual < diff 2> actual_errlog &&
133
+ test -z "$(cat actual)" &&
134
+ test_cmp expect_errlog actual_errlog
135
+ '
136
+
137
+ ############################################################
138
+
139
+ cat > orig <<EOF
140
+ FOO
141
+ bAr
142
+ baz
143
+ EOF
144
+
145
+ cat > diff <<EOF
146
+ diff -u a/foo b/foo
147
+ --- a/foo 2013-11-04 16:01:56.000000000 +0800
148
+ +++ b/foo 2013-11-04 16:01:59.000000000 +0800
149
+ @@ remove bAr
150
+ RE: ^[\\s]+(foo|FOO)\$
151
+ RE:-[bB][aA][rR]
152
+ +bar
153
+ @@ mixed
154
+ RE: baz
155
+ +end of text
156
+ EOF
157
+
158
+ cat > expect <<EOF
159
+ FOO
160
+ bar
161
+ baz
162
+ end of text
163
+ EOF
164
+
165
+ cat > expect_errlog <<EOF
166
+ Patched "actual".
167
+ EOF
168
+
169
+ test_expect_success 'use regexp in patch' '
170
+ cp orig actual &&
171
+ rpatch actual < diff 2> actual_errlog &&
172
+ test_cmp expect actual &&
173
+ test_cmp expect_errlog actual_errlog
174
+ '
175
+
176
+ ############################################################
177
+
178
+ cat > expect_errlog <<EOF
179
+ actual: Hunk 1 (remove bAr) is already patched.
180
+ actual: Hunk 2 (mixed) is already patched.
181
+ actual: nothing changed
182
+ EOF
183
+
184
+ test_expect_success 'use regexp in patch (2nd)' '
185
+ rpatch actual < diff 2> actual_errlog &&
186
+ test_cmp expect actual &&
187
+ test_cmp expect_errlog actual_errlog
188
+ '
189
+
190
+ ############################################################
191
+
192
+ cat > diff <<EOF
193
+ diff -u a/foo b/foo
194
+ --- a/foo 2013-11-04 16:01:56.000000000 +0800
195
+ +++ b/foo 2013-11-04 16:01:59.000000000 +0800
196
+ @@ add two lines
197
+ +bar
198
+ +baz
199
+ trash text
200
+ EOF
201
+
202
+ cat > expect_errlog <<EOF
203
+ Error: Line 6 of patch "<IO>" is invalid.
204
+ => "trash text"
205
+ EOF
206
+
207
+ test_expect_success 'patch load fail: bad syntax' '
208
+ rm actual &&
209
+ touch actual &&
210
+ test_must_fail rpatch actual < diff 2> actual_errlog &&
211
+ test_cmp expect_errlog actual_errlog
212
+ '
213
+
214
+ ############################################################
215
+
216
+ cat > orig <<EOF
217
+ foo
218
+ EOF
219
+
220
+ cat > diff <<EOF
221
+ diff -u a/foo b/foo
222
+ --- a/foo 2013-11-04 16:01:56.000000000 +0800
223
+ +++ b/foo 2013-11-04 16:01:59.000000000 +0800
224
+ @@ insert one
225
+ bar
226
+ +baz
227
+ EOF
228
+
229
+ cat > expect_errlog <<EOF
230
+ ERROR: actual: Hunk 1 (insert one) FAILED to apply. Match failed.
231
+ actual: nothing changed
232
+ EOF
233
+
234
+ test_expect_success 'patch apply fail' '
235
+ cp orig actual &&
236
+ test_must_fail rpatch actual < diff 2> actual_errlog &&
237
+ test_cmp expect_errlog actual_errlog
238
+ '
239
+
240
+ ############################################################
241
+
242
+ cat > orig <<EOF
243
+ foo
244
+ EOF
245
+
246
+ cat > diff <<EOF
247
+ diff -u a/foo b/foo
248
+ --- a/foo 2013-11-04 16:01:56.000000000 +0800
249
+ +++ b/foo 2013-11-04 16:01:59.000000000 +0800
250
+ @@ add header
251
+ +# header...
252
+ foo
253
+ @@ add footer
254
+ baz
255
+ +footer...
256
+ EOF
257
+
258
+ cat > expect <<EOF
259
+ # header...
260
+ foo
261
+ EOF
262
+
263
+ cat > expect_errlog <<EOF
264
+ ERROR: actual: Hunk 2 (add footer) FAILED to apply. Match failed.
265
+ Warning: saved orignal file as "actual.orig".
266
+ Patched "actual".
267
+ EOF
268
+
269
+ test_expect_success 'partial patch success' '
270
+ cp orig actual &&
271
+ test ! -f actual.orig &&
272
+ test_must_fail rpatch actual < diff 2> actual_errlog &&
273
+ test -f actual.orig &&
274
+ test_cmp actual.orig orig &&
275
+ test_cmp actual expect &&
276
+ test_cmp expect_errlog actual_errlog
277
+ '
278
+
279
+ ############################################################
280
+
281
+ cat > expect_errlog <<EOF
282
+ actual: Hunk 1 (add header) is already patched.
283
+ ERROR: actual: Hunk 2 (add footer) FAILED to apply. Match failed.
284
+ actual: nothing changed
285
+ EOF
286
+
287
+ test_expect_success 'partial patch success (2nd)' '
288
+ test_must_fail rpatch actual < diff 2> actual_errlog &&
289
+ test -f actual.orig &&
290
+ test_cmp actual.orig orig &&
291
+ test_cmp actual expect &&
292
+ test_cmp expect_errlog actual_errlog
293
+ '
294
+
295
+ ############################################################
296
+
297
+ test_done