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# Copyright (C) 2012 Daniel Bates (dbates@intudata.com)
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions are
9# met:
10#
11#     * Redistributions of source code must retain the above copyright
12# notice, this list of conditions and the following disclaimer.
13#     * Redistributions in binary form must reproduce the above
14# copyright notice, this list of conditions and the following disclaimer
15# in the documentation and/or other materials provided with the
16# distribution.
17#     * Neither the name of Apple Computer, Inc. ("Apple") nor the names of
18# its contributors may be used to endorse or promote products derived
19# from this software without specific prior written permission.
20#
21# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33# Unit tests of parseSvnPropertyValue().
34
35use strict;
36use warnings;
37
38use Test::More;
39use VCSUtils;
40
41my @testCaseHashRefs = (
42{
43    # New test
44    diffName => "singe-line '+' change",
45    inputText => <<'END',
46   + *
47END
48    expectedReturn => ["*", undef],
49    expectedNextLine => undef,
50},
51{
52    # New test
53    diffName => "single-line '-' change",
54    inputText => <<'END',
55   - *
56END
57    expectedReturn => ["*", undef],
58    expectedNextLine => undef,
59},
60{
61    # New test
62    diffName => "'Merged' change",
63    inputText => <<'END',
64   Merged /trunk/Makefile:r33020
65END
66    expectedReturn => ["/trunk/Makefile:r33020", undef],
67    expectedNextLine => undef,
68},
69{
70    # New test
71    diffName => "'Reverse-merged' change",
72    inputText => <<'END',
73   Reverse-merged /trunk/Makefile:r33020
74END
75    expectedReturn => ["/trunk/Makefile:r33020", undef],
76    expectedNextLine => undef,
77},
78{
79    # New test
80    diffName => "single-line '-' change followed by empty line with Unix line endings",
81    inputText => <<'END',
82   - *
83
84END
85    expectedReturn => ["*", "\n"],
86    expectedNextLine => undef,
87},
88{
89    # New test
90    diffName => "single-line '-' change followed by empty line with Windows line endings",
91    inputText => toWindowsLineEndings(<<'END',
92   - *
93
94END
95),
96    expectedReturn => ["*", "\r\n"],
97    expectedNextLine => undef,
98},
99{
100    # New test
101    diffName => "single-line '-' change followed by the next property",
102    inputText => <<'END',
103   - *
104Deleted: svn:executable
105END
106    expectedReturn => ["*", "Deleted: svn:executable\n"],
107    expectedNextLine => undef,
108},
109{
110    # New test
111    diffName => "multi-line '+' change and start of binary patch",
112    inputText => <<'END',
113   + A
114long sentence that spans
115multiple lines.
116
117Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==
118END
119    expectedReturn => ["A\nlong sentence that spans\nmultiple lines.", "\n"],
120    expectedNextLine => "Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==\n",
121},
122{
123    # New test
124    diffName => "multi-line '+' change and start of binary patch with Windows line endings",
125    inputText => toWindowsLineEndings(<<'END',
126   + A
127long sentence that spans
128multiple lines.
129
130Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==
131END
132),
133    expectedReturn => ["A\r\nlong sentence that spans\r\nmultiple lines.", "\r\n"],
134    expectedNextLine => "Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==\r\n",
135},
136{
137    # New test
138    diffName => "multi-line '-' change followed by '+' single-line change",
139    inputText => <<'END',
140   - A
141long sentence that spans
142multiple lines.
143   + A single-line.
144END
145    expectedReturn => ["A\nlong sentence that spans\nmultiple lines.", "   + A single-line.\n"],
146    expectedNextLine => undef,
147},
148{
149    # New test
150    diffName => "multi-line '-' change followed by the next property",
151    inputText => <<'END',
152   - A
153long sentence that spans
154multiple lines.
155Added: svn:executable
156END
157    expectedReturn => ["A\nlong sentence that spans\nmultiple lines.", "Added: svn:executable\n"],
158    expectedNextLine => undef,
159},
160{
161    # New test
162    diffName => "multi-line '-' change followed by '+' multi-line change",
163    inputText => <<'END',
164   - A
165long sentence that spans
166multiple lines.
167   + Another
168long sentence that spans
169multiple lines.
170END
171    expectedReturn => ["A\nlong sentence that spans\nmultiple lines.", "   + Another\n"],
172    expectedNextLine => "long sentence that spans\n",
173},
174{
175    # New test
176    diffName => "'Reverse-merged' change followed by 'Merge' change",
177    inputText => <<'END',
178   Reverse-merged /trunk/Makefile:r33020
179   Merged /trunk/Makefile:r41697
180END
181    expectedReturn => ["/trunk/Makefile:r33020", "   Merged /trunk/Makefile:r41697\n"],
182    expectedNextLine => undef,
183},
184{
185    # New test
186    diffName => "'Merged' change followed by 'Merge' change",
187    inputText => <<'END',
188   Merged /trunk/Makefile:r33020
189   Merged /trunk/Makefile.shared:r58350
190END
191    expectedReturn => ["/trunk/Makefile:r33020", "   Merged /trunk/Makefile.shared:r58350\n"],
192    expectedNextLine => undef,
193},
194{
195    # New test
196    diffName => "'Reverse-merged' change followed by 'Reverse-merged' change",
197    inputText => <<'END',
198   Reverse-merged /trunk/Makefile:r33020
199   Reverse-merged /trunk/Makefile.shared:r58350
200END
201    expectedReturn => ["/trunk/Makefile:r33020", "   Reverse-merged /trunk/Makefile.shared:r58350\n"],
202    expectedNextLine => undef,
203},
204{
205    # New test
206    diffName => "'Reverse-merged' change followed by 'Reverse-merged' change followed by 'Merged' change",
207    inputText => <<'END',
208   Reverse-merged /trunk/Makefile:r33020
209   Reverse-merged /trunk/Makefile.shared:r58350
210   Merged /trunk/ChangeLog:r64190
211END
212    expectedReturn => ["/trunk/Makefile:r33020", "   Reverse-merged /trunk/Makefile.shared:r58350\n"],
213    expectedNextLine => "   Merged /trunk/ChangeLog:r64190\n",
214},
215##
216# Using SVN 1.7 syntax
217##
218{
219    # New test
220    diffName => "singe-line '+' change using SVN 1.7 syntax",
221    inputText => <<'END',
222+*
223\ No newline at end of property
224END
225    expectedReturn => ["*", "\\ No newline at end of property\n"],
226    expectedNextLine => undef,
227},
228{
229    # New test
230    diffName => "single-line '-' change using SVN 1.7 syntax",
231    inputText => <<'END',
232-*
233\ No newline at end of property
234END
235    expectedReturn => ["*", "\\ No newline at end of property\n"],
236    expectedNextLine => undef,
237},
238);
239
240my $testCasesCount = @testCaseHashRefs;
241plan(tests => 2 * $testCasesCount); # Total number of assertions.
242
243foreach my $testCase (@testCaseHashRefs) {
244    my $testNameStart = "parseSvnPropertyValue(): $testCase->{diffName}: comparing";
245
246    my $fileHandle;
247    open($fileHandle, "<", \$testCase->{inputText});
248    my $line = <$fileHandle>;
249
250    my @got = VCSUtils::parseSvnPropertyValue($fileHandle, $line);
251    my $expectedReturn = $testCase->{expectedReturn};
252
253    is_deeply(\@got, $expectedReturn, "$testNameStart return value.");
254
255    my $gotNextLine = <$fileHandle>;
256    is($gotNextLine, $testCase->{expectedNextLine},  "$testNameStart next read line.");
257}
258