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 22 use strict; 23 use warnings; 24 25 use File::Temp; 26 use POSIX qw/getcwd/; 27 use Test::More; 28 use VCSUtils; 29 30 # We should consider moving escapeNewLineCharacters() and toMacLineEndings() 31 # to VCSUtils.pm if they're useful in other places. 32 sub 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 50 sub toMacLineEndings($) 51 { 52 my ($text) = @_; 53 $text =~ s/\n/\r/g; 54 return $text; 55 } 56 57 my $gitDiffHeaderForNewFile = <<EOF; 58 diff --git a/Makefile b/Makefile 59 new file mode 100644 60 index 0000000..756e864 61 --- /dev/null 62 +++ b/Makefile 63 @@ -0,0 +1,17 @@ 64 EOF 65 66 my $gitDiffHeader = <<EOF; 67 diff --git a/Makefile b/Makefile 68 index 756e864..04d2ae1 100644 69 --- a/Makefile 70 +++ b/Makefile 71 @@ -1,3 +1,4 @@ 72 EOF 73 74 my $svnConvertedGitDiffHeader = <<EOF; 75 Index: Makefile 76 index 756e864..04d2ae1 100644 77 --- Makefile 78 +++ Makefile 79 @@ -1,3 +1,4 @@ 80 EOF 81 82 my $svnConvertedGitDiffHeaderForNewFile = <<EOF; 83 Index: Makefile 84 new file mode 100644 85 index 0000000..756e864 86 --- Makefile 87 +++ Makefile 88 @@ -0,0 +1,17 @@ 89 EOF 90 91 my $svnDiffHeaderForNewFile = <<EOF; 92 Index: Makefile 93 =================================================================== 94 --- Makefile (revision 0) 95 +++ Makefile (revision 0) 96 @@ -0,0 +1,17 @@ 97 EOF 98 99 my $svnDiffHeader = <<EOF; 100 Index: Makefile 101 =================================================================== 102 --- Makefile (revision 53052) 103 +++ Makefile (working copy) 104 @@ -1,3 +1,4 @@ 105 EOF 106 107 my $diffBody = <<EOF; 108 + 109 MODULES = JavaScriptCore JavaScriptGlue WebCore WebKit WebKitTools 110 111 all: 112 EOF 113 114 my $MakefileContents = <<EOF; 115 MODULES = JavaScriptCore JavaScriptGlue WebCore WebKit WebKitTools 116 117 all: 118 EOF 119 120 my $mockDir = File::Temp->tempdir("parseDiffXXXX", CLEANUP => 1); 121 writeToFile(File::Spec->catfile($mockDir, "MakefileWithUnixEOL"), $MakefileContents); 122 writeToFile(File::Spec->catfile($mockDir, "MakefileWithWindowsEOL"), toWindowsLineEndings($MakefileContents)); 123 writeToFile(File::Spec->catfile($mockDir, "MakefileWithMacEOL"), toMacLineEndings($MakefileContents)); 124 125 # The array of test cases. 126 my @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 }], 142 undef], 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 }], 157 undef], 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 }], 172 undef], 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", 179 Index: 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 190 EOF 191 expectedReturn => [ 192 [{ 193 # Same as input text 194 svnConvertedText => <<"EOF", 195 Index: 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 206 EOF 207 indexPath => "MakefileWithWindowsEOL", 208 isSvn => 1, 209 numTextChunks => 1, 210 sourceRevision => 53052 211 }], 212 undef], 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", 219 Index: 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 226 EOF 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 }], 242 undef], 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 }], 257 undef], 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 }], 272 undef], 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 }], 287 undef], 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 }], 304 undef], 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 }], 318 undef], 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 }], 332 undef], 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", 339 diff --git a/MakefileWithWindowsEOL b/MakefileWithWindowsEOL 340 index 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 350 EOF 351 expectedReturn => [ 352 [{ 353 # Same as input text 354 svnConvertedText => <<"EOF", 355 Index: MakefileWithWindowsEOL 356 index 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 366 EOF 367 indexPath => "MakefileWithWindowsEOL", 368 isGit => 1, 369 numTextChunks => 1 370 }], 371 undef], 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", 378 diff --git a/MakefileWithMacEOL b/MakefileWithMacEOL 379 index 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 385 EOF 386 expectedReturn => [ 387 [{ 388 # Same as input text 389 svnConvertedText => q(Index: MakefileWithMacEOL 390 index 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 }], 400 undef], 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 }], 414 undef], 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 }], 429 undef], 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 }], 444 undef], 445 expectedNextLine => undef, 446 }, 447 ); 448 449 my $testCasesCount = @testCaseHashRefs; 450 plan(tests => 2 * $testCasesCount); # Total number of assertions. 451 452 my $savedCWD = getcwd(); 453 chdir($mockDir) or die; 454 foreach 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 } 471 chdir($savedCWD); 472 473 sub substituteString 474 { 475 my ($string, $searchString, $replacementString) = @_; 476 $string =~ s/$searchString/$replacementString/g; 477 return $string; 478 } 479 480 sub writeToFile 481 { 482 my ($file, $text) = @_; 483 open(FILE, ">$file") or die; 484 print FILE $text; 485 close(FILE); 486 } 487