1#!/usr/bin/perl -w 2# 3# Copyright (C) 2011 Research In Motion Limited. All rights reserved. 4# Copyright (C) 2013 Apple Inc. All rights reserved. 5# 6# This library is free software; you can redistribute it and/or 7# modify it under the terms of the GNU Lesser General Public 8# License as published by the Free Software Foundation; either 9# version 2.1 of the License, or (at your option) any later version. 10# 11# This library is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14# Lesser General Public License for more details. 15# 16# You should have received a copy of the GNU Lesser General Public 17# License along with this library; if not, write to the Free Software 18# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 20# Unit tests of parseDiff() with mock files; test override of patch EOL with EOL of target file. 21 22use strict; 23use warnings; 24 25use File::Temp; 26use POSIX qw/getcwd/; 27use Test::More; 28use VCSUtils; 29 30# We should consider moving escapeNewLineCharacters() and toMacLineEndings() 31# to VCSUtils.pm if they're useful in other places. 32sub escapeNewLineCharacters($) 33{ 34 my ($text) = @_; 35 my @characters = split(//, $text); 36 my $result = ""; 37 foreach (@characters) { 38 if (/^\r$/) { 39 $result .= '\r'; 40 next; 41 } 42 if (/^\n$/) { 43 $result .= '\n'; 44 } 45 $result .= $_; 46 } 47 return $result; 48} 49 50sub toMacLineEndings($) 51{ 52 my ($text) = @_; 53 $text =~ s/\n/\r/g; 54 return $text; 55} 56 57my $gitDiffHeaderForNewFile = <<EOF; 58diff --git a/Makefile b/Makefile 59new file mode 100644 60index 0000000..756e864 61--- /dev/null 62+++ b/Makefile 63@@ -0,0 +1,17 @@ 64EOF 65 66my $gitDiffHeader = <<EOF; 67diff --git a/Makefile b/Makefile 68index 756e864..04d2ae1 100644 69--- a/Makefile 70+++ b/Makefile 71@@ -1,3 +1,4 @@ 72EOF 73 74my $svnConvertedGitDiffHeader = <<EOF; 75Index: Makefile 76index 756e864..04d2ae1 100644 77--- Makefile 78+++ Makefile 79@@ -1,3 +1,4 @@ 80EOF 81 82my $svnConvertedGitDiffHeaderForNewFile = <<EOF; 83Index: Makefile 84new file mode 100644 85index 0000000..756e864 86--- Makefile 87+++ Makefile 88@@ -0,0 +1,17 @@ 89EOF 90 91my $svnDiffHeaderForNewFile = <<EOF; 92Index: Makefile 93=================================================================== 94--- Makefile (revision 0) 95+++ Makefile (revision 0) 96@@ -0,0 +1,17 @@ 97EOF 98 99my $svnDiffHeader = <<EOF; 100Index: Makefile 101=================================================================== 102--- Makefile (revision 53052) 103+++ Makefile (working copy) 104@@ -1,3 +1,4 @@ 105EOF 106 107my $diffBody = <<EOF; 108+ 109 MODULES = JavaScriptCore JavaScriptGlue WebCore WebKit WebKitTools 110 111 all: 112EOF 113 114my $MakefileContents = <<EOF; 115MODULES = JavaScriptCore JavaScriptGlue WebCore WebKit WebKitTools 116 117all: 118EOF 119 120my $mockDir = File::Temp->tempdir("parseDiffXXXX", CLEANUP => 1); 121writeToFile(File::Spec->catfile($mockDir, "MakefileWithUnixEOL"), $MakefileContents); 122writeToFile(File::Spec->catfile($mockDir, "MakefileWithWindowsEOL"), toWindowsLineEndings($MakefileContents)); 123writeToFile(File::Spec->catfile($mockDir, "MakefileWithMacEOL"), toMacLineEndings($MakefileContents)); 124 125# The array of test cases. 126my @testCaseHashRefs = ( 127### 128# SVN test cases 129## 130{ 131 # New test 132 diffName => "SVN: Patch with Unix line endings and IndexPath has Unix line endings", 133 inputText => substituteString($svnDiffHeader, "Makefile", "MakefileWithUnixEOL") . $diffBody, 134 expectedReturn => [ 135[{ 136 svnConvertedText => substituteString($svnDiffHeader, "Makefile", "MakefileWithUnixEOL") . $diffBody, # Same as input text 137 indexPath => "MakefileWithUnixEOL", 138 isSvn => 1, 139 numTextChunks => 1, 140 sourceRevision => "53052", 141}], 142undef], 143 expectedNextLine => undef, 144}, 145{ 146 # New test 147 diffName => "SVN: Patch with Windows line endings and IndexPath has Unix line endings", 148 inputText => substituteString($svnDiffHeader, "Makefile", "MakefileWithUnixEOL") . toWindowsLineEndings($diffBody), 149 expectedReturn => [ 150[{ 151 svnConvertedText => substituteString($svnDiffHeader, "Makefile", "MakefileWithUnixEOL") . $diffBody, 152 indexPath => "MakefileWithUnixEOL", 153 isSvn => 1, 154 numTextChunks => 1, 155 sourceRevision => "53052", 156}], 157undef], 158 expectedNextLine => undef, 159}, 160{ 161 # New test 162 diffName => "SVN: Patch with Windows line endings and IndexPath has Windows line endings", 163 inputText => substituteString($svnDiffHeader, "Makefile", "MakefileWithWindowsEOL") . toWindowsLineEndings($diffBody), 164 expectedReturn => [ 165[{ 166 svnConvertedText => substituteString($svnDiffHeader, "Makefile", "MakefileWithWindowsEOL") . toWindowsLineEndings($diffBody), # Same as input text 167 indexPath => "MakefileWithWindowsEOL", 168 isSvn => 1, 169 numTextChunks => 1, 170 sourceRevision => "53052", 171}], 172undef], 173 expectedNextLine => undef, 174}, 175{ 176 # New test 177 diffName => "SVN: Patch adds Windows newline to EOF and IndexPath has Windows line endings", 178 inputText => <<"EOF", 179Index: MakefileWithWindowsEOL 180=================================================================== 181--- MakefileWithWindowsEOL (revision 53052) 182+++ MakefileWithWindowsEOL (working copy) 183@@ -1,3 +1,4 @@\r 184 MODULES = JavaScriptCore JavaScriptGlue WebCore WebKit WebKitTools\r 185 \r 186-all: 187\\ No newline at end of file 188+all:\r 189+\r 190EOF 191 expectedReturn => [ 192[{ 193 # Same as input text 194 svnConvertedText => <<"EOF", 195Index: MakefileWithWindowsEOL 196=================================================================== 197--- MakefileWithWindowsEOL (revision 53052) 198+++ MakefileWithWindowsEOL (working copy) 199@@ -1,3 +1,4 @@\r 200 MODULES = JavaScriptCore JavaScriptGlue WebCore WebKit WebKitTools\r 201 \r 202-all: 203\\ No newline at end of file 204+all:\r 205+\r 206EOF 207 indexPath => "MakefileWithWindowsEOL", 208 isSvn => 1, 209 numTextChunks => 1, 210 sourceRevision => 53052 211}], 212undef], 213 expectedNextLine => undef, 214}, 215{ 216 # New test 217 diffName => "SVN: Patch adds Mac newline to EOF and IndexPath has Mac line endings", 218 inputText => <<"EOF", 219Index: MakefileWithMacEOL 220=================================================================== 221--- MakefileWithMacEOL (revision 53052) 222+++ MakefileWithMacEOL (working copy) 223@@ -1,3 +1,4 @@\r MODULES = JavaScriptCore JavaScriptGlue WebCore WebKit WebKitTools\r \r-all: 224\\ No newline at end of file 225+all:\r+\r 226EOF 227 expectedReturn => [ 228[{ 229 # Same as input text 230 svnConvertedText => q(Index: MakefileWithMacEOL 231=================================================================== 232--- MakefileWithMacEOL (revision 53052) 233+++ MakefileWithMacEOL (working copy) 234@@ -1,3 +1,4 @@\r MODULES = JavaScriptCore JavaScriptGlue WebCore WebKit WebKitTools\r \r-all: 235\\ No newline at end of file 236+all:\r+\r), 237 indexPath => "MakefileWithMacEOL", 238 isSvn => 1, 239 numTextChunks => 1, 240 sourceRevision => 53052 241}], 242undef], 243 expectedNextLine => undef, 244}, 245{ 246 # New test 247 diffName => "SVN: Patch with Unix line endings and IndexPath has Windows line endings", 248 inputText => substituteString($svnDiffHeader, "Makefile", "MakefileWithWindowsEOL") . $diffBody, 249 expectedReturn => [ 250[{ 251 svnConvertedText => substituteString($svnDiffHeader, "Makefile", "MakefileWithWindowsEOL") . toWindowsLineEndings($diffBody), 252 indexPath => "MakefileWithWindowsEOL", 253 isSvn => 1, 254 numTextChunks => 1, 255 sourceRevision => "53052", 256}], 257undef], 258 expectedNextLine => undef, 259}, 260{ 261 # New test 262 diffName => "SVN: Patch with Unix line endings and nonexistent IndexPath", 263 inputText => substituteString($svnDiffHeaderForNewFile, "Makefile", "NonexistentFile") . $diffBody, 264 expectedReturn => [ 265[{ 266 svnConvertedText => substituteString($svnDiffHeaderForNewFile, "Makefile", "NonexistentFile") . $diffBody, # Same as input text 267 indexPath => "NonexistentFile", 268 isSvn => 1, 269 isNew => 1, 270 numTextChunks => 1, 271}], 272undef], 273 expectedNextLine => undef, 274}, 275{ 276 # New test 277 diffName => "SVN: Patch with Windows line endings and nonexistent IndexPath", 278 inputText => substituteString($svnDiffHeaderForNewFile, "Makefile", "NonexistentFile") . toWindowsLineEndings($diffBody), 279 expectedReturn => [ 280[{ 281 svnConvertedText => substituteString($svnDiffHeaderForNewFile, "Makefile", "NonexistentFile") . toWindowsLineEndings($diffBody), # Same as input text 282 indexPath => "NonexistentFile", 283 isSvn => 1, 284 isNew => 1, 285 numTextChunks => 1, 286}], 287undef], 288 expectedNextLine => undef, 289}, 290### 291# Git test cases 292## 293{ 294 # New test 295 diffName => "Git: Patch with Unix line endings and IndexPath has Unix line endings", 296 inputText => substituteString($gitDiffHeader, "Makefile", "MakefileWithUnixEOL") . $diffBody, 297 expectedReturn => [ 298[{ 299 svnConvertedText => substituteString($svnConvertedGitDiffHeader, "Makefile", "MakefileWithUnixEOL") . $diffBody, # Same as input text 300 indexPath => "MakefileWithUnixEOL", 301 isGit => 1, 302 numTextChunks => 1, 303}], 304undef], 305 expectedNextLine => undef, 306}, 307{ 308 # New test 309 diffName => "Git: Patch with Windows line endings and IndexPath has Unix line endings", 310 inputText => substituteString($gitDiffHeader, "Makefile", "MakefileWithUnixEOL") . toWindowsLineEndings($diffBody), 311 expectedReturn => [ 312[{ 313 svnConvertedText => substituteString($svnConvertedGitDiffHeader, "Makefile", "MakefileWithUnixEOL") . $diffBody, 314 indexPath => "MakefileWithUnixEOL", 315 isGit => 1, 316 numTextChunks => 1, 317}], 318undef], 319 expectedNextLine => undef, 320}, 321{ 322 # New test 323 diffName => "Git: Patch with Windows line endings and IndexPath has Windows line endings", 324 inputText => substituteString($gitDiffHeader, "Makefile", "MakefileWithWindowsEOL") . toWindowsLineEndings($diffBody), 325 expectedReturn => [ 326[{ 327 svnConvertedText => substituteString($svnConvertedGitDiffHeader, "Makefile", "MakefileWithWindowsEOL") . toWindowsLineEndings($diffBody), # Same as input text 328 indexPath => "MakefileWithWindowsEOL", 329 isGit => 1, 330 numTextChunks => 1, 331}], 332undef], 333 expectedNextLine => undef, 334}, 335{ 336 # New test 337 diffName => "Git: Patch adds newline to EOF with Windows line endings and IndexPath has Windows line endings", 338 inputText => <<"EOF", 339diff --git a/MakefileWithWindowsEOL b/MakefileWithWindowsEOL 340index e7e8475..ae16fc3 100644 341--- a/MakefileWithWindowsEOL 342+++ b/MakefileWithWindowsEOL 343@@ -1,3 +1,4 @@\r 344 MODULES = JavaScriptCore JavaScriptGlue WebCore WebKit WebKitTools\r 345 \r 346-all: 347\\ No newline at end of file 348+all:\r 349+\r 350EOF 351 expectedReturn => [ 352[{ 353 # Same as input text 354 svnConvertedText => <<"EOF", 355Index: MakefileWithWindowsEOL 356index e7e8475..ae16fc3 100644 357--- MakefileWithWindowsEOL 358+++ MakefileWithWindowsEOL 359@@ -1,3 +1,4 @@\r 360 MODULES = JavaScriptCore JavaScriptGlue WebCore WebKit WebKitTools\r 361 \r 362-all: 363\\ No newline at end of file 364+all:\r 365+\r 366EOF 367 indexPath => "MakefileWithWindowsEOL", 368 isGit => 1, 369 numTextChunks => 1 370}], 371undef], 372 expectedNextLine => undef, 373}, 374{ 375 # New test 376 diffName => "Git: Patch adds Mac newline to EOF and IndexPath has Mac line endings", 377 inputText => <<"EOF", 378diff --git a/MakefileWithMacEOL b/MakefileWithMacEOL 379index e7e8475..ae16fc3 100644 380--- a/MakefileWithMacEOL 381+++ b/MakefileWithMacEOL 382@@ -1,3 +1,4 @@\r MODULES = JavaScriptCore JavaScriptGlue WebCore WebKit WebKitTools\r \r-all: 383\\ No newline at end of file 384+all:\r+\r 385EOF 386 expectedReturn => [ 387[{ 388 # Same as input text 389 svnConvertedText => q(Index: MakefileWithMacEOL 390index e7e8475..ae16fc3 100644 391--- MakefileWithMacEOL 392+++ MakefileWithMacEOL 393@@ -1,3 +1,4 @@\r MODULES = JavaScriptCore JavaScriptGlue WebCore WebKit WebKitTools\r \r-all: 394\\ No newline at end of file 395+all:\r+\r), 396 indexPath => "MakefileWithMacEOL", 397 isGit => 1, 398 numTextChunks => 1 399}], 400undef], 401 expectedNextLine => undef, 402}, 403{ 404 # New test 405 diffName => "Git: Patch with Unix line endings and IndexPath has Windows line endings", 406 inputText => substituteString($gitDiffHeader, "Makefile", "MakefileWithWindowsEOL") . $diffBody, 407 expectedReturn => [ 408[{ 409 svnConvertedText => substituteString($svnConvertedGitDiffHeader, "Makefile", "MakefileWithWindowsEOL") . toWindowsLineEndings($diffBody), 410 indexPath => "MakefileWithWindowsEOL", 411 isGit => 1, 412 numTextChunks => 1, 413}], 414undef], 415 expectedNextLine => undef, 416}, 417{ 418 # New test 419 diffName => "Git: Patch with Unix line endings and nonexistent IndexPath", 420 inputText => substituteString($gitDiffHeaderForNewFile, "Makefile", "NonexistentFile") . $diffBody, 421 expectedReturn => [ 422[{ 423 svnConvertedText => substituteString($svnConvertedGitDiffHeaderForNewFile, "Makefile", "NonexistentFile") . $diffBody, # Same as input text 424 indexPath => "NonexistentFile", 425 isGit => 1, 426 isNew => 1, 427 numTextChunks => 1, 428}], 429undef], 430 expectedNextLine => undef, 431}, 432{ 433 # New test 434 diffName => "Git: Patch with Windows line endings and nonexistent IndexPath", 435 inputText => substituteString($gitDiffHeaderForNewFile, "Makefile", "NonexistentFile") . toWindowsLineEndings($diffBody), 436 expectedReturn => [ 437[{ 438 svnConvertedText => substituteString($svnConvertedGitDiffHeaderForNewFile, "Makefile", "NonexistentFile") . toWindowsLineEndings($diffBody), # Same as input text 439 indexPath => "NonexistentFile", 440 isGit => 1, 441 isNew => 1, 442 numTextChunks => 1, 443}], 444undef], 445 expectedNextLine => undef, 446}, 447); 448 449my $testCasesCount = @testCaseHashRefs; 450plan(tests => 2 * $testCasesCount); # Total number of assertions. 451 452my $savedCWD = getcwd(); 453chdir($mockDir) or die; 454foreach my $testCase (@testCaseHashRefs) { 455 my $testNameStart = "parseDiff(): $testCase->{diffName}: comparing"; 456 457 my $fileHandle; 458 open($fileHandle, "<", \$testCase->{inputText}); 459 my $line = <$fileHandle>; 460 461 my @got = VCSUtils::parseDiff($fileHandle, $line); 462 my $expectedReturn = $testCase->{expectedReturn}; 463 464 $got[0][0]->{svnConvertedText} = escapeNewLineCharacters($got[0][0]->{svnConvertedText}); 465 $expectedReturn->[0][0]->{svnConvertedText} = escapeNewLineCharacters($expectedReturn->[0][0]->{svnConvertedText}); 466 is_deeply(\@got, $expectedReturn, "$testNameStart return value."); 467 468 my $gotNextLine = <$fileHandle>; 469 is($gotNextLine, $testCase->{expectedNextLine}, "$testNameStart next read line."); 470} 471chdir($savedCWD); 472 473sub substituteString 474{ 475 my ($string, $searchString, $replacementString) = @_; 476 $string =~ s/$searchString/$replacementString/g; 477 return $string; 478} 479 480sub writeToFile 481{ 482 my ($file, $text) = @_; 483 open(FILE, ">$file") or die; 484 print FILE $text; 485 close(FILE); 486} 487