initial import
[vuplus_webkit] / Tools / Scripts / webkitperl / VCSUtils_unittest / parseSvnProperty.pl
1 #!/usr/bin/perl -w
2 #
3 # Copyright (C) Research in Motion Limited 2010. All Rights Reserved.
4 # Copyright (C) 2010 Chris Jerdonek (chris.jerdonek@gmail.com)
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions are
8 # met:
9 #
10 #     * Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 #     * Redistributions in binary form must reproduce the above
13 # copyright notice, this list of conditions and the following disclaimer
14 # in the documentation and/or other materials provided with the
15 # distribution.
16 #     * Neither the name of Apple Computer, Inc. ("Apple") nor the names of
17 # its contributors may be used to endorse or promote products derived
18 # from this software without specific prior written permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32 # Unit tests of parseSvnProperty().
33
34 use strict;
35 use warnings;
36
37 use Test::More;
38 use VCSUtils;
39
40 my @testCaseHashRefs = (
41 ####
42 # Simple test cases
43 ##
44 {
45     # New test
46     diffName => "simple: add svn:executable",
47     inputText => <<'END',
48 Added: svn:executable
49    + *
50 END
51     expectedReturn => [
52 {
53     name => "svn:executable",
54     propertyChangeDelta => 1,
55     value => "*",
56 },
57 undef],
58     expectedNextLine => undef,
59 },
60 {
61     # New test
62     diffName => "simple: delete svn:executable",
63     inputText => <<'END',
64 Deleted: svn:executable
65    - *
66 END
67     expectedReturn => [
68 {
69     name => "svn:executable",
70     propertyChangeDelta => -1,
71     value => "*",
72 },
73 undef],
74     expectedNextLine => undef,
75 },
76 {
77     # New test
78     diffName => "simple: add svn:mergeinfo",
79     inputText => <<'END',
80 Added: svn:mergeinfo
81    Merged /trunk/Makefile:r33020
82 END
83     expectedReturn => [
84 {
85     name => "svn:mergeinfo",
86     propertyChangeDelta => 1,
87     value => "/trunk/Makefile:r33020",
88 },
89 undef],
90     expectedNextLine => undef,
91 },
92 {
93     # New test
94     diffName => "simple: delete svn:mergeinfo",
95     inputText => <<'END',
96 Deleted: svn:mergeinfo
97    Reverse-merged /trunk/Makefile:r33020
98 END
99     expectedReturn => [
100 {
101     name => "svn:mergeinfo",
102     propertyChangeDelta => -1,
103     value => "/trunk/Makefile:r33020",
104 },
105 undef],
106     expectedNextLine => undef,
107 },
108 {
109     # New test
110     diffName => "simple: modified svn:mergeinfo",
111     inputText => <<'END',
112 Modified: svn:mergeinfo
113    Reverse-merged /trunk/Makefile:r33020
114    Merged /trunk/Makefile:r41697
115 END
116     expectedReturn => [
117 {
118     name => "svn:mergeinfo",
119     propertyChangeDelta => 1,
120     value => "/trunk/Makefile:r41697",
121 },
122 undef],
123     expectedNextLine => undef,
124 },
125 ####
126 # Using SVN 1.4 syntax
127 ##
128 {
129     # New test
130     diffName => "simple: modified svn:mergeinfo using SVN 1.4 syntax",
131     inputText => <<'END',
132 Name: svn:mergeinfo
133    Reverse-merged /trunk/Makefile:r33020
134    Merged /trunk/Makefile:r41697
135 END
136     expectedReturn => [
137 {
138     name => "svn:mergeinfo",
139     propertyChangeDelta => 1,
140     value => "/trunk/Makefile:r41697",
141 },
142 undef],
143     expectedNextLine => undef,
144 },
145 {
146     # New test
147     diffName => "simple: delete svn:executable using SVN 1.4 syntax",
148     inputText => <<'END',
149 Name: svn:executable
150    - *
151 END
152     expectedReturn => [
153 {
154     name => "svn:executable",
155     propertyChangeDelta => -1,
156     value => "*",
157 },
158 undef],
159     expectedNextLine => undef,
160 },
161 {
162     # New test
163     diffName => "simple: add svn:executable using SVN 1.4 syntax",
164     inputText => <<'END',
165 Name: svn:executable
166    + *
167 END
168     expectedReturn => [
169 {
170     name => "svn:executable",
171     propertyChangeDelta => 1,
172     value => "*",
173 },
174 undef],
175     expectedNextLine => undef,
176 },
177 ####
178 # Property value followed by empty line and start of next diff
179 ##
180 {
181     # New test
182     diffName => "add svn:executable, followed by empty line and start of next diff",
183     inputText => <<'END',
184 Added: svn:executable
185    + *
186
187 Index: Makefile.shared
188 END
189     expectedReturn => [
190 {
191     name => "svn:executable",
192     propertyChangeDelta => 1,
193     value => "*",
194 },
195 "\n"],
196     expectedNextLine => "Index: Makefile.shared\n",
197 },
198 {
199     # New test
200     diffName => "add svn:executable, followed by empty line and start of next diff using Windows line endings",
201     inputText => toWindowsLineEndings(<<'END',
202 Added: svn:executable
203    + *
204
205 Index: Makefile.shared
206 END
207 ),
208     expectedReturn => [
209 {
210     name => "svn:executable",
211     propertyChangeDelta => 1,
212     value => "*",
213 },
214 "\r\n"],
215     expectedNextLine => "Index: Makefile.shared\r\n",
216 },
217 {
218     # New test
219     diffName => "add svn:executable, followed by empty line and start of next property diff",
220     inputText => <<'END',
221 Added: svn:executable
222    + *
223
224 Property changes on: Makefile.shared
225 END
226     expectedReturn => [
227 {
228     name => "svn:executable",
229     propertyChangeDelta => 1,
230     value => "*",
231 },
232 "\n"],
233     expectedNextLine => "Property changes on: Makefile.shared\n",
234 },
235 {
236     # New test
237     diffName => "add svn:executable, followed by empty line and start of next property diff using Windows line endings",
238     inputText => toWindowsLineEndings(<<'END',
239 Added: svn:executable
240    + *
241
242 Property changes on: Makefile.shared
243 END
244 ),
245     expectedReturn => [
246 {
247     name => "svn:executable",
248     propertyChangeDelta => 1,
249     value => "*",
250 },
251 "\r\n"],
252     expectedNextLine => "Property changes on: Makefile.shared\r\n",
253 },
254 {
255     # New test
256     diffName => "multi-line '+' change, followed by empty line and start of next diff",
257     inputText => <<'END',
258 Name: documentation
259    + A
260 long sentence that spans
261 multiple lines.
262
263 Index: Makefile.shared
264 END
265     expectedReturn => [
266 {
267     name => "documentation",
268     propertyChangeDelta => 1,
269     value => "A\nlong sentence that spans\nmultiple lines.",
270 },
271 "\n"],
272     expectedNextLine => "Index: Makefile.shared\n",
273 },
274 {
275     # New test
276     diffName => "multi-line '+' change, followed by empty line and start of next diff using Windows line endings",
277     inputText => toWindowsLineEndings(<<'END',
278 Name: documentation
279    + A
280 long sentence that spans
281 multiple lines.
282
283 Index: Makefile.shared
284 END
285 ),
286     expectedReturn => [
287 {
288     name => "documentation",
289     propertyChangeDelta => 1,
290     value => "A\r\nlong sentence that spans\r\nmultiple lines.",
291 },
292 "\r\n"],
293     expectedNextLine => "Index: Makefile.shared\r\n",
294 },
295 {
296     # New test
297     diffName => "multi-line '+' change, followed by empty line and start of next property diff",
298     inputText => <<'END',
299 Name: documentation
300    + A
301 long sentence that spans
302 multiple lines.
303
304 Property changes on: Makefile.shared
305 END
306     expectedReturn => [
307 {
308     name => "documentation",
309     propertyChangeDelta => 1,
310     value => "A\nlong sentence that spans\nmultiple lines.",
311 },
312 "\n"],
313     expectedNextLine => "Property changes on: Makefile.shared\n",
314 },
315 {
316     # New test
317     diffName => "multi-line '+' change, followed by empty line and start of next property diff using Windows line endings",
318     inputText => toWindowsLineEndings(<<'END',
319 Name: documentation
320    + A
321 long sentence that spans
322 multiple lines.
323
324 Property changes on: Makefile.shared
325 END
326 ),
327     expectedReturn => [
328 {
329     name => "documentation",
330     propertyChangeDelta => 1,
331     value => "A\r\nlong sentence that spans\r\nmultiple lines.",
332 },
333 "\r\n"],
334     expectedNextLine => "Property changes on: Makefile.shared\r\n",
335 },
336 ####
337 # Property value followed by empty line and start of binary patch
338 ##
339 {
340     # New test
341     diffName => "add svn:executable, followed by empty line and start of binary patch",
342     inputText => <<'END',
343 Added: svn:executable
344    + *
345
346 Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==
347 END
348     expectedReturn => [
349 {
350     name => "svn:executable",
351     propertyChangeDelta => 1,
352     value => "*",
353 },
354 "\n"],
355     expectedNextLine => "Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==\n",
356 },
357 {
358     # New test
359     diffName => "add svn:executable, followed by empty line and start of binary patch using Windows line endings",
360     inputText => toWindowsLineEndings(<<'END',
361 Added: svn:executable
362    + *
363
364 Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==
365 END
366 ),
367     expectedReturn => [
368 {
369     name => "svn:executable",
370     propertyChangeDelta => 1,
371     value => "*",
372 },
373 "\r\n"],
374     expectedNextLine => "Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==\r\n",
375 },
376 {
377     # New test
378     diffName => "multi-line '+' change, followed by empty line and start of binary patch",
379     inputText => <<'END',
380 Name: documentation
381    + A
382 long sentence that spans
383 multiple lines.
384
385 Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==
386 END
387     expectedReturn => [
388 {
389     name => "documentation",
390     propertyChangeDelta => 1,
391     value => "A\nlong sentence that spans\nmultiple lines.",
392 },
393 "\n"],
394     expectedNextLine => "Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==\n",
395 },
396 {
397     # New test
398     diffName => "multi-line '+' change, followed by empty line and start of binary patch using Windows line endings",
399     inputText => toWindowsLineEndings(<<'END',
400 Name: documentation
401    + A
402 long sentence that spans
403 multiple lines.
404
405 Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==
406 END
407 ),
408     expectedReturn => [
409 {
410     name => "documentation",
411     propertyChangeDelta => 1,
412     value => "A\r\nlong sentence that spans\r\nmultiple lines.",
413 },
414 "\r\n"],
415     expectedNextLine => "Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==\r\n",
416 },
417 {
418     # New test
419     diffName => "multi-line '-' change, followed by multi-line '+' change, empty line, and start of binary patch",
420     inputText => <<'END',
421 Modified: documentation
422    - A
423 long sentence that spans
424 multiple lines.
425    + Another
426 long sentence that spans
427 multiple lines.
428
429 Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==
430 END
431     expectedReturn => [
432 {
433     name => "documentation",
434     propertyChangeDelta => 1,
435     value => "Another\nlong sentence that spans\nmultiple lines.",
436 },
437 "\n"],
438     expectedNextLine => "Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==\n",
439 },
440 {
441     # New test
442     diffName => "multi-line '-' change, followed by multi-line '+' change, empty line, and start of binary patch using Windows line endings",
443     inputText => toWindowsLineEndings(<<'END',
444 Modified: documentation
445    - A
446 long sentence that spans
447 multiple lines.
448    + Another
449 long sentence that spans
450 multiple lines.
451
452 Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==
453 END
454 ),
455     expectedReturn => [
456 {
457     name => "documentation",
458     propertyChangeDelta => 1,
459     value => "Another\r\nlong sentence that spans\r\nmultiple lines.",
460 },
461 "\r\n"],
462     expectedNextLine => "Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==\r\n",
463 },
464 ####
465 # Successive properties
466 ##
467 {
468     # New test
469     diffName => "single-line '+' change followed by custom property with single-line '+' change",
470     inputText => <<'END',
471 Added: svn:executable
472    + *
473 Added: documentation
474    + A sentence.
475 END
476     expectedReturn => [
477 {
478     name => "svn:executable",
479     propertyChangeDelta => 1,
480     value => "*",
481 },
482 "Added: documentation\n"],
483     expectedNextLine => "   + A sentence.\n",
484 },
485 {
486     # New test
487     diffName => "multi-line '+' change, followed by svn:executable",
488     inputText => <<'END',
489 Name: documentation
490    + A
491 long sentence that spans
492 multiple lines.
493 Name: svn:executable
494    + *
495 END
496     expectedReturn => [
497 {
498     name => "documentation",
499     propertyChangeDelta => 1,
500     value => "A\nlong sentence that spans\nmultiple lines.",
501 },
502 "Name: svn:executable\n"],
503     expectedNextLine => "   + *\n",
504 },
505 {
506     # New test
507     diffName => "multi-line '-' change, followed by multi-line '+' change and add svn:executable",
508     inputText => <<'END',
509 Modified: documentation
510    - A
511 long sentence that spans
512 multiple lines.
513    + Another
514 long sentence that spans
515 multiple lines.
516 Added: svn:executable
517    + *
518 END
519     expectedReturn => [
520 {
521     name => "documentation",
522     propertyChangeDelta => 1,
523     value => "Another\nlong sentence that spans\nmultiple lines.",
524 },
525 "Added: svn:executable\n"],
526     expectedNextLine => "   + *\n",
527 },
528 {
529     # New test
530     diffName => "'Merged' change followed by 'Merged' change",
531     inputText => <<'END',
532 Added: svn:mergeinfo
533    Merged /trunk/Makefile:r33020
534    Merged /trunk/Makefile.shared:r58350
535 END
536     expectedReturn => [
537 {
538     name => "svn:mergeinfo",
539     propertyChangeDelta => 1,
540     value => "/trunk/Makefile.shared:r58350",
541 },
542 undef],
543     expectedNextLine => undef,
544 },
545 {
546     # New test
547     diffName => "'Reverse-merged' change followed by 'Reverse-merged' change",
548     inputText => <<'END',
549 Deleted: svn:mergeinfo
550    Reverse-merged /trunk/Makefile:r33020
551    Reverse-merged /trunk/Makefile.shared:r58350
552 END
553     expectedReturn => [
554 {
555     name => "svn:mergeinfo",
556     propertyChangeDelta => -1,
557     value => "/trunk/Makefile.shared:r58350",
558 },
559 undef],
560     expectedNextLine => undef,
561 },
562 ####
563 # Property values with trailing new lines.
564 ##
565 # FIXME: We do not support property values with trailing new lines, since it is difficult to
566 #        disambiguate them from the empty line that preceeds the contents of a binary patch as
567 #        in the test case (above): "multi-line '+' change, followed by empty line and start of binary patch".
568 {
569     # New test
570     diffName => "single-line '+' with trailing new line",
571     inputText => <<'END',
572 Added: documentation
573    + A sentence.
574
575 END
576     expectedReturn => [
577 {
578     name => "documentation",
579     propertyChangeDelta => 1,
580     value => "A sentence.",
581 },
582 "\n"],
583     expectedNextLine => undef,
584 },
585 {
586     # New test
587     diffName => "single-line '+' with trailing new line using Windows line endings",
588     inputText => toWindowsLineEndings(<<'END',
589 Added: documentation
590    + A sentence.
591
592 END
593 ),
594     expectedReturn => [
595 {
596     name => "documentation",
597     propertyChangeDelta => 1,
598     value => "A sentence.",
599 },
600 "\r\n"],
601     expectedNextLine => undef,
602 },
603 {
604     # New test
605     diffName => "single-line '+' with trailing new line, followed by empty line and start of binary patch",
606     inputText => <<'END',
607 Added: documentation
608    + A sentence.
609
610
611 Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==
612 END
613     expectedReturn => [
614 {
615     name => "documentation",
616     propertyChangeDelta => 1,
617     value => "A sentence.",
618 },
619 "\n"],
620     expectedNextLine => "\n",
621 },
622 {
623     # New test
624     diffName => "single-line '+' with trailing new line, followed by empty line and start of binary patch using Windows line endings",
625     inputText => toWindowsLineEndings(<<'END',
626 Added: documentation
627    + A sentence.
628
629
630 Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==
631 END
632 ),
633     expectedReturn => [
634 {
635     name => "documentation",
636     propertyChangeDelta => 1,
637     value => "A sentence.",
638 },
639 "\r\n"],
640     expectedNextLine => "\r\n",
641 },
642 {
643     # New test
644     diffName => "single-line '-' change with trailing new line, and single-line '+' change",
645     inputText => <<'END',
646 Modified: documentation
647    - A long sentence.
648
649    + A sentence.
650 END
651     expectedReturn => [
652 {
653     name => "documentation",
654     propertyChangeDelta => -1, # Since we only interpret the '-' property.
655     value => "A long sentence.",
656 },
657 "\n"],
658     expectedNextLine => "   + A sentence.\n",
659 },
660 {
661     # New test
662     diffName => "single-line '-' change with trailing new line, and single-line '+' change using Windows line endings",
663     inputText => toWindowsLineEndings(<<'END',
664 Modified: documentation
665    - A long sentence.
666
667    + A sentence.
668 END
669 ),
670     expectedReturn => [
671 {
672     name => "documentation",
673     propertyChangeDelta => -1, # Since we only interpret the '-' property.
674     value => "A long sentence.",
675 },
676 "\r\n"],
677     expectedNextLine => "   + A sentence.\r\n",
678 },
679 {
680     # New test
681     diffName => "multi-line '-' change with trailing new line, and multi-line '+' change",
682     inputText => <<'END',
683 Modified: documentation
684    - A
685 long sentence that spans
686 multiple lines.
687
688    + Another
689 long sentence that spans
690 multiple lines.
691 END
692     expectedReturn => [
693 {
694     name => "documentation",
695     propertyChangeDelta => -1, # Since we only interpret the '-' property.
696     value => "A\nlong sentence that spans\nmultiple lines.",
697 },
698 "\n"],
699     expectedNextLine => "   + Another\n",
700 },
701 {
702     # New test
703     diffName => "multi-line '-' change with trailing new line, and multi-line '+' change using Windows line endings",
704     inputText => toWindowsLineEndings(<<'END',
705 Modified: documentation
706    - A
707 long sentence that spans
708 multiple lines.
709
710    + Another
711 long sentence that spans
712 multiple lines.
713 END
714 ),
715     expectedReturn => [
716 {
717     name => "documentation",
718     propertyChangeDelta => -1, # Since we only interpret the '-' property.
719     value => "A\r\nlong sentence that spans\r\nmultiple lines.",
720 },
721 "\r\n"],
722     expectedNextLine => "   + Another\r\n",
723 },
724 );
725
726 my $testCasesCount = @testCaseHashRefs;
727 plan(tests => 2 * $testCasesCount); # Total number of assertions.
728
729 foreach my $testCase (@testCaseHashRefs) {
730     my $testNameStart = "parseSvnProperty(): $testCase->{diffName}: comparing";
731
732     my $fileHandle;
733     open($fileHandle, "<", \$testCase->{inputText});
734     my $line = <$fileHandle>;
735
736     my @got = VCSUtils::parseSvnProperty($fileHandle, $line);
737     my $expectedReturn = $testCase->{expectedReturn};
738
739     is_deeply(\@got, $expectedReturn, "$testNameStart return value.");
740
741     my $gotNextLine = <$fileHandle>;
742     is($gotNextLine, $testCase->{expectedNextLine},  "$testNameStart next read line.");
743 }