Home | History | Annotate | Download | only in VCSUtils_unittest
      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