1#!/usr/bin/perl -w
2#
3# Copyright (C) 2011 Research In Motion Limited. All rights reserved.
4#
5# This library is free software; you can redistribute it and/or
6# modify it under the terms of the GNU Lesser General Public
7# License as published by the Free Software Foundation; either
8# version 2.1 of the License, or (at your option) any later version.
9#
10# This library 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 GNU
13# Lesser General Public License for more details.
14#
15# You should have received a copy of the GNU Lesser General Public
16# License along with this library; if not, write to the Free Software
17# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18
19# Unit tests of parseDiff() with mock files; test override of patch EOL with EOL of target file.
20
21use strict;
22use warnings;
23
24use File::Temp;
25use POSIX qw/getcwd/;
26use Test::More;
27use VCSUtils;
28
29my $gitDiffHeaderForNewFile = <<EOF;
30diff --git a/Makefile b/Makefile
31new file mode 100644
32index 0000000..756e864
33--- /dev/null
34+++ b/Makefile
35@@ -0,0 +1,17 @@
36EOF
37
38my $gitDiffHeader = <<EOF;
39diff --git a/Makefile b/Makefile
40index 756e864..04d2ae1 100644
41--- a/Makefile
42+++ b/Makefile
43@@ -1,3 +1,4 @@
44EOF
45
46my $svnConvertedGitDiffHeader = <<EOF;
47Index: Makefile
48index 756e864..04d2ae1 100644
49--- Makefile
50+++ Makefile
51@@ -1,3 +1,4 @@
52EOF
53
54my $svnConvertedGitDiffHeaderForNewFile = <<EOF;
55Index: Makefile
56new file mode 100644
57index 0000000..756e864
58--- Makefile
59+++ Makefile
60@@ -0,0 +1,17 @@
61EOF
62
63my $svnDiffHeaderForNewFile = <<EOF;
64Index: Makefile
65===================================================================
66--- Makefile	(revision 0)
67+++ Makefile	(revision 0)
68@@ -0,0 +1,17 @@
69EOF
70
71my $svnDiffHeader = <<EOF;
72Index: Makefile
73===================================================================
74--- Makefile	(revision 53052)
75+++ Makefile	(working copy)
76@@ -1,3 +1,4 @@
77EOF
78
79my $diffBody = <<EOF;
80+
81 MODULES = JavaScriptCore JavaScriptGlue WebCore WebKit WebKitTools
82
83 all:
84EOF
85
86my $MakefileContents = <<EOF;
87MODULES = JavaScriptCore JavaScriptGlue WebCore WebKit WebKitTools
88
89all:
90EOF
91
92my $mockDir = File::Temp->tempdir("parseDiffXXXX", CLEANUP => 1);
93writeToFile(File::Spec->catfile($mockDir, "MakefileWithUnixEOL"), $MakefileContents);
94writeToFile(File::Spec->catfile($mockDir, "MakefileWithWindowsEOL"), toWindowsLineEndings($MakefileContents));
95
96# The array of test cases.
97my @testCaseHashRefs = (
98###
99# SVN test cases
100##
101{
102    # New test
103    diffName => "SVN: Patch with Unix line endings and IndexPath has Unix line endings",
104    inputText => substituteString($svnDiffHeader, "Makefile", "MakefileWithUnixEOL") . $diffBody,
105    expectedReturn => [
106[{
107    svnConvertedText => substituteString($svnDiffHeader, "Makefile", "MakefileWithUnixEOL") . $diffBody, # Same as input text
108    indexPath => "MakefileWithUnixEOL",
109    isSvn => 1,
110    sourceRevision => "53052",
111}],
112undef],
113    expectedNextLine => undef,
114},
115{
116    # New test
117    diffName => "SVN: Patch with Windows line endings and IndexPath has Unix line endings",
118    inputText => substituteString($svnDiffHeader, "Makefile", "MakefileWithUnixEOL") . toWindowsLineEndings($diffBody),
119    expectedReturn => [
120[{
121    svnConvertedText => substituteString($svnDiffHeader, "Makefile", "MakefileWithUnixEOL") . $diffBody,
122    indexPath => "MakefileWithUnixEOL",
123    isSvn => 1,
124    sourceRevision => "53052",
125}],
126undef],
127    expectedNextLine => undef,
128},
129{
130    # New test
131    diffName => "SVN: Patch with Windows line endings and IndexPath has Windows line endings",
132    inputText => substituteString($svnDiffHeader, "Makefile", "MakefileWithWindowsEOL") . toWindowsLineEndings($diffBody),
133    expectedReturn => [
134[{
135    svnConvertedText => substituteString($svnDiffHeader, "Makefile", "MakefileWithWindowsEOL") . toWindowsLineEndings($diffBody), # Same as input text
136    indexPath => "MakefileWithWindowsEOL",
137    isSvn => 1,
138    sourceRevision => "53052",
139}],
140undef],
141    expectedNextLine => undef,
142},
143{
144    # New test
145    diffName => "SVN: Patch with Unix line endings and IndexPath has Windows line endings",
146    inputText => substituteString($svnDiffHeader, "Makefile", "MakefileWithWindowsEOL") . $diffBody,
147    expectedReturn => [
148[{
149    svnConvertedText => substituteString($svnDiffHeader, "Makefile", "MakefileWithWindowsEOL") . toWindowsLineEndings($diffBody),
150    indexPath => "MakefileWithWindowsEOL",
151    isSvn => 1,
152    sourceRevision => "53052",
153}],
154undef],
155    expectedNextLine => undef,
156},
157{
158    # New test
159    diffName => "SVN: Patch with Unix line endings and nonexistent IndexPath",
160    inputText => substituteString($svnDiffHeaderForNewFile, "Makefile", "NonexistentFile") . $diffBody,
161    expectedReturn => [
162[{
163    svnConvertedText => substituteString($svnDiffHeaderForNewFile, "Makefile", "NonexistentFile") . $diffBody, # Same as input text
164    indexPath => "NonexistentFile",
165    isSvn => 1,
166    isNew => 1,
167}],
168undef],
169    expectedNextLine => undef,
170},
171{
172    # New test
173    diffName => "SVN: Patch with Windows line endings and nonexistent IndexPath",
174    inputText => substituteString($svnDiffHeaderForNewFile, "Makefile", "NonexistentFile") . toWindowsLineEndings($diffBody),
175    expectedReturn => [
176[{
177    svnConvertedText => substituteString($svnDiffHeaderForNewFile, "Makefile", "NonexistentFile") . toWindowsLineEndings($diffBody), # Same as input text
178    indexPath => "NonexistentFile",
179    isSvn => 1,
180    isNew => 1,
181}],
182undef],
183    expectedNextLine => undef,
184},
185###
186# Git test cases
187##
188{
189    # New test
190    diffName => "Git: Patch with Unix line endings and IndexPath has Unix line endings",
191    inputText => substituteString($gitDiffHeader, "Makefile", "MakefileWithUnixEOL") . $diffBody,
192    expectedReturn => [
193[{
194    svnConvertedText => substituteString($svnConvertedGitDiffHeader, "Makefile", "MakefileWithUnixEOL") . $diffBody, # Same as input text
195    indexPath => "MakefileWithUnixEOL",
196    isGit => 1,
197}],
198undef],
199    expectedNextLine => undef,
200},
201{
202    # New test
203    diffName => "Git: Patch with Windows line endings and IndexPath has Unix line endings",
204    inputText => substituteString($gitDiffHeader, "Makefile", "MakefileWithUnixEOL") . toWindowsLineEndings($diffBody),
205    expectedReturn => [
206[{
207    svnConvertedText => substituteString($svnConvertedGitDiffHeader, "Makefile", "MakefileWithUnixEOL") . $diffBody,
208    indexPath => "MakefileWithUnixEOL",
209    isGit => 1,
210}],
211undef],
212    expectedNextLine => undef,
213},
214{
215    # New test
216    diffName => "Git: Patch with Windows line endings and IndexPath has Windows line endings",
217    inputText => substituteString($gitDiffHeader, "Makefile", "MakefileWithWindowsEOL") . toWindowsLineEndings($diffBody),
218    expectedReturn => [
219[{
220    svnConvertedText => substituteString($svnConvertedGitDiffHeader, "Makefile", "MakefileWithWindowsEOL") . toWindowsLineEndings($diffBody), # Same as input text
221    indexPath => "MakefileWithWindowsEOL",
222    isGit => 1,
223}],
224undef],
225    expectedNextLine => undef,
226},
227{
228    # New test
229    diffName => "Git: Patch with Unix line endings and IndexPath has Windows line endings",
230    inputText => substituteString($gitDiffHeader, "Makefile", "MakefileWithWindowsEOL") . $diffBody,
231    expectedReturn => [
232[{
233    svnConvertedText => substituteString($svnConvertedGitDiffHeader, "Makefile", "MakefileWithWindowsEOL") . toWindowsLineEndings($diffBody),
234    indexPath => "MakefileWithWindowsEOL",
235    isGit => 1,
236}],
237undef],
238    expectedNextLine => undef,
239},
240{
241    # New test
242    diffName => "Git: Patch with Unix line endings and nonexistent IndexPath",
243    inputText => substituteString($gitDiffHeaderForNewFile, "Makefile", "NonexistentFile") . $diffBody,
244    expectedReturn => [
245[{
246    svnConvertedText => substituteString($svnConvertedGitDiffHeaderForNewFile, "Makefile", "NonexistentFile") . $diffBody, # Same as input text
247    indexPath => "NonexistentFile",
248    isGit => 1,
249    isNew => 1,
250}],
251undef],
252    expectedNextLine => undef,
253},
254{
255    # New test
256    diffName => "Git: Patch with Windows line endings and nonexistent IndexPath",
257    inputText => substituteString($gitDiffHeaderForNewFile, "Makefile", "NonexistentFile") . toWindowsLineEndings($diffBody),
258    expectedReturn => [
259[{
260    svnConvertedText => substituteString($svnConvertedGitDiffHeaderForNewFile, "Makefile", "NonexistentFile") . toWindowsLineEndings($diffBody), # Same as input text
261    indexPath => "NonexistentFile",
262    isGit => 1,
263    isNew => 1,
264}],
265undef],
266    expectedNextLine => undef,
267},
268);
269
270my $testCasesCount = @testCaseHashRefs;
271plan(tests => 2 * $testCasesCount); # Total number of assertions.
272
273my $savedCWD = getcwd();
274chdir($mockDir) or die;
275foreach my $testCase (@testCaseHashRefs) {
276    my $testNameStart = "parseDiff(): $testCase->{diffName}: comparing";
277
278    my $fileHandle;
279    open($fileHandle, "<", \$testCase->{inputText});
280    my $line = <$fileHandle>;
281
282    my @got = VCSUtils::parseDiff($fileHandle, $line);
283    my $expectedReturn = $testCase->{expectedReturn};
284
285    is_deeply(\@got, $expectedReturn, "$testNameStart return value.");
286
287    my $gotNextLine = <$fileHandle>;
288    is($gotNextLine, $testCase->{expectedNextLine},  "$testNameStart next read line.");
289}
290chdir($savedCWD);
291
292sub substituteString
293{
294    my ($string, $searchString, $replacementString) = @_;
295    $string =~ s/$searchString/$replacementString/g;
296    return $string;
297}
298
299sub writeToFile
300{
301    my ($file, $text) = @_;
302    open(FILE, ">$file") or die;
303    print FILE $text;
304    close(FILE);
305}
306